Overview
@saflib/playwright provides shared Playwright utilities for SAF products: typed string locators aligned with Vue copy, screenshot helpers for journey review, Vuetify conveniences, and a default config SPA packages extend.
E2E specs live in each client SPA under e2e/ (see @saflib/vue — e2e/). Product layout and client packages are described in base.
Writing tests
Tests are often authored manually or with agent help. A typical flow:
- Run the app against a production-like build (the
prod-localscript in thedeploy/folder). Production bundles behave more consistently under Playwright. - Use Playwright codegen for a first pass.
- Refactor to fixtures and
getByStringusing page.strings.tsexports. After vue/add-view, each page has a fixture stub to extend. This step is particularly good for an agent to do.
You can also use the vue/add-e2e-test workflow to create Playwright tests, though it's a good idea to have created the codegen tests to include in the prompts.
What this package provides
| Export | Role |
|---|---|
getByString | Locate elements from the same ElementString objects Vue binds (see String locators) |
attachScreenshot / cleanScreenshots | Visual record of a user journey in the HTML report; Chromium copies land beside the spec for deploy bundling |
chooseVuetifySelectOption | Open a Vuetify combobox and pick an option (handles async items and truncated labels) |
getUniqueEmail / getUniqueId | Ephemeral test identities |
tightAndroidViewport | Small mobile viewport for responsive checks |
playwright.config | Default SAF config (browsers, health gate, timeouts) |
Entrypoint: @saflib/playwright and @saflib/playwright/playwright.config.
Integration
SPA packages — each {product}/clients/{spa}/ holds e2e/**/*.spec.ts and a playwright.config.ts that re-exports the shared default (see base/clients/common/playwright.config.ts). Set DOMAIN and PROTOCOL for the stack under test (local dev uses docker.localhost / http).
Fixtures — page-level Playwright fixtures (PageName.fixture.ts) are scaffolded by vue/add-view. Cross-SPA flows compose fixtures from @saflib/ory-kratos-spa/fixtures, product common/fixtures, and page fixtures (example: base/clients/admin/e2e).
Security e2e — HTTP/browser security specs in @saflib/base-security use createSecurityPlaywrightConfig from @saflib/security/playwright/config (see @saflib/security), not this package's SPA default.
String locators
Playwright's built-in locators are flexible, but copy-heavy UIs break tests when strings drift. SAF shares the same string objects between Vue templates and Playwright via ElementString / ElementStringObject from @saflib/utils — see best-practices — shared strings.
Each page exports a .strings.ts file; the SPA re-exports them at ./strings so Playwright imports strings without pulling in Vite or Vue (see vue — strings.ts).
String objects use keys that map to HTML attributes (text, aria-label, data-testid, placeholder, label, …). Bind in Vue:
<button v-bind="elementStringObject" />getByString picks the best matching Playwright locator for whichever keys are present (label → test id → placeholder → text). For i18n interpolation patterns in plain strings, it uses the same regex helper as @saflib/utils.
Define and organize strings in @saflib/vue — Components and i18n.
User journeys
Tests should cover the designed user journeys for the SPA they primarily exercise. Specs may cross subdomains (auth login, admin setup) when those dependencies are part of the journey — that is expected.
Organize specs under e2e/{journey}/ so screenshot artifacts stay grouped per flow.
Use attachScreenshot at key steps to document the journey in the HTML report. Call cleanScreenshots at the start of a spec so Chromium PNGs beside the test file reflect the latest run (gitignored; optional deploy bundling).
Default Playwright config
@saflib/playwright/playwright.config provides:
- Projects — Chromium and Firefox, both depending on a server health setup project
- Global health gate —
global.setup.tspolls{PROTOCOL}://api.{DOMAIN}/healthuntil all configured API subdomains return 200 (matches product Caddyapi.{DOMAIN}) - Timeouts — 10s action and expect timeouts (Playwright defaults are 30s)
- CI —
forbidOnly, two retries, single worker; local runs use parallel workers - Tracing —
on-first-retry; HTML reporter
Extend or replace in a SPA's playwright.config.ts when a product needs extra projects (mobile viewport, webkit, etc.).