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.

  1. Copy .env.default, the included environment template, or start from any .env file you already have configured.

  2. Edit .env with 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.

VariableDefaultDescription
BASE_URLhttp://localhost:5173Storefront URL
SITE_IDRefArchGlobalB2C Commerce site ID
SITE_ALIASglobalURL prefix for multisite routing
LOCALEen-GBLocale prefix for multisite routing
HEADLESSfalseRun browser headless
VERBOSEfalseGet more debug logging and stack traces during test runs.

Run all commands from the template root.

CommandDescription
pnpm e2eRun all tests
pnpm e2e --mode=localAuto-start local dev server and run tests
pnpm e2e --mode=remoteRun against a remote URL (requires BASE_URL)
pnpm e2e --grep "@checkout"Filter tests by tag or name
pnpm e2e --headedRun tests with the browser visible
pnpm e2e --uiOpen interactive UI mode
pnpm e2e --debugDebug with the CodeceptJS inspector
pnpm reportOpen 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.

  1. Get an API key from console.anthropic.com.

  2. Add the key to .env.

  3. 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:

  1. Clarifies requirements—asks about scope, device targets, and guest or authenticated flows
  2. Audits existing coverage—reviews unit tests and Storybook stories to avoid duplication
  3. Proposes a test plan—lists scenarios, tags, and page objects before writing code
  4. Generates artifacts—spec files, page objects, flow files, and self-healing recipes
  5. Registers everything—updates src/pages/index.ts, src/flows/index.ts, and helpers/self-healing/recipes.ts

This table describes the files the skill produces.

ArtifactLocationPurpose
Spec filesrc/specs/<feature>/*.spec.tsTest scenarios with Chai assertions
Page objectsrc/pages/*.page.tsReusable element interactions
Flowsrc/flows/*.flow.tsMulti-page workflows
Healing recipeshelpers/self-healing/recipes.tsFallback 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, wcag21aa tags)
  • Viewports: Desktop (1200×900) and mobile (Pixel 7 emulation). pnpm a11y runs both passes sequentially via scripts/run-a11y.ts, starting with desktop and then enabling mobile with PLAYWRIGHT_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. The a11yNoRetry plugin never retries confirmed a11y regressions (thrown as A11yBaselineError) 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.

  1. Add a Scenario to src/specs/core/accessibility.spec.ts. Use this pattern as a starting point.

  2. Run pnpm a11y:update-baseline. The command creates baseline entries for the new page automatically.

  3. Review the diff in a11y-baseline.json, then commit it.

axe-core reports violations with four impact levels.

LevelMeaning
criticalBlocks access entirely for users with disabilities
seriousCreates significant barriers; fix quickly
moderateCreates difficulty for users with disabilities. Workarounds sometimes exist.
minorLow 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 violations so 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.

VariableValuesDescription
BASE_URLURLStorefront URL to scan. Defaults to http://localhost:5173.
PLAYWRIGHT_MOBILEtrueEnables Pixel 7 emulation. pnpm a11y sets this automatically for the mobile pass. Use it directly to run a single mobile pass.
A11Y_UPDATE_BASELINEtrueWrites current violation counts to a11y-baseline.json at the package root instead of asserting. pnpm a11y:update-baseline sets this automatically.
A11Y_COLLECT_RESULTStrueWrites 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—the run_a11y job handles the scan, reporting, and artifact upload.
  • Kill switch: The run_a11y job is gated on the ENABLE_A11Y_CI repository variable. Set it to false to disable a11y CI globally without modifying any workflow file.
  • Command: pnpm a11y:report --no-ai—runs scans in collect mode and generates both a11y-report/report.md and a11y-report/report.html.
  • Job summary: The CI job appends a11y-report/report.md to 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.html as 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.