Requirement: all specs import { test, expect } from fixtures/rw.
Tests do not construct contexts, API clients, page objects, or auth state directly.
fixtures/rw.@playwright/test in specs.globalSetup and reused via .auth/storageState.json.api, home, profile, auth, editor, article, settings.const { test, expect } = require('../../fixtures/rw');
Specs use fixture-owned test and expect. No direct spec-level setup is allowed.
globalSetup..auth/emptyState.json is ensured before execution..auth/storageState.json is written after successful UI login.auth-chromium.API_BASE_URL, RW_USER_EMAIL, and RW_USER_PASSWORD.UI auth is owned by setup. API auth is owned by fixture. Tests do not own either.
| Fixture | Provides |
|---|---|
api | Authenticated API client for state seeding and verification |
home | Home page domain object |
profile | Profile page domain object |
auth | Auth page domain object |
editor | Editor page domain object |
article | Article page domain object |
settings | Settings page domain object |
test('example', async ({ editor, api }) => {
// fixtures injected — no setup required
}); Tests receive domain primitives as inputs. Tests do not construct page objects.
projects: [
{ name: 'auth-chromium', storageState: '.auth/storageState.json' },
{ name: 'unauth-chromium', storageState: '.auth/emptyState.json' }
] @auth → authenticated project@unauth → unauthenticated projectAuthenticated and unauthenticated execution is controlled at the project level, not through conditional logic inside tests.
| Rule | Requirement |
|---|---|
| Single entrypoint | All tests import from fixtures/rw. |
| Forbidden | new PageObject(...) inside tests |
| Forbidden | request.newContext() inside tests |
| Forbidden | manual login flows inside tests |
| Forbidden | hardcoded tokens |
| Forbidden | environment overrides inside tests |
| Required | all dependencies come from fixture injection |
| Required | all UI auth comes from storageState; all API auth comes from fixture |
Fixtures define what exists in the test. Tests do not manage auth state, clients, or page construction.
export WEB_BASE_URL="http://sut.testlab:3000"
export API_BASE_URL="http://sut.testlab:3001/api"
export RW_USER_EMAIL="rwuser_pw@test.com"
export RW_USER_PASSWORD="password" npx playwright test --project=auth-chromium npx playwright test --project=unauth-chromium npx playwright test specs/sprint7
Valid projects: auth-chromium, unauth-chromium.
Do not use --project=chromium unless it exists in config.
junit.xml[SCENARIO] S3.1 WRONG_ENVIRONMENT Cause: missing API or web base URL; missing credentials.
[SCENARIO] S3.2 SUT_UNREACHABLE Cause: network failure; DNS failure; routing failure; connection refused.
[SCENARIO] S3.3 AUTH_REJECTED Cause: invalid credentials; auth endpoint failure.
[fixtures/rw] CONTRACT VIOLATION Cause: missing env inputs; empty token; incorrect fixture usage.
Symptoms: test expects auth but runs unauth; missing UI state.
Cause: incorrect @auth / @unauth tagging or wrong selected project.
Sprint 07 transitions the framework from tests that manage setup to tests that receive controlled execution context.
| UPSTREAM |
Sprint 05 — Deterministic data (state correctness) Sprint 06 — Release gates (decision model) |
| DOWNSTREAM |
Sprint 08 — Page object structure at scale Sprint 14 — Structured failure artifacts Sprint 15 — Failure classification (triage) Sprint 17 — Release gate automation |
Fixtures define the execution boundary of the system. If this layer is not deterministic, all test results, classifications, and release decisions become unreliable.