End-to-End Testing with CodeceptJS
Your Storefront Next app includes an end-to-end test suite built with CodeceptJS and Playwright. Run automated tests against your storefront locally or in a remote environment to verify that user-facing flows work as expected.
Configure the storefront app from the project root.
-
Copy
.env.default, the included environment template, or start from any.envfile you already have configured. -
Edit
.envwith your B2C Commerce credentials.
From the project root, install dependencies.
This step also installs Playwright browsers.
Copy the environment template from the e2e directory.
This table describes the key variables in .env.
| Variable | Default | Description |
|---|---|---|
BASE_URL | http://localhost:5173 | Storefront URL |
SITE_ID | RefArchGlobal | B2C Commerce site ID |
SITE_ALIAS | global | URL prefix for multisite routing |
LOCALE | en-GB | Locale prefix for multisite routing |
HEADLESS | false | Run browser headless |
VERBOSE | false | Get more debug logging and stack traces during test runs. |
Run all commands from the template root.
| Command | Description |
|---|---|
pnpm e2e | Run all tests |
pnpm e2e --mode=local | Auto-start local dev server and run tests |
pnpm e2e --mode=remote | Run against a remote URL (requires BASE_URL) |
pnpm e2e --grep "@checkout" | Filter tests by tag or name |
pnpm e2e --headed | Run tests with the browser visible |
pnpm e2e --ui | Open interactive UI mode |
pnpm e2e --debug | Debug with the CodeceptJS inspector |
pnpm report | Open the Allure test report |
The test suite integrates with CodeceptJS AI to provide self-healing tests, an interactive debugging console, and automatic page object generation. AI features are disabled by default. To use them, pass the --ai flag.
-
Get an API key from console.anthropic.com.
-
Add the key to
.env. -
Run tests with AI enabled.
- Self-healing: Automatically repairs broken locators when tests fail.
- Interactive console: Add
pause()to a test, then describe actions in plain English. - Page object generation: Call
I.askForPageObject()to read the live document object model (DOM) and generate a page object.
To see AI healing decisions in the console, run:
AI coding assistants such as Cursor and Claude Code can generate complete E2E tests using the generate-storefront-e2e-test skill. This is separate from the Anthropic API key used for runtime self-healing—no additional API key is required.
The skill guides the assistant through a structured workflow, from understanding the commerce scenario to producing spec files, page objects, and self-healing recipes.
Ask your AI assistant to create an E2E test. Any of these prompts activates the skill.
The assistant:
- Clarifies requirements—asks about scope, device targets, and guest or authenticated flows
- Audits existing coverage—reviews unit tests and Storybook stories to avoid duplication
- Proposes a test plan—lists scenarios, tags, and page objects before writing code
- Generates artifacts—spec files, page objects, flow files, and self-healing recipes
- Registers everything—updates
src/pages/index.ts,src/flows/index.ts, andhelpers/self-healing/recipes.ts
This table describes the files the skill produces.
| Artifact | Location | Purpose |
|---|---|---|
| Spec file | src/specs/<feature>/*.spec.ts | Test scenarios with Chai assertions |
| Page object | src/pages/*.page.ts | Reusable element interactions |
| Flow | src/flows/*.flow.ts | Multi-page workflows |
| Healing recipes | helpers/self-healing/recipes.ts | Fallback selectors for AI self-healing |
Generated code follows these conventions.
- Scenarios never call
I.*directly—all browser interactions live in page objects or flows. - Chai
expect()for value assertions, CodeceptJS methods for UI interactions. - All hardcoded paths wrapped in
buildSitePath()for multisite support. - Each scenario is independent and can run in any order.
- Page objects use semantic locators with
.as('Name')descriptions.
After generation, verify the tests.
TypeScript definitions are auto-generated before each test run. To generate them manually for IDE IntelliSense, run:
The end-to-end test suite includes full-page accessibility scanning using axe-core via @axe-core/playwright. Scans run in a real browser against the running storefront and catch issues that component-level Storybook a11y tests can’t detect, such as page composition, routing, layout, and responsive behavior issues.
- Scope: WCAG 2.1 AA (
wcag2a,wcag2aa,wcag21aatags) - Viewports: Desktop (1200×900) and mobile (Pixel 7 emulation).
pnpm a11yruns both passes sequentially viascripts/run-a11y.ts, starting with desktop and then enabling mobile withPLAYWRIGHT_MOBILE=true. - Baseline: The test suite snapshots violation counts per page per viewport. CI fails only when critical or serious violations increase or a new critical/serious rule appears. Moderate and minor regressions are logged as informational and don’t block CI.
- Retries: The test suite retries infrastructure failures such as timeouts and navigation errors up to two times via
.retry(2)on the Feature. Thea11yNoRetryplugin never retries confirmed a11y regressions (thrown asA11yBaselineError) because axe scans are deterministic and re-running a real violation always reproduces it.
Start the storefront development server before running scans. From packages/template-retail-rsc-app, run pnpm dev.
Each scan prints a banner identifying the page, viewport, and WCAG standard.
The test suite prints the severity legend once at the start of the run. On completion, each scan prints one of these results.
✓ PASS: homepage/desktop—5 violations (within baseline)—scan passed↓ homepage/desktop—violations decreased, run pnpm a11y:update-baseline—improvement detectedⓘ 2 moderate/minor rules exceeded baseline (not blocking—update with pnpm a11y:update-baseline)—moderate or minor counts increased; informational only, printed below the PASS line- Failure: full violation report followed by a summary of new or increased critical/serious rules
pnpm a11y:report runs all scans with result collection enabled and writes two files to a11y-report/.
report.md—Markdown summary table (page × viewport × severity counts) and per-violation detail with rule ID, description, axe-core help URL, and HTML snippets of affected elements. Use this to create accessibility tickets.report.html—Styled HTML version of the same report, intended for CI artifact upload and browser viewing.
a11y-report/ is gitignored and treated as a generated artifact. Generate it locally when needed.
The test suite stores the baseline in a11y-baseline.json at the package root. Each entry maps a <pageKey>/<viewport> key to a Record<ruleId, nodeCount>.
On every test run, the spec compares the current axe output against the baseline.
- New critical/serious rule or more critical/serious violations than baseline → the test fails
- New moderate/minor rule or more moderate/minor violations than baseline → the test passes and logs the violation
- Fewer violations than baseline → the test passes with a log message suggesting a baseline update
Ratchet-down workflow: After fixing a known issue, update the baseline to lock in the improvement.
Initial setup for new pages: After adding a new page, run pnpm a11y:update-baseline. The command creates baseline entries automatically and populates them with current violation counts. Commit the result.
pnpm a11y always runs both viewport passes. To target a single viewport, invoke the test runner directly.
pnpm e2e run --multiple desktop --grep "@a11y" doesn’t work. CodeceptJS run-multiple doesn’t forward --grep to its workers, so all tests run instead of just the a11y suite.
-
Add a
Scenariotosrc/specs/core/accessibility.spec.ts. Use this pattern as a starting point. -
Run
pnpm a11y:update-baseline. The command creates baseline entries for the new page automatically. -
Review the diff in
a11y-baseline.json, then commit it.
axe-core reports violations with four impact levels.
| Level | Meaning |
|---|---|
critical | Blocks access entirely for users with disabilities |
serious | Creates significant barriers; fix quickly |
moderate | Creates difficulty for users with disabilities. Workarounds sometimes exist. |
minor | Low impact; fix when convenient |
Severity appears in these places in test output.
- Scan banner: Printed before each scan alongside the WCAG standard.
- Failure summary: Each failing rule appears inline as
rule-id [impact]: N violationsso you can assess priority at a glance. - Full violation report: Printed above the summary, grouped by impact level with rule descriptions, help URLs, and affected element selectors and HTML snippets.
- Markdown report: Summary table and per-rule detail sections with help URLs and HTML snippets for ticket creation.
This table describes the environment variables for the a11y suite.
| Variable | Values | Description |
|---|---|---|
BASE_URL | URL | Storefront URL to scan. Defaults to http://localhost:5173. |
PLAYWRIGHT_MOBILE | true | Enables Pixel 7 emulation. pnpm a11y sets this automatically for the mobile pass. Use it directly to run a single mobile pass. |
A11Y_UPDATE_BASELINE | true | Writes current violation counts to a11y-baseline.json at the package root instead of asserting. pnpm a11y:update-baseline sets this automatically. |
A11Y_COLLECT_RESULTS | true | Writes scan results to a11y-report/data/ for offline report generation. pnpm a11y:report sets this automatically. |
A11y scans run as a parallel job alongside the core E2E suite on every PR, merge group event, and push to main or release-* branches. Both jobs share the same MRT deployment, so there’s no extra deploy cost.
- Caller workflow:
.github/workflows/e2e-core-pr.yml - Reusable runner:
.github/workflows/e2e-pr-runner.yml—therun_a11yjob handles the scan, reporting, and artifact upload. - Kill switch: The
run_a11yjob is gated on theENABLE_A11Y_CIrepository variable. Set it tofalseto disable a11y CI globally without modifying any workflow file. - Command:
pnpm a11y:report --no-ai—runs scans in collect mode and generates botha11y-report/report.mdanda11y-report/report.html. - Job summary: The CI job appends
a11y-report/report.mdto the GitHub Actions job summary after each run, so you can view violation details directly in the Actions UI without downloading anything. - HTML report artifact: The CI job uploads
a11y-report/report.htmlas a CI artifact (a11y-report-<run-id>) after each run. Download it from the Actions run summary to view violation details in a browser without cloning the branch.
TypeScript errors about missing page objects
Regenerate definitions.
Tests fail with “Element not found”
Enable AI self-healing.
Local dev server won’t start
Check that .env exists at the project root and contains valid B2C Commerce credentials.
Port 5173 is already in use
AI features aren’t working
Verify that ANTHROPIC_API_KEY is set in .env.
Remote tests fail: “BASE_URL required”
Set BASE_URL before running the command.