Because tests are plain .js in your repo with no proprietary format, CI is
straightforward.
A minimal job
permissions: contents: readjobs: e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: { node-version: 22 } - run: npx @unotest/web install-chromium working-directory: unotest - run: npx @unotest/web collection smoke --workers=4 working-directory: unotest env: APP_BASE_URL: ${{ secrets.APP_BASE_URL }} TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }} TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}To run the suite on a box on every push instead,
npx @unotest/web init --ci github writes the workflow — see
Run on every push.
Tips
- Browsers: run the bundled Chromium in CI; you can widen
browsersto Firefox/WebKit in your config. Playwright’s WebKit does not drawbackdrop-filter, so a design compared withassertScreenshotthat uses it is compared in Chromium; the run warns once when WebKit meets such a page. - Retries: turn on
retry.countfor CI (off in dev) to absorb transient flakiness — assertion failures still never retry. - Secrets: inject variables from your CI secret store; the runner masks them in logs and artifacts.
- Environments: target a named environment with
--env staging— it layersunotest/.env.staging/.secrets.stagingover the base files (details). - Split:
smokeon every push,regressnightly. - iOS:
unotest mobileneeds macOS runners with Xcode.
Failure artifacts
On failure the bundle (screenshot, console,
semantic DOM, trace) is written into the run’s directory as failure/, under
the project’s unotest/.runs/ (or unotest/.runs.<env>/ for a run started
with --env); UNOTEST_ARTIFACTS_ROOT moves that whole tree to another root.
Upload the run directory as a CI artifact for inspection. A red collection
also prints the failing scenario’s own output and the path of its run
directory into the job log (see Run smoke / regress).