Running in CI
GitHub Actions
.github/workflows/e2e.yml
name: End-to-end tests
on:
push:
branches: [main]
pull_request:
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx intelliwright install chromium --with-deps
- run: npx intelliwright test
env:
TYPESAFE_API_KEY: ${{ secrets.TYPESAFE_API_KEY }}
E2E_MEMBER_EMAIL: ${{ secrets.E2E_MEMBER_EMAIL }}
E2E_MEMBER_PASSWORD: ${{ secrets.E2E_MEMBER_PASSWORD }}
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: intelliwright-report
path: |
intelliwright-report/
test-results/
retention-days: 14
--with-depsinstalls the system libraries the browser needs on a fresh Linux runner..env.localisn't in CI, so pass provider keys and test credentials as secrets. Variables set by CI are used as they are.- Uploading
intelliwright-report/andtest-results/keeps the report, screenshots and traces of failed runs. Download the artifact and runnpx intelliwright show-report intelliwright-report. - The run exits with code 1 when a test fails, which fails the job.
A config for CI
intelliwright.config.ts
const ci = Boolean(process.env.CI);
export default defineConfig({
retries: ci ? 2 : 0,
workers: ci ? 2 : undefined,
webServer: {
command: ci ? "npm run build && npm run start" : "npm run dev",
url: "http://localhost:3000",
reuseExistingServer: !ci,
timeout: 120_000,
},
reporters: ci ? ["terminal", "html", "junit"] : ["terminal", "html"],
});
- Retries turn one-off failures into
flakyresults instead of failed builds, while the summary still lists them. Fix flaky tests rather than relying on retries; see Fixing flaky tests. - Workers default to half the runner's CPU cores. Lower it if the app under test struggles with parallel load.
- A production build is closer to what users get, and usually faster to test than a dev server.
- JUnit lets CI systems that read it show each test's result.
- The HTML report never opens by itself when
CIis set.
Keep CI fast and cheap
- Commit
.intelliwright/cache.json. AI actions whose cached locators still match make no Jev calls in CI. - Replace
ai.runwith its generated code once a flow works, as described in Goal-driven runs. - Run a smoke suite on every push and the rest on a schedule, with named suites:
npx intelliwright test --suite smoke. - Check the
Jevline at the end of the run for the number of calls and the cost.
Without a key
Pull requests from forks don't get your secrets. Tests that don't use Jev features still run without a key. For tests that do, either tag them, such as @ai, and run --tag "not @ai" when the key is missing, or use a mock evaluator. Failure triage is skipped with a note.
Other CI systems
The same steps work anywhere Node.js 22 runs:
npm ci
npx intelliwright install chromium --with-deps
npx intelliwright test --reporter terminal,junit
Then publish test-results/junit.xml and keep intelliwright-report/ and test-results/ as artifacts.