Skip to content

About

Playwright + TypeScript framework demo: page objects, fixtures, UI and API suites, CI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

playwright-ts-framework

CI

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.

Architecture overview

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 is InventoryPage.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 /posts resource. Response contracts are zod schemas checked with expectContract, 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 in tsconfig.json and resolved natively by Playwright.

Running

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 report

Docker (official Playwright image):

docker build -t playwright-ts-framework .
docker run --rm -v "$PWD/playwright-report:/app/playwright-report" playwright-ts-framework

The 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

Reporting and CI

  • Reporters: console list, Playwright HTML (playwright-report/).
  • Traces are captured on first retry; screenshots and video are kept on failure.
  • .github/workflows/ci.yml runs typecheck and tests on push, pull request and manual dispatch, then uploads the HTML report and (on failure) test-results/ as artifacts.

Design decisions

  • Authenticate once, reuse everywhere. A setup project produces storageState, so UI specs skip the login form. Login specs opt out with an empty storageState.
  • Semantic locators first. Elements are found the way users and assistive technology find them: getByRole with an accessible name (textboxes, buttons, the alert for 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. testIdAttribute is set to data-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. strict and noUncheckedIndexedAccess are 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 forbidOnly apply only when CI is set, so local runs fail fast.

Related projects

Limitations

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.

Project layout

.
├── .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

License

MIT, see LICENSE.

About

Playwright + TypeScript framework demo: page objects, fixtures, UI and API suites, CI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages