A Playwright + TypeScript framework built to show how I'd actually architect a test suite at a senior level, not just how I'd write individual tests.
ARCHITECTURE.md is the part that matters — it explains why things are built this way, not just what's in the repo.
Written with an AI assistant's help (docs included), but every architectural decision in here is mine and I can defend any of it in a live conversation — treat that as the actual test, not the prose.
AIProvider interface (OpenRouter behind it) used for two things: semantic assertions on text that isn't fixed-wording, and Zod-validated AI-generated test data. Nothing calls the API directly from a test.@smoke PR gate, a full suite that publishes results as a GitHub check, and a nightly run with a published report and flaky-test detection.| Suite | Target | Why |
|---|---|---|
tests/api/ |
Conduit (real REST API) | Real CRUD resources, auth, and validation — a fair target for contract testing |
tests/hybrid/ |
Conduit (API + UI) | API write, UI read, and back, against a real app |
tests/ui/ |
QA Playground | Clean components, so the suite can focus on locator strategy and dialog handling |
TypeScript · Playwright Test · Zod · @faker-js/faker · OpenRouter · ESLint + Prettier · Husky + lint-staged · GitHub Actions
Node version is pinned in .nvmrc (run nvm use if you have nvm).
npm install
npx playwright install --with-deps chromium
cp .env.example .env # optional — only needed if you want OPENROUTER_API_KEY set
npm run test:smoke # fast subset, same as the PR gate
npm run test:api # API suite against Conduit
npm run test:ui # UI suite against QA Playground
npm run test:hybrid # hybrid API+UI suite against Conduit
npm run test:a11y # accessibility checks (axe-core), grep @a11y
npm run test:perf # Core Web Vitals budgets, grep @perf
npm run test:resilience # network failure / error-path tests, grep @resilience
npm run test:negative # data-driven input validation tests, grep @negative
npm run test:ai # the AI-assisted hybrid test, grep @ai
npm test # everything
No credentials needed for any of this. A Conduit test user gets registered per worker automatically (src/fixtures/auth.fixture.ts). OPENROUTER_API_KEY is optional — without it, the AI-assisted hybrid test just falls back to faker data and skips the bonus semantic check. The test itself still runs and reports.
Skips the local Node/Playwright-browser setup entirely — the image is pinned to the same Playwright version this repo uses, so it's the same environment CI runs in.
docker build -t playwright-ts-portfolio .
docker run --rm playwright-ts-portfolio
npm run lint # eslint
npm run format:check # prettier --check
npm run typecheck # tsc --noEmit
There's a Husky pre-commit hook running lint-staged on whatever's staged.
src/
ai/ AIProvider interface + OpenRouter implementation, assertion + data-gen helpers
api/ fluent ApiClient, endpoint clients, Zod schemas
core/ logger (ring buffer), self-healing locator, web-vitals collector
expects/ custom expect matchers
fixtures/ Playwright fixture composition — the only import path for tests
flows/ named business use cases, composed from Page Objects
pages/ Page Objects — one per page used in tests
utils/ test data builders
tests/
api/ Conduit API tests (CRUD + data-driven negative tests)
ui/ QA Playground UI tests
hybrid/ Conduit API+UI (+ AI) tests
ARCHITECTURE.md has the reasoning behind the layout. CONTRIBUTING.md covers how to add to it, whether that's a new Page Object, a fixture, or anything else.