English for Cypress and Playwright Testing
Master the vocabulary for discussing selectors, flakiness, fixtures, and assertions when writing end-to-end tests with Cypress and Playwright.
End-to-end testing conversations tend to circle around one recurring problem: flakiness. Whether you’re using Cypress or Playwright, the vocabulary for describing why a test fails intermittently — race condition, auto-waiting, network stubbing — is what actually helps a team fix the root cause instead of just adding another retry and hoping.
Key Vocabulary
End-to-end test (E2E test) A test that exercises an application the way a real user would, driving an actual browser through a full flow rather than testing an isolated unit or function. Example: “This bug wouldn’t have been caught by our unit tests alone — it only shows up when the full checkout flow runs end-to-end against a real browser.”
Selector
The string or strategy used to locate a specific element on the page, such as a CSS selector, text content, or a dedicated test attribute like data-testid.
Example: “This selector is matching on a CSS class used purely for styling, so it breaks every time a designer changes that class — we should switch to a dedicated test attribute instead.”
Auto-waiting The built-in behavior of both Cypress and Playwright to automatically retry an assertion or action for a period of time before failing, rather than requiring explicit manual waits. Example: “We don’t need an explicit wait here — auto-waiting already retries this assertion until the element appears or a timeout is reached.”
Flaky test (flakiness) A test that passes and fails inconsistently across identical runs without any change to the underlying code, usually caused by timing issues, unhandled asynchronous behavior, or test interdependence. Example: “This test is flaky specifically under CI load, which usually points to a race condition that just doesn’t reproduce reliably on a fast local machine.”
Fixture Predefined, reusable test data — like a JSON file representing an API response — used to set up consistent, predictable conditions for a test rather than relying on live or random data. Example: “We’re loading this fixture instead of hitting the real API, so the test’s input data stays consistent no matter when or where it runs.”
Network stubbing / interception The practice of intercepting network requests during a test and returning a controlled, predefined response, rather than letting the request hit a real backend. Example: “We stubbed the payment API response here so this test doesn’t depend on a real payment gateway being available and doesn’t risk making an actual charge.”
Assertion A statement in a test that verifies an expected condition is true, such as an element being visible or containing specific text, causing the test to fail if the condition isn’t met. Example: “This assertion is checking that the element exists, but not that it’s actually visible — a hidden element could still pass this check misleadingly.”
Test isolation The principle that each test should run independently, without depending on the state left behind by a previous test, so that tests can run in any order or in parallel reliably. Example: “This test only passes when it runs after another specific test, which means we’re missing test isolation — each test should set up its own state from scratch.”
Common Phrases
In code reviews:
- “This selector is tied to a CSS class used for styling — could we add a dedicated
data-testidso the test doesn’t break when the design changes?” - “We’re adding a hard-coded wait here instead of relying on auto-waiting — that usually masks a real timing issue rather than fixing it.”
- “This test depends on data left behind by a previous test, which breaks test isolation and will fail if we ever run tests in a different order.”
In standups:
- “Yesterday I replaced a chain of brittle CSS selectors with
data-testidattributes; today I’m confirming that fixed the flakiness we saw in CI.” - “I’m blocked on a flaky test that fails intermittently only in CI — I suspect a race condition between an API call and a UI update that isn’t accounted for.”
- “I finished adding network stubbing for the payment flow test, so it no longer depends on a real payment gateway being reachable.”
In test strategy discussions:
- “We should rely on auto-waiting and proper assertions instead of arbitrary sleep calls, since sleeps either waste time or aren’t long enough under load.”
- “Fixtures make our tests reproducible regardless of what’s actually in the staging database at the time they run.”
- “Test isolation is worth the setup cost — flaky, order-dependent tests erode trust in the whole suite much faster than a slightly slower but reliable one.”
Phrases to Avoid
Saying “the test is broken” for a flaky test. Say instead: “this test is flaky — it fails intermittently without a code change, which usually points to a race condition or timing issue” — a broken test fails consistently, while a flaky test needs a different diagnostic approach entirely.
Saying “just add a wait” as the default fix for flakiness. Say instead: “let’s check whether auto-waiting is already covering this, or whether the real issue is an assertion checking the wrong condition” — arbitrary waits often just paper over a race condition instead of resolving it.
Saying “the selector doesn’t work” without specifying why. Say instead: “this selector is tied to a styling class that changes often — let’s use a dedicated test attribute instead” — this identifies the actual instability, rather than treating the failure as random.
Quick Reference
| Term | How to use it |
|---|---|
| selector | ”Use a data-testid selector instead of a styling class.” |
| auto-waiting | ”Auto-waiting retries this assertion before timing out — no manual wait needed.” |
| flaky test | ”This test is flaky under CI load, likely a race condition.” |
| fixture | ”We load a fixture instead of depending on live API data.” |
| network stubbing | ”We stubbed the payment API so no real charge happens during tests.” |
| test isolation | ”Each test should set up its own state, not depend on a prior test.” |
Key Takeaways
- Distinguish a flaky test from a broken one — flaky failures need root-cause diagnosis (timing, race conditions), not just a rerun.
- Prefer dedicated test attributes over styling-based selectors, since the latter breaks whenever a designer changes a class name.
- Trust auto-waiting before reaching for arbitrary manual waits, which often mask rather than fix a real timing issue.
- Use fixtures and network stubbing to keep tests reproducible and independent of live backend state.
- Treat test isolation as a non-negotiable design principle — tests that depend on run order erode confidence in the whole suite.