playwright-testing — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited playwright-testing (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generate tests from evidence, not guesswork: inspect the product, name the claim, choose the smallest durable test structure, then harden until reruns are boring.
Playwright tests are checks — automated pass/fail assertions. Testing as investigation — charters, heuristics, oracles under stress, edge-case discovery, perspective rotation — is upstream. Compose with tester-mindset when strategy, risk framing, or the shape of the unknown dominates. This skill tells you how to build durable checks; it does not replace the thinking that decides which checks to build.
for Node Playwright Test, Playwright Pytest, Playwright .NET, or Java Playwright test projects
playwright-cli, UI Mode, or codegenin any ecosystem — route to setup-playwright
auth.setup.ts,setup-project wiring, or ecosystem equivalents — route to setup-playwright (using that wiring in tests belongs here)
compose with tester-mindset first
digraph route {
"Working Playwright harness exists?" [shape=diamond];
"Main artifact is config,\nbrowser install, or auth plumbing?" [shape=diamond];
"setup-playwright" [shape=box];
"playwright-testing" [shape=box];
"Working Playwright harness exists?" -> "setup-playwright" [label="no"];
"Working Playwright harness exists?" -> "Main artifact is config,\nbrowser install, or auth plumbing?" [label="yes"];
"Main artifact is config,\nbrowser install, or auth plumbing?" -> "setup-playwright" [label="yes"];
"Main artifact is config,\nbrowser install, or auth plumbing?" -> "playwright-testing" [label="no"];
}objects, fixtures, auth usage, parameterization, route/HAR mocking, test.step(), multi-role flows.
iframes, popups, downloads, dialogs, request-fixture polling, clock, accessibility.
— snapshot discipline, sessions, saved state, CLI tracing, --debug=cli.
— runner-side reruns, trace/report triage, codegen / UI Mode, visual QA.
is contested, or edge cases are the main job. Its claim/oracle/apparatus/ residual-risk vocabulary is assumed here.
accessibility, or frontend-polish is the claim.
auth, recovery, session, tenant, permission, or callback-origin boundaries.
plumbing rather than spec authoring.
contract, oracle, stakeholders, and cost of being wrong before writing code. A bank's checkout suite should be scoped differently from a side-project's — context drives how much evidence is enough. Keep E2E thin: protect critical journeys, push detail to unit, integration, or contract tests when they can prove it more cheaply.
(playwright.config.*, pytest config, .NET/Java test project settings), fixtures, page objects, data helpers, auth setup, scripts, CI hints, reporters, and neighboring specs. Note base URL, browser projects or equivalent scopes, retries, reusable auth state, startup contract, output dirs, test-id contract, dependencies, and trace/video policy.
playwright-cliagainst the running app. Snapshot before interacting so refs stay stable; re-snapshot after navigation. Scope large pages with --depth or a section target. If a locator stays ambiguous, use UI Mode, the Inspector, or codegen to generate and refine before writing the test. Use named sessions and state-save / state-load when multi-role comparison or preserved auth materially changes the investigation.
a plain spec suffices or repetition justifies page objects, fixtures, reused auth, parameterization, or controlled mocks. Add at least two off-happy-path cases.
Default to TypeScript @playwright/test only when no stronger local signal exists. Use user-facing locators, web-first assertions, isolated data, test.step() for multi-phase flows, fixtures over broad beforeEach, and a setup project plus storageState for reusable auth.
with --reporter=line or dot. Open the trace or report before guessing. Reproduce flakes with --workers=1, headed mode, --debug, or UI Mode. Once green, harden with --repeat-each 10 (or 5 when runtime is expensive), then broaden to the browser/device matrix only when the claim needs it.
suggest, what was intentionally mocked or excluded, and the next higher-fidelity probe if material risk remains.
Testing-phase only. If the blocker is port binding, sandbox, build locks, or missing browsers, route to setup-playwright.
paths or --grep over broad globs during triage.
runs.
missing, inspect the latest test-results/ directory first.
globally.
Walk top-down; stop at the first that fits:
getByRolegetByLabel / getByPlaceholdergetByText / getByAltText / getByTitlegetByTestIdlocator.filter({ hasText }) or filter({ has: ... })These are Playwright-grounded heuristics, not context-free laws. Each rule earns its place because a common failure mode hides behind its violation. Applied under pressure without thought they become ritual; applied with context they prevent real harm. If a rule conflicts with the named claim, state the conflict explicitly and choose deliberately rather than following by rote.
assertion against product behavior. One behavior per test; split if the name needs "and".
user-visible state, or another observable contract. Network waits are a means, not the oracle.
toBeVisible, toHaveText, toHaveURL,toHaveCount, toHaveValue). Do not wrap a one-shot async read in expect(): prefer await expect(locator).toBeVisible() over expect(await locator.isVisible()).toBe(true) — the first polls, the second is a single-shot race.
fill() for ordinary text entry; use pressSequentially() onlywhen the app genuinely reacts per keystroke.
locators with chaining, filtering, or an explicit contract rather than defaulting to first() or nth().
waitForTimeout as synchronization. Wait on user-visible state,URL change, or request completion that gates a visible contract.
expect.poll(...) orexpect(...).toPass({ timeout }). toPass() defaults to zero timeout — always pass an explicit one.
page.clock when the browser clock is theclaim; do not wait in real time.
of mutable backend data unless a fixture owns isolation.
seed, and clean up backend-persisted state.
force: true unless you can explainwhy the user can still perform the action.
@smoke, @vrt for filtering,test.slow() for legitimate long flows, test.fail() for expected failures, test.fixme() for unstable or wasteful cases.
files. Do not wrap one-off tests in a page-object layer by default.
beforeEach / afterEach for explicit,composable, or worker-scoped setup.
request fixture for API seeding or backend verification;it inherits baseURL and shared headers.
outside per-case loops so they run once, not once per generated case.
storageState unless thelogin UI itself is the claim.
separate storage states, not a shared page.
start waitForEvent(...) before the triggering action.
frameLocator() for iframes.mock the UI behavior being verified. When mocking in apps with service workers, set serviceWorkers: 'block'.
environment can keep baselines stable.
ARIA snapshots and axe-style scans are evidence, not signoff.
needs it.
sessionStorage, rendering that depends on real time, state mutating in uncontrolled side effects, locators that can only be reached via a screenshot — flag it as app-side design feedback, not only a test-side workaround. addInitScript, page.clock, explicit test ids, and similar tools are workarounds, not endorsements of the underlying coupling.
Nondeterminism is a risk to expose or control, not a quality goal.
2, local retries to 0.evidence.
--workers=1, open theartifact, fix the determinism root cause, rerun the targeted suite, then broaden.
the user explicitly wants them, use an explicit seed and print it on failure.
Stop adding tests when the claim has risk-appropriate evidence, remaining uncertainty is named, and the next test would cost more than the confidence it could add. When material risk remains but more authored coverage is inefficient, escalate to monitoring, canary, staged rollout, or explicit acceptance — do not inflate the suite as a substitute for that conversation. "More tests" is not a universal answer; it is one of several instruments.
Before blaming the product, rule out environment:
EADDRINUSE on the Playwright webServer port[id]page.route() interceptionThese are setup bugs, not product bugs. Fix them before weakening assertions.
A different failure class from flakiness. Before assuming a real defect:
workers: 1. Shared-state bugs surfaceserially in CI but hide behind parallelism locally. Re-run locally with --workers=1.
project may emulate mobile. Check the project that actually failed.
storageState captured locally may not match the CI authprovider. If state is path-dependent, the setup project must run in CI too. UI Mode does not run setup projects by default.
reuseExistingServer: true may be serving amanually-started dev build with uncommitted changes. CI builds from clean.
en-US. If the testreads formatted output, pin locale and timezoneId via test.use().
window.devicePixelRatio, inputmodality, or focus behavior may differ. Repro with --headed disabled.
adding retries or widening assertions.
Reject or rewrite tests with:
matters
toPass() without an explicit timeoutCommon excuses and expected responses live in references/pressure-tests.md. Load that reference when a Playwright shortcut is being rationalized or when revising the skill's trigger and quality rules.
When the claim is visible, run a dedicated visual pass:
final DOM.
loading states.
or overlapping UI is a failure.
screenshots as debugging artifacts.
Firefox or WebKit only when browser evidence is needed.
Details and snippets live in references/debugging-and-visual-qa.md.
When recommending or delivering tests, include:
Use playwright-cli to explore checkout and generate tests. → inspectthe checkout surface, name checkout claims, write deterministic specs for success and validation failures, run with --reporter=line.
Review these Playwright tests for flakiness. → look for weakassertions, sleeps, shared state, brittle selectors, retry-masked failures, and environment mistakes before calling anything a product bug.
Add responsive coverage for this settings page. → explore desktop andmobile viewports, assert stable navigation and accessible controls, use screenshots only when rendering itself is the contract.
Install Playwright in this repo. → route to setup-playwright; returnhere only after the harness exists and the job is authoring or hardening tests.
For doc refreshes, trigger audits, and pressure-test scenarios, see references/coverage-and-validation.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.