Common Errors
The most common errors new users hit, with cause and fix for each.
1. Browser doesn't open during Phase 4
Cause: HEADLESS=true is the default. The browser is running — you just can't see it.
Fix: Add this to e2e-tests/.env.testing:
HEADLESS=false
Restart the pipeline and Phase 4 will open a visible Chromium window.
2. OAUTH_STORAGE_KEY is undefined
Cause: The field is missing from .env.testing, commented out, or misspelled. There is no fallback by design — an undefined storage key would silently inject auth into the wrong localStorage slot, causing all tests to run unauthenticated without an obvious error.
Fix: Add the line explicitly to .env.testing:
OAUTH_STORAGE_KEY=your-exact-key-name
To find the correct key: open your app → log in → DevTools → Application → Local Storage → find the key containing your JWT or user object. Common names: auth-token, user, session, supabase.auth.token.
3. Phase 7 hangs for 2+ minutes
Cause: The @bdd-generator agent is scanning all files in shared/ to find reusable steps, instead of using the step list from the approved plan. This usually happens when the agent's memory file has accumulated stale context from a previous run.
Fix: Clear the agent's memory and re-run:
rm -f .claude/agent-memory/bdd-generator/MEMORY.md
Then run /e2e-automate again. On the next run the agent will rebuild from the plan directly.
4. Consumer phase sees no data from precondition
Cause: The precondition step saved only scalar values (strings, numbers) to test-data.json, but the consumer expects a re-hydrated store — typically the full localStorage state from the end of the precondition scenario.
Fix: Add a localStorage snapshot in the precondition After hook so the full app state is captured:
// e2e-tests/features/playwright-bdd/@Workflows/@YourWorkflow/@0-Precondition/steps.js
After({ tags: '@cross-feature-data' }, async ({ page, $bddContext }) => {
const storage = await page.evaluate(() => JSON.stringify(localStorage));
const existing = $bddContext.testData ?? {};
$bddContext.testData = { ...existing, localStorageSnapshot: storage };
});
The consumer phase reads $bddContext.testData.localStorageSnapshot to restore the exact localStorage state from Phase 0.
5. "Step not found" after editing a steps file
Cause: playwright-bdd caches generated step bindings in .features-gen/. Editing steps.js after the cache was built means Playwright is still loading the old bindings.
Fix:
rm -rf .features-gen/ && pnpm test:bdd
pnpm test:bdd runs bddgen before Playwright, which rebuilds .features-gen/ from scratch.
6. Auth fails in tests but works in the browser manually
Cause: Stale storageState — the user.json file was captured with a session that has since expired (or with the wrong user account).
Fix: Delete the cached auth state and re-run:
rm -f e2e-tests/playwright/auth-storage/.auth/user.json
pnpm test:bdd
The setup project will re-run auth and write a fresh user.json before the test suite starts.
7. Steps defined in one module aren't visible to another
Cause: Steps defined in @Modules/@SomePage/steps.js are path-scoped — playwright-bdd only loads them for feature files that live under the same directory. They are invisible to any feature file in a different @Module directory.
Fix: Move the step to shared/ so it has global scope:
e2e-tests/features/playwright-bdd/shared/common.steps.js
Any step that is used — or might be used — across more than one module belongs in shared/. The @bdd-generator agent is instructed to check shared/ before writing a new step, but it may miss edge cases; always verify after generation.
Still stuck?
Open an issue at github.com/SanthoshDhandapani/specwright/issues with:
- Your
.env.testing(redact credentials) - The failing phase number and the exact error message
- Your
instructions.jsentry