Skip to main content

Retries

Retries automatically re-run a failing test a few times before giving up, so an intermittent failure (a slow animation, a flaky network, a device hiccup) does not fail the whole run. Taqwright runs on the Playwright test runner, so retries work the same way they do in Playwright, with one mobile-specific detail: each attempt opens a fresh device session.

Enable retries

Set retries on the command line or in taqwright.config.ts. The CLI flag wins for that run:

npx taqwright test --retries 2
taqwright.config.ts
import { defineConfig, Platform } from '@taqwright/taqwright';

export default defineConfig({
retries: 2,
projects: [/* ... */],
});

Retries can also be set per project (see Projects) or for a single group with test.describe.configure:

tests/checkout.spec.ts
import { test } from '@taqwright/taqwright';

test.describe('Checkout', () => {
test.describe.configure({ retries: 3 });

test('card payment', async ({ mobile }) => { /* ... */ });
});

How retries work on a device

When a test fails, taqwright tears down its session and runs the test again from the start, up to the configured number of retries, until it passes or the budget is exhausted. Every attempt gets a fresh Appium/WebDriver session, so a wedged driver never carries into the next try.

Whether the app starts clean on a retry depends on resetBetweenTests:

  • resetBetweenTests: true terminates, uninstalls, reinstalls, and relaunches the app before each attempt, so every retry starts from a clean app.
  • resetBetweenTests: false (the default) leaves the app installed, so its state carries over between tests in a worker.

See Test isolation for the full reset behaviour.

Flaky tests

A test that fails on its first run but passes on a retry is reported as flaky, not failed. The run still succeeds, and the flaky result is surfaced in the list and html reporters with no extra setup. Watching for flaky tests is a good way to find tests that need a more stable locator or assertion. See Reporters.

Detect a retry at runtime

testInfo.retry is the current attempt number: 0 on the first run, 1 on the first retry, and so on. It is available in any test, hook, or fixture, so you can do extra work only when retrying, for example capture a diagnostic screenshot or take a slower, more deliberate path:

tests/search.spec.ts
import { test, expect } from '@taqwright/taqwright';

test('search returns results', async ({ mobile }, testInfo) => {
if (testInfo.retry) {
// Only on a retry: grab the screen for debugging.
await testInfo.attach('retry-screen', {
body: await mobile.screenshot(),
contentType: 'image/png',
});
}

await mobile.getById('Search dresses...').fill('boho');
await expect(mobile.getByText('boho', { exact: false })).toBeVisible();
});

Serial mode

test.describe.serial(...) runs the tests in a group one after another and stops the group at the first failure. With retries enabled, the whole group is retried together, which keeps dependent steps consistent:

tests/onboarding.spec.ts
import { test, expect } from '@taqwright/taqwright';

test.describe.serial('Onboarding', () => {
test('create account', async ({ mobile }) => {
await mobile.getByLabel('Sign up').click();
// ...
});

test('complete profile', async ({ mobile }) => {
// Relies on the account created above.
await mobile.getByLabel('Save profile').click();
await expect(mobile.getByLabel('View All')).toBeVisible();
});
});

Each test in the group still opens its own session, but with the default resetBetweenTests: false the app keeps the state the previous test left behind. That is taqwright's equivalent of Playwright's "reuse a single page" pattern: combine serial mode with a shared setup in beforeAll to carry app state across the group.

Device blips are retried separately

Independently of the retries knob, taqwright already retries transient device errors (an adb or emulator hiccup while opening or resetting a session) during setup. Those internal retries do not consume your test retry budget.

See Configuration for where retries sits in the full config, and Command line for the --retries flag.