Global setup and teardown
Per-test hooks (beforeEach / afterEach, see
Writing tests) run inside every test. Sometimes you
need work that happens once for the whole run instead: seed a backend, sign in a single
account, provision fixtures, then clean up at the end. Taqwright gives you two ways to do
this.
| Setup project (recommended) | globalSetup / globalTeardown | |
|---|---|---|
| Shows in the HTML report | Yes | No |
| Retries, trace, video | Yes | No |
mobile fixture / device session | Yes | No |
| Setup shape | A normal taqwright spec | A plain module |
The deciding factor is the mobile fixture. A setup project runs as a real test in a
worker, so it can drive a device. A globalSetup module runs before any worker starts, so
it has no mobile fixture and no Appium session. Reach for a setup project whenever your
setup has to touch the app on a device; use globalSetup for pure, device-free work
(hitting an API, writing a file, setting environment variables).
Option 1: Setup project (recommended)
Add a project whose testMatch selects your setup spec, then list it in the
dependencies of the projects that need it. The runner finishes the setup project before
any dependent project starts.
import { defineConfig, Platform } from '@taqwright/taqwright';
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: /global\.setup\.ts/,
use: {
platform: Platform.ANDROID,
device: { provider: 'emulator', name: 'taqwright_api34' },
buildPath: './app/DemoApp-v1.0.0.apk',
appBundleId: 'com.taqelah.demo_app',
},
},
{
name: 'android',
dependencies: ['setup'], // runs after the `setup` project completes
use: {
platform: Platform.ANDROID,
device: { provider: 'emulator', name: 'taqwright_api34' },
buildPath: './app/DemoApp-v1.0.0.apk',
appBundleId: 'com.taqelah.demo_app',
},
},
],
});
The setup spec is an ordinary taqwright test, so the full device API is available. Alias
test to setup for readability:
import { test as setup, expect } from '@taqwright/taqwright';
setup('sign in once', async ({ mobile }) => {
await mobile.getByLabel('Username').fill('emma@demoapp.com');
await mobile.getByLabel('Password').fill('10203040');
await mobile.getByLabel('Login').click();
await expect(mobile.getByLabel('View All')).toBeVisible();
});
Because resetBetweenTests reinstalls the app between tests, prefer a setup project for
state that lives outside the app (backend seeding, account provisioning, an uploaded
file). For in-app state that must survive into the dependent tests, keep
resetBetweenTests off on those projects so the app is not wiped between the setup project
and them.
Filtering
CLI filters like --grep and --project select your primary tests; their
dependencies still run automatically, so the setup project executes even when you filter
down to a single test:
npx taqwright test --project android --grep @checkout
# the `setup` project still runs first
Teardown
Taqwright projects do not take a project-level teardown property, so run end-of-suite
cleanup through globalTeardown (below). It runs once, after every project and test has
finished.
Option 2: globalSetup and globalTeardown
For device-free setup, point the top-level globalSetup / globalTeardown config options
at plain modules. Each is a path, or an array of paths run in order.
import { defineConfig, Platform } from '@taqwright/taqwright';
export default defineConfig({
globalSetup: './global-setup.ts',
globalTeardown: './global-teardown.ts',
projects: [
{
name: 'android',
use: {
platform: Platform.ANDROID,
device: { provider: 'emulator', name: 'taqwright_api34' },
buildPath: './app/DemoApp-v1.0.0.apk',
appBundleId: 'com.taqelah.demo_app',
},
},
],
});
A setup module default-exports an async function. There is no mobile fixture here, so do
device-free work only and hand values to your tests through process.env:
export default async () => {
const res = await fetch('https://api.example.com/seed', { method: 'POST' });
const { token } = await res.json();
process.env.SEED_TOKEN = token; // read this in your tests
};
export default async () => {
await fetch('https://api.example.com/seed', { method: 'DELETE' });
};
If you want the typed signature, import FullConfig from Playwright (taqwright does not
re-export a dedicated type):
import type { FullConfig } from '@playwright/test';
export default async (config: FullConfig) => {
// ...
};
globalSetupglobalSetup and globalTeardown run before any worker starts, so the mobile fixture
and a live Appium session are not available. If your setup must drive the app on a device,
use a setup project (Option 1).
When a project sets device.autoDiscover (or an emulator pool with auto-boot), taqwright
prepends its own internal globalSetup to enumerate and pre-boot devices. Your own
globalSetup still runs alongside it, so nothing is lost. See
Parallelism.
See Configuration for these options in the full
taqwright.config.ts, and Writing tests for
per-test beforeEach / afterEach hooks.