Continuous integration
Prepare a CI job or Linux container, run your tests and retain the result and evidence.
A CI job runs the same Retest tests as your local machine, then keeps the run folder for review. Prepare its browser and app first, and let a non-zero exit fail the job.
Runner requirements
Use Node.js 24.12 or later and a supported browser on macOS or Linux. See Browsers for engine support. Native tests need the Mac toolchain and permissions in iOS simulator apps or macOS apps.
Run in a container Link to Run in a container
Retest's Linux browser checks ran in Docker with Chrome and Debian's Chromium. Use this container setup for a Linux job.
Retest keeps Chrome's sandbox enabled. A Linux container needs a non-root user, an init process and a seccomp profile that permits the sandbox's user namespaces.
Copy Retest's seccomp profile into your project at the path below. The image must already contain Node, Retest, a browser and your tests, and have a user named node.
docker run --rm --init --cap-drop ALL \ --security-opt seccomp=docker/linux/chromium-seccomp.json \ --user node <image> npx retest runWithout that profile, Chrome can stop before it answers, and Retest exits 2 with a sandbox setup failure. The init process reaps browser processes during shutdown. For large pages, increase Docker's shared memory with --shm-size if the default 64 MB is insufficient.
Add a GitHub workflow Link to Add a GitHub workflow
retest init can write a starting workflow along with the config, example test and package scripts. Use --yes to choose defaults without a terminal. It leaves existing files in place, so review an existing workflow yourself if the command reports that it kept one.
The generated workflow below runs directly on the host. Retest has not been checked on Linux outside Docker. On Ubuntu 23.10 and later, Chrome needs an AppArmor profile that allows user namespaces; that setup has not been tried.
npx retest init --ci github --yesname: Reteston: [pull_request]jobs: e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 24 } - run: npm ci - run: npm run typecheck:e2e - run: npm run test:e2e - uses: actions/upload-artifact@v4 if: always() with: { name: retest-runs, path: .retest/runs }The generated workflow installs the project with npm, checks test types, runs Retest and uploads the run folder even after a failure. Change the dependency step for your package manager and provide the browser your config selects. The workflow does not install a browser.
Start the app or use a preview Link to Start the app or use a preview
For a local app in the job, give Retest its start command and readiness address. Replace the command below with your app's script and port.
import { chrome, defineConfig } from '@rehearsal-labs/retest'export default defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173', start: { command: 'npm run dev -- --port 4173', ready: 'http://127.0.0.1:4173', }, }), },})If the readiness address already answers, Retest uses that server and leaves it running. Otherwise, it starts the command, waits for an HTTP answer and stops the server when the run ends. Any HTTP status counts as ready, so keep an application check in the test.
For a deployed preview, override the configured app's address at run time. With several apps, use the named form for each app you need to replace.
npx retest run --base-url https://preview.example.testnpx retest run --base-url web=https://preview.example.testA base URL override does not remove start. Use a config without a local start command for preview-only jobs, or make its readiness settings appropriate to that job.
Handle results and cancellation Link to Handle results and cancellation
Keep CI secrets in environment variables referenced by the config, and use secret() in test code. Retest removes variables used by env secrets from the test process, but that process is not a sandbox. Screenshots can contain sensitive pixels, so control access to uploaded run folders.
When CI has a value other than empty, 0 or false, test.only is refused before tests start. Leave that guard enabled in release checks so an accidentally narrowed suite cannot pass the job.
| Exit code | What the job should do |
|---|---|
0 | Accept the completed run. |
1 | Fail the job because at least one test failed. Read the result for the cause. |
2 | Fail the job because setup, output or another required part could not complete. |
130 or 143 | Treat the run as interrupted, not passed. |
If the job sends SIGTERM, Retest records interruption, writes its result, closes browsers and stops servers it started, then exits with 143. A forced kill cannot complete that cleanup. Results and exit codes explains mixed failures and incomplete runs.
Keep the run folder Link to Keep the run folder
Upload .retest/runs even when tests fail. It holds results, events, logs and available screenshots or recordings. To include report.html, use --reporter html when running tests, or generate it afterwards with retest report. Other CI services can use the same install, run and upload sequence.
For live machine-readable output, use --reporter jsonl. A program can read saved runs through readRunFolder; a folder whose result was never written is reconstructed from events and marked incomplete.