command in your config, the job is install, browser, run.
.github/workflows/e2e.yml
--no-install makes npx fail rather than fetch a mutable version from the
registry; with --frozen-lockfile, the runner, the engine, and the browser
all come from your lockfile.
Point your CI’s test summary at .e2e/junit.xml and failures show up as test
results instead of a red step. A startup failure such as APP_UNREACHABLE
appears there too, as a run suite. For the failure itself on the pull
request, add the GitHub reporter.
What CI changes
CI mode is on when theCI variable is set and is not empty, 0, or false.
That is the only signal, so CI=1 npx --no-install e2e run reproduces CI
behavior locally.
Override any of them when you mean it:
E2E_TELEMETRY_DISABLED: '1' to the job’s
env to send nothing from CI.
Model credentials
Deterministic tests need no model. For a suite that usesagent, the job
passes the key the provider package reads:
Keep model-backed tests opt-in
Deterministic tests are reproducible. Agentic tests can take a different, equally valid path on each run. Gating merges on them makes the model a shared dependency of every pull request.1
Split the config
A separate
e2e.agent.config.ts with its own tests glob and a larger
timeout, since every planned step includes model round trips.2
Split the workflow
Run it on
workflow_dispatch or schedule, never on pull_request.3
Keep it out of required checks
Branch protection requires the deterministic job only.
Nightly agentic run
Exit codes
A non-zero exit fails the step, which is usually all you want. When you react to the class of failure: 1 is a test failure, 2 is configuration or policy, 3 is infrastructure, 130 is a cancellation.Pull request comments
One comment per run, edited in place on a rerun.
CLI reference
Flags, reporters, and every exit code.
