Skip to content
Back to skills

End To End Testing

ASecurity

Write reliable end-to-end tests that exercise real user journeys — Playwright for web, Maestro for mobile — without the flakiness that makes teams ignore them. Use when adding an end-to-end test, debugging a flaky test, choosing what to cover end-to-end vs unit/integration, setting up CI for browser/device tests, or replacing hard sleeps and brittle selectors with reliable ones. Triggers — "end-to-end test", "e2e", "Playwright", "Maestro", "the test is flaky", "browser test", "user flow test"...

  • 6 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 4, 2026
developmenttypescriptpythontestingdebuggingapifrontend

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned September 4, 2026

npx -y skills add kouroshez/coding-os --skill end-to-end-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of End To End Testing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for End To End Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kouroshez-end-to-end-testing/badge)](https://www.skillsdirectory.com/skills/kouroshez-end-to-end-testing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: end-to-end-testing
tier: quality
domain: [frontend, mobile]
description: Write reliable end-to-end tests that exercise real user journeys — Playwright for web, Maestro for mobile — without the flakiness that makes teams ignore them. Use when adding an end-to-end test, debugging a flaky test, choosing what to cover end-to-end vs unit/integration, setting up CI for browser/device tests, or replacing hard sleeps and brittle selectors with reliable ones. Triggers — "end-to-end test", "e2e", "Playwright", "Maestro", "the test is flaky", "browser test", "user flow test", "test the signup flow". Pairs with testing-strategy (which test type to pick — end-to-end is the top of the pyramid, used sparingly), a11y (accessible locators double as test locators), frontend-fundamentals + mobile-fundamentals.
globs: ""
paths: []
last_reviewed: "2026-06-04"
versions_ref: versions.json
---

# End-to-End Testing

End-to-end tests are the most valuable and the most expensive tests — they prove a real user journey works across the whole stack, and they break for unrelated reasons if written carelessly. The discipline: **few but critical** journeys, **semantic** locators, **zero hard sleeps**, and **isolated** data. A flaky end-to-end suite is worse than none — teams learn to ignore red.

> Lint Playwright specs for flakiness anti-patterns:
> `python3 scripts/lint_e2e.py tests/**/*.spec.ts`

## Cover journeys, not units (it's the tip of the pyramid)

End-to-end tests are slow and broad — reserve them for the handful of journeys
that, if broken, mean the product is down: sign up → log in, add to cart →
checkout, the core create→read→update path. Everything else (edge cases, error
states, validation) is cheaper and more reliable as unit/integration tests.
Which test type for a given change is owned by
[testing-strategy](../testing-strategy/SKILL.md) — this skill is how to write the
end-to-end ones well.

## Playwright — locators + auto-wait (web)

```typescript
// Wrong — brittle selector + a hard sleep = flaky and slow
await page.waitForTimeout(3000);
await page.click(".btn-primary.css-1x2y3z");      // generated class, breaks on rebuild

// Correct — semantic locator + auto-waiting assertion
await page.getByRole("button", { name: "Sign in" }).click();   // waits for actionable
await expect(page.getByText("Welcome")).toBeVisible();          // retries until true or times out
```

Playwright **auto-waits** for elements to be actionable — `getByRole`/`getByLabel`/
`getByText` plus web-first `expect` assertions retry automatically. A
`waitForTimeout` is always wrong: either too short (flaky) or too long (slow).
Prefer role/label/text locators (they double as accessibility checks — see
[a11y](../a11y/SKILL.md)) over CSS/XPath. Detail → [references/playwright.md](references/playwright.md).

## Maestro — flows for mobile

```yaml
# flows/login.yaml
appId: com.example.app
---
- launchApp
- tapOn: "Email"
- inputText: "user@example.com"
- tapOn: "Sign in"
- assertVisible: "Welcome"
```

Maestro drives real iOS/Android (or emulators) from a declarative YAML flow. It
has built-in retry/wait — no manual sleeps. Select by accessible text/id, not
pixel coordinates. Detail → [references/maestro.md](references/maestro.md).

## Kill flakiness at the source

| Flake cause | Fix |
|---|---|
| hard sleep (`waitForTimeout`) | auto-waiting locator + web-first `expect` |
| brittle selector (CSS class, nth-child) | `getByRole`/`getByTestId`/accessible text |
| shared/leftover data between tests | each test seeds + tears down its own data |
| test order dependence | full isolation — any test runs alone |
| real network to third parties | mock/route external calls; control the clock |
| race on navigation | `await` the action; let auto-wait handle readiness |

A test must pass **alone and in any order**. If it needs a previous test to have
run, it's not a test — it's a step in a script.

## CI

Run headless, sharded across workers (`--workers`, Playwright `--shard`),
retries = 1–2 for true environment blips only (not to paper over flake). On
failure, capture the **trace** (Playwright `trace: on-first-retry`) / Maestro
recording — debugging a CI-only failure without a trace is guesswork. Pin
versions ([versions.json](versions.json)); browsers via `playwright install`.

## Anti-patterns (reject on sight)

- `waitForTimeout` / `sleep` anywhere → auto-waiting assertion instead.
- CSS/XPath selectors tied to styling or generated classes → semantic locators.
- A test that depends on another test's data or order → isolate it.
- Hitting real third-party APIs in an end-to-end test → mock the boundary.
- A test with no assertion (only actions) → it proves nothing.
- Hundreds of end-to-end tests covering edge cases → push those down to unit/integration.
- Retries cranked to 5 to hide flake → fix the root cause.

## See also

- [references/playwright.md](references/playwright.md) — locators, fixtures, network mocking, traces, parallelism.
- [references/maestro.md](references/maestro.md) — flows, selectors, CI, device matrix.
- [assets/e2e-checklist.md](assets/e2e-checklist.md) — the ship gate.
- [testing-strategy](../testing-strategy/SKILL.md) · [a11y](../a11y/SKILL.md).

Files in this skill

  • SKILL.md5.2 KB
  • assets/e2e-checklist.md1.2 KB
  • references/maestro.md2.2 KB
  • references/playwright.md2.9 KB
  • scripts/lint_e2e.py3.2 KB
  • versions.json398 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.