Skip to content
AI & Agents
Skill

/cypress-flake-fixer

Find and fix flake-prone anti-patterns in an existing Cypress suite, and APIs removed in Cypress 12 to 16. Bundles a zero-dependency scanner for fixed cy.wait() delays, assigned command return values, async/await, force: true, chaining after actions, one-shot expect() inside

BOOST
From plugin
awesome-copilot
40k200 skills200 agents
Install
$ npx -y skills add github/awesome-copilot --skill cypress-flake-fixer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/cypress-flake-fixer

Context preview

The summary Claude sees to decide when to auto-load this skill.

Find and fix flake-prone anti-patterns in an existing Cypress suite, and APIs removed in Cypress 12 to 16. Bundles a zero-dependency scanner for fixed cy.wait() delays, assigned command return values, async/await, force: true, chaining after actions, one-shot expect() inside

SKILL.md

cypress-flake-fixer.SKILL.md
name: cypress-flake-fixer
description: 'Find and fix flake-prone anti-patterns in an existing Cypress suite, and APIs removed in Cypress 12 to 16. Bundles a zero-dependency scanner for fixed cy.wait() delays, assigned command return values, async/await, force: true, chaining after actions, one-shot expect() inside .then(), conditional testing, and removed APIs such as Cypress.env(), cy.exec(), cy.server()/cy.route(). Use when asked to fix flaky Cypress tests, remove cy.wait, stabilize or harden a Cypress suite, audit Cypress specs, debug "detached from the DOM" errors, or prepare an upgrade to Cypress 15 or 16.'

Cypress Flake Fixer

Audit an existing Cypress suite for the code patterns that cause intermittent failures, then fix them without hiding the problem behind retries, longer timeouts, or `force: true`.

When to Use This Skill

  • A Cypress spec passes locally and fails in CI, or fails once in every few runs
  • The suite contains `cy.wait(<number>)`, `{ force: true }`, or tests that only pass in order
  • Errors mention "detached from the DOM", "timed out retrying", or a subject that "is no longer attached"
  • The project is upgrading Cypress across a major version (12 through 16)
  • A review of Cypress test code is requested

For writing new Cypress tests from scratch, coding standards are enough. This skill is for diagnosing and repairing an existing suite.

Prerequisites

  • Node.js 18 or later to run the scanner (it has no dependencies and does not need Cypress installed)
  • The Cypress version, read from `package.json`. Fixes differ by major version

Workflow

1. Scan

node ./scripts/scan-cypress.mjs <project-root>
node ./scripts/scan-cypress.mjs <project-root> --json          # machine-readable
node ./scripts/scan-cypress.mjs <project-root> --strict        # add low-confidence rules
node ./scripts/scan-cypress.mjs cypress/e2e/checkout.cy.ts     # one file

The scanner reads the Cypress version from the nearest `package.json` and grades removed APIs as `error` when the installed major already rejects them and `warn` when they break on upgrade. Run `--list-rules` for the catalog.

Findings are heuristic. Open each location and confirm before editing.

2. Measure before changing anything

When the goal is to fix a specific flaky spec, record how often it fails first. Without a baseline there is no way to tell a fix from luck.

for i in $(seq 1 20); do npx cypress run --spec "cypress/e2e/checkout.cy.ts" --quiet || echo "FAIL $i"; done

A spec that fails 1 run in 10 needs about 30 clean runs after the fix before the fix is believable.

3. Fix in this order

| Order | Rules | Why first | |---|---|---| | 1 | CY002, CY003, CY007 graded `error` | The test is wrong or already broken; other fixes build on correct command flow | | 2 | CY001, intercept ordering | Time-based waits are the largest single source of flake | | 3 | CY005, CY006 | Broken retry-ability causes detached-DOM and one-shot assertion failures | | 4 | CY004 | `force: true` hides a real overlap, animation, or disabled state | | 5 | CY008, CY010, CY012 | State leaks and order dependence | | 6 | CY013, CY101, CY102 | Selector and assertion hygiene |

Before-and-after code for every rule is in [references/anti-patterns.md](./references/anti-patterns.md). Replacements for removed APIs are in [references/removed-apis.md](./references/removed-apis.md). Read the section for the rule being fixed; do not load both files upfront.

4. Replace each fixed wait with the condition it was standing in for

Do not delete a `cy.wait(n)` or swap it for a guess. Work out what the delay covered:

| The wait covered | Replace with | |---|---| | A network request | `cy.intercept(...).as('x')` registered before the trigger, then `cy.wait('@x')` | | A render that follows a request or state change | A `.should()` on the DOM that results | | A debounce, throttle, polling interval, or toast timeout | `cy.clock()` before `cy.visit()`, then `cy.tick(ms)` | | A CSS animation or transition | An assertion on the final state; Cypress already waits for the element to stop moving before acting | | Client-side hydration of server-rendered HTML | A signal the app sets when hydration finishes (see Gotchas) | | Unknown | Run the test in `npx cypress open`, select the wait in the Command Log, and read which requests and DOM changes happened during it |

5. Verify

1. Run the changed spec alone, then repeat it at least as many times as the baseline run. 2. Rerun the scanner and compare counts per rule. 3. Run the full suite once to catch order dependence exposed by the change.

Rules for the fix itself

  • Change test code only. If the test exposes an application bug (double submit, missing loading state, race in the UI), report it instead of working around it.
  • Do not raise `defaultCommandTimeout`, add `retries`, or add `{ force: true }` to make a test pass. Each one converts a visible failure into a slower or hidden one.
  • Do not replace `cy.wait(2000)` with `cy.wait(5000)`, or with `.should('exist')` on an element that was already present.
  • Keep one rule category per commit so a regression can be bisected.
  • Fix shared custom commands in `cypress/support` first. A fixed wait inside a command runs in every test that calls it.

Gotchas

  • **Register `cy.intercept()` before the request can fire.** For requests made on page load that means before `cy.visit()`. An intercept registered after the request has left never matches, and `cy.wait('@alias')` times out intermittently depending on network speed.
  • **Each `cy.wait('@alias')` consumes one request.** If the app calls the endpoint twice, the first wait resolves on the first call and the assertion runs against stale data. Wait once per expected call, or assert on the DOM.
  • **GraphQL uses one URL for every operation.** Alias inside the handler: `cy.intercept('POST', '/graphql', (req) => { if (req.body.operationName === 'GetOrders') req.alias = 'getOrde
Read more
Ships withawesome-copilot

A community-created collection of custom agents, instructions, skills, hooks, workflows, and plugins to supercharge your GitHub Copilot experience.

Get the whole plugin

Other skills on awesome-copilot.