Configuration
Configure your app address, browser targets and timeouts, and let Retest start a local app server.
Start with one app address and one browser in your config. This page shows how to add browser targets, separate sessions and a server start command as your tests need them.
Configure one app Link to Configure one app
Create retest.config.ts in the folder where you run Retest, or use the file written by retest init. This config points tests at the task app on port 4173 and runs them in your installed Google Chrome.
import { chrome, defineConfig } from '@rehearsal-labs/retest'const config = defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173' }), },})export default configdeclare module '@rehearsal-labs/retest' { interface Register { config: typeof config }}web is your app's name, and chrome describes its browser target. Because there is one app, a test without an apps option receives it as page. Relative paths such as page.goto('/') resolve against baseUrl.
The Register block makes the config's names and capabilities available to TypeScript in your tests. Keep it when you change the config; TypeScript explains how it catches wrong app names and unsupported methods.
Retest checks the config when it loads it, including for JavaScript callers. An unknown key or an invalid value stops the command with exit code 2 and a message naming the file and setting.
Choose browser targets Link to Choose browser targets
Give an app several named targets to run the same tests in more than one browser. Add app and chromium to the imports, then use this defineConfig call. Keep the export and registration block from the first example.
const config = defineConfig({ apps: { web: app({ baseUrl: 'http://127.0.0.1:4173', targets: { chrome: chrome(), chromium: chromium(), }, }), },})A test using this app runs once on each target, and its results name the target it used. chrome() finds an installed Google Chrome. chromium() needs an executable path, supplied through executablePath or RETEST_CHROMIUM; see Browsers for installation and engine support.
For an app with one target, the target helper directly under apps is the shorter form shown in the first example. Use a target's viewport to set only its page size, or emulate to describe an emulated device. A target cannot take both.
Give each person an app Link to Give each person an app
Use separate app entries when one test needs two browser sessions, for example a member and an administrator. They can use the same website address while keeping separate cookies and storage.
const config = defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173' }), admin: chrome({ baseUrl: 'http://127.0.0.1:4173' }), }, defaultApp: 'web',})Keep the export and registration block from the first example. defaultApp keeps existing tests using page on the web app. A test that explicitly declares both apps receives their names instead of page.
test('both sessions start signed out', { apps: ['web', 'admin'] }, async ({ web, admin }) => { await web.goto('/account') await admin.goto('/account') await expect(web.getByTestId('account')).toHaveText('Signed out') await expect(admin.getByTestId('account')).toHaveText('Signed out')})Each app gets a browser context and page of its own. The same approach lets a test use different platforms together; One test across platforms shows a flow across web and native apps.
Choose target pairings Link to Choose target pairings
When a test uses two or more apps that each have several targets, use runs to choose their pairings. With app, chrome and chromium imported, this config runs the two-session test on two browser pairings:
const config = defineConfig({ apps: { web: app({ baseUrl: 'http://127.0.0.1:4173', targets: { chrome: chrome(), chromium: chromium() }, }), admin: app({ baseUrl: 'http://127.0.0.1:4173', targets: { chrome: chrome(), chromium: chromium() }, }), }, defaultApp: 'web', runs: [ { web: 'chrome', admin: 'chromium' }, { web: 'chromium', admin: 'chrome' }, ],})The test using both apps runs once per listed pairing. Apps with only one target use it automatically. If no runs entry names all of the test's apps that have several targets, the test file fails collection. Retest does not generate every combination.
Start a local server Link to Start a local server
Add start when Retest should start the app's development server. In your config, use your own start command and set ready to an endpoint that answers when the server is available.
const config = defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173', start: { command: 'npm run dev', ready: 'http://127.0.0.1:4173', timeoutMs: 60_000, }, }), },})Retest first sends an HTTP request to ready. If a server already answers, it reuses that server and leaves it running. Otherwise it starts the command, waits for an answer and stops the server it started when the run ends.
Readiness checks
Any HTTP response counts as ready, including an error response. The readiness check proves that a server answers, so your tests must still check that the app works.
A server that exits early or never answers causes setup failures for tests that need it. Read the log path named in the failure for its output. If the command needs another working directory, set start.cwd relative to the config's folder.
Set time budgets Link to Set time budgets
Use timeouts to change how long Retest allows an operation to take. Add it alongside your app settings when actions, checks or tests need a different budget.
const config = defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173' }) }, timeouts: { action: 5000, assertion: 10_000, test: 30_000, },})Values are milliseconds. Here an action gets up to five seconds, a check up to ten seconds, and the whole test up to thirty seconds. An action or assertion cannot use more time than the test has left. A test's own timeout option can set its individual test budget.
Without overrides, the action budget is ten seconds, assertions get five seconds and a test gets sixty seconds. --timeouts overrides the config for a run. The Configuration reference lists navigation, setup and the other budgets.
Keep environment values in the config Link to Keep environment values in the config
Read a deployment address from the environment when the same tests run locally and in continuous integration. This uses TASK_APP_URL when it is set and the local address otherwise.
const config = defineConfig({ apps: { web: chrome({ baseUrl: process.env['TASK_APP_URL'] ?? 'http://127.0.0.1:4173', }), },})For passwords, declare a secret source such as env('TASK_APP_PASSWORD') in secrets and use secret('password') in the test. Signing in and secrets shows the complete config and sign-in flow.
You can also replace addresses with --base-url, or load another file with --config. Use flags for a run's choices, including --workers; the worker count is not a config key.