A compact, production-style test automation framework built with Playwright and TypeScript. It demonstrates UI automation against SauceDemo and API contract testing against JSONPlaceholder.
Author: Yurii Simashkevych, Senior/Lead SDET.
Three Playwright projects, defined in playwright.config.ts:
| Project | Purpose | Notes |
|---|---|---|
setup |
Logs in once through the UI and saves storageState to playwright/.auth/ |
Runs before ui |
ui |
Login, cart, checkout and error-state tests | Depends on setup; starts already authenticated |
api |
Status, header and contract checks on /posts and /users |
No browser, no dependency on setup |
Layers:
- Page objects (
src/pages) expose locators and user-level actions only. Assertions live in the specs, so each test shows what it verifies; the one exception isInventoryPage.expectLoaded(), a readiness check. - Fixtures (
src/fixtures) inject page objects (index.ts) and a typed API client (api.ts) into tests. - API client (
src/api) wraps the/postsresource. Response contracts are zod schemas checked withexpectContract, which fails with every violation listed and returns the typed body. - Test data and environment (
src/data) keep public demo credentials, checkout info, base URLs and the storageState path out of specs and config. - Path aliases
@pages/*,@fixtures/*,@api/*,@data/*are declared intsconfig.jsonand resolved natively by Playwright.
npm ci
npx playwright install chromium
npm test # everything (setup + ui + api)
npm run test:ui # setup + ui
npm run test:api # api only
npm run typecheck # tsc --noEmit
npm run report # open the Playwright HTML reportDocker (official Playwright image):
docker build -t playwright-ts-framework .
docker run --rm -v "$PWD/playwright-report:/app/playwright-report" playwright-ts-frameworkThe Docker base image tag matches the exact @playwright/test version pinned in package.json; bump both together.
Targets can be overridden with environment variables:
| Variable | Default |
|---|---|
UI_BASE_URL |
https://www.saucedemo.com |
API_BASE_URL |
https://jsonplaceholder.typicode.com |
- Reporters: console list, Playwright HTML (
playwright-report/). - Traces are captured on first retry; screenshots and video are kept on failure.
.github/workflows/ci.ymlruns typecheck and tests on push, pull request and manual dispatch, then uploads the HTML report and (on failure)test-results/as artifacts.
- Authenticate once, reuse everywhere. A setup project produces
storageState, so UI specs skip the login form. Login specs opt out with an emptystorageState. - Semantic locators first. Elements are found the way users and assistive technology find them:
getByRolewith an accessible name (textboxes, buttons, thealertfor errors, the "Sort products" combobox, the "Thank you for your order!" heading). The cart count is asserted through the button's accessible name ("Cart, 2 items"), which is what a screen reader announces. If a role locator cannot find something, that is an accessibility bug in the product, not a reason to reach for CSS. - Test ids only as a fallback, with a comment saying why: product cards have no list or article role, so
data-test="inventory-item"scopes actions to one card, and prices are plain text with no role.testIdAttributeis set todata-test, which SauceDemo uses. No CSS or XPath. - No hard sleeps. All waiting is through web-first assertions and
expect(...).toPass(). - Fixtures over inheritance. Page objects are composed via fixtures, so each test requests only what it needs and setup/teardown stays explicit.
- Isolated test state. Every test gets a fresh browser context; cart state does not leak between tests. JSONPlaceholder is a fake API (writes are echoed, not persisted), so write tests assert on the echoed response only.
- Strict TypeScript.
strictandnoUncheckedIndexedAccessare enabled; the typecheck runs in CI before the tests. - Separate UI and API projects so they can run, fail and be filtered independently.
- CI retries (2) and
forbidOnlyapply only whenCIis set, so local runs fail fast.
- graphql-api-tests-go: GraphQL API testing in Go.
- ai-test-triage: LLM-assisted triage of Playwright failures.
- qa-claude-skills: Claude Code skills for QA, including the Playwright review checklist this repo follows.
Both targets are public third-party demo sites. Tests depend on their availability and on their current behavior; a failure can come from the site rather than from the framework.
.
├── .github/workflows/ci.yml
├── Dockerfile
├── playwright.config.ts
├── tsconfig.json
├── src
│ ├── api/ # PostsClient, schemas / contract checks
│ ├── data/ # users, checkout data, base URLs (env.ts)
│ ├── fixtures/ # UI and API fixtures
│ └── pages/ # Login, Inventory, Cart, Checkout page objects
└── tests
├── setup/ # auth.setup.ts (storageState)
├── ui/ # login.spec.ts, cart-checkout.spec.ts
└── api/ # posts.spec.ts
MIT, see LICENSE.