cypress-testing
Authors and improves Cypress E2E tests - installs Cypress, configures `cypress.config.ts`, authors `cy.*` command chains, refactors existing specs (`cy.wait(ms)` sleeps into assertions, repeated flows into `cy.session` custom commands), and debugs with the time-travel GUI; Cypress Cloud for parallel runs and recording. Use for both greenfield test authoring and improving hand-written specs already in the codebase. For automated refactor of raw Cypress Studio recordings specifically, use a dedicated codegen-review pass.
Install with skills.sh (any agent)
npx skills add testland/qa --skill cypress-testingcypress-testing
Overview
Per cy-overview (opens in new window):
"Cypress is described as 'a next generation front end testing tool built for the modern web.'"
Differentiators (cy-overview (opens in new window)):
When to use
For cross-browser including WebKit, see playwright-testing.
How to use
Step 1 - Install
npm install --save-dev cypress
npx cypress open # first run scaffolds the projectThe interactive setup creates cypress.config.ts + cypress/ directory.
Step 2 - Configure
// cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.{ts,tsx}',
video: true,
screenshotOnRunFailure: true,
retries: { runMode: 2, openMode: 0 },
},
component: {
devServer: {
framework: 'react',
bundler: 'vite',
},
},
});Step 3 - Author E2E tests
// cypress/e2e/checkout.cy.ts
describe('Checkout flow', () => {
beforeEach(() => {
cy.visit('/login');
cy.get('[data-testid="email"]').type('user@example.com');
cy.get('[data-testid="password"]').type('test-password');
cy.get('[data-testid="signin-btn"]').click();
cy.contains('Welcome').should('be.visible');
});
it('completes checkout end-to-end', () => {
cy.visit('/products/BOOK-001');
cy.contains('button', /add to cart/i).click();
cy.get('[data-testid="cart-count"]').should('have.text', '1');
cy.visit('/checkout');
cy.get('[name="card"]').type('4242 4242 4242 4242');
cy.contains('button', /place order/i).click();
cy.contains('Order confirmed', { timeout: 10000 }).should('be.visible');
});
});Per cy-overview (opens in new window), assertions auto-wait - no cy.wait(2000) needed.
Step 4 - Use cypress-testing-library
For accessibility-first selectors:
npm install --save-dev @testing-library/cypress// cypress/support/commands.ts
import '@testing-library/cypress/add-commands';
// Now in tests:
cy.findByRole('button', { name: /sign in/i }).click();
cy.findByLabelText('Email').type('user@example.com');findByRole (from cypress-testing-library) is the Cypress equivalent of Playwright's getByRole - preferred for accessibility-aware testing.
Step 5 - Custom commands
// cypress/support/commands.ts
declare global {
namespace Cypress {
interface Chainable {
login(email: string, password: string): Chainable<void>;
}
}
}
Cypress.Commands.add('login', (email, password) => {
cy.session([email, password], () => {
cy.visit('/login');
cy.findByLabelText('Email').type(email);
cy.findByLabelText('Password').type(password);
cy.findByRole('button', { name: /sign in/i }).click();
cy.url().should('not.include', '/login');
});
});
// Usage in tests:
beforeEach(() => {
cy.login('user@example.com', 'pwd');
});cy.session(...) caches the auth state across tests - reuse the login result, avoid re-running the login flow.
Step 6 - Run
# Open the GUI (interactive; great for development)
npx cypress open
# Headless (CI)
npx cypress run
# Single spec
npx cypress run --spec "cypress/e2e/checkout.cy.ts"
# Specific browser
npx cypress run --browser firefox
npx cypress run --browser chromeStep 7 - Time-travel debugger
Per cy-overview (opens in new window): "Hover over commands in the Command Log to see exactly what happened at each step."
In cypress open mode:
This is Cypress's killer feature - debugging by visually replaying the test.
Step 8 - Cypress Cloud + CI
Recording and parallel runs go through Cypress Cloud (paid; OSS alternative currents-integration in the qa-test-reporting plugin), and the GitHub Actions job wires cypress-io/github-action + screenshot artifacts on failure. Commands and the full workflow YAML: references/ci-and-cloud.md.
Worked example
A team has a hand-written checkout.cy.ts that logs in from scratch in every test and sleeps cy.wait(3000) before asserting the cart count. It flakes about 1 run in 5 on CI.
Result: the flow runs faster (login cached, no fixed sleep) and the flake disappears because every wait is now assertion-driven.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
cy.wait(2000) between actions | Defeats Cypress's auto-wait; flaky. | Trust assertions; chain commands. |
cy.get('.button-class') (CSS class) | Brittle; defeats findByRole patterns. | cypress-testing-library + data-testid (Steps 3-4). |
| Cross-test state via global variables | Tests order-dependent. | cy.session() for auth; per-test fresh state. |
| Mixing Cypress + plain xUnit assertions | Confusing; two assertion styles. | Cypress chains throughout. |
| Running Cypress against production | Cypress can mutate state; pollutes prod data. | Local / staging only. |
Limitations
References
Cypress Cloud + CI integration
View source (opens in new window)Cypress Cloud + CI integration
Operational detail split out of cypress-testing. The core authoring loop (config, specs, custom commands, the time-travel debugger) stays in SKILL.md; this file holds the recording / parallelization and the CI wiring.
Cypress Cloud (paid; optional)
# Record run to Cypress Cloud
npx cypress run --record --key <CYPRESS_RECORD_KEY>
# Parallel
npx cypress run --record --parallelCloud provides:
OSS alternative: currents-integration (in the qa-test-reporting plugin) covers similar analytics for both Cypress + Playwright.
CI integration (GitHub Actions)
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: cypress-io/github-action@v6
with:
start: npm start
wait-on: 'http://localhost:3000'
browser: chrome
record: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-screenshots
path: cypress/screenshotsRelated skills
browserstack-automate
Author and run E2E tests on BrowserStack Automate - cloud grid covering 3000+ real device + browser combinations. Covers BROWSERSTACK_USERNAME + ACCESS_KEY auth, hub URL https://hub-cloud.browserstack.com/wd/hub, W3C capabilities + bstack:options (projectName, buildName, sessionName), BrowserStackLocal for testing against localhost / internal environments, parallel session limits, and CI integration. Use for cross-browser regression on real devices + browsers - distinct from running a single test framework locally, and from a matrix runner limited to the browser engines bundled on the local machine.
lambdatest-automate
Author and run E2E tests on LambdaTest - cloud grid for cross-browser + real-device testing with W3C WebDriver, Cypress, Playwright, and Appium support. Covers LT_USERNAME + LT_ACCESS_KEY auth, hub URL hub.lambdatest.com/wd/hub, W3C capabilities + LT:Options dict (build, name, project, smartUI, network, console, video, tunnel), LambdaTest Tunnel for internal apps. Use for cross-browser regression with LambdaTest as the cloud grid; complements BrowserStack + Sauce Labs.
playwright-testing
Authors and remediates Playwright E2E tests across Chromium, Firefox, WebKit - `npm init playwright@latest` scaffolding, `playwright.config.ts` browser projects, accessibility-first locators (`getByRole`/`getByLabelText`) to replace brittle CSS selectors, web-first assertions to eliminate `waitForTimeout` flakiness, Page Object pattern, trace viewer debugging, sharded parallel execution with merged HTML reporting, and GitHub Actions CI integration. Use for new test authoring, flakiness remediation, and CI setup; for reviewing codegen output specifically, use a dedicated codegen-review pass.
puppeteer-testing
Authors browser automation scripts using Puppeteer - Chrome / Chromium-only headless / headed automation, Page object via `page.*` API, network interception, PDF generation, screenshot capture, scraping. Distinct from Playwright (Puppeteer's older sibling, Chrome-only) - use Puppeteer for Chrome-only browser automation tasks (scraping, generating PDFs from HTML, screenshot pipelines) where Playwright's multi-browser support is unneeded overhead. Use when a project already depends on `puppeteer` / `puppeteer-core`, or when a Chrome-only script must emit PDFs, screenshots, or scraped data rather than assert on a page.
saucelabs-automate
Author and run E2E tests on Sauce Labs - cloud grid for cross-browser + real-device testing with W3C WebDriver, Cypress, Playwright, and Appium support. Covers SAUCE_USERNAME + SAUCE_ACCESS_KEY auth, regional hub URLs (us-west-1 / us-east-4 / eu-central-1), W3C capabilities, sauce:options dict (build, name, screenResolution, tunnelName), Sauce Connect Proxy for internal-environment testing. Use for cross-browser regression with Sauce Labs as the cloud grid; complements BrowserStack + LambdaTest as alternative providers.
selenium-testing
Authors Selenium WebDriver tests in any of its 6+ supported languages (Java, Python, JavaScript, C#, Ruby, Kotlin, PHP) - picks the appropriate language binding, configures WebDriver per browser, uses `By.*` locators with the team's accessibility-first preference where supported, runs locally + via Selenium Grid for distributed execution, parses results to JUnit XML. Use for legacy Selenium-locked stacks; new projects pick Playwright or Cypress.
testcafe-testing
Authors TestCafe E2E tests - `npm install testcafe`, fixture/test syntax, `Selector` API for queries, automatic-waits, no WebDriver required (TestCafe injects scripts via a proxy), supports any browser including remote / cloud farms. Use when the team prefers a no-WebDriver architecture and one of TestCafe's specific features (e.g., role-based auth) matters.
web-e2e-overview
Teaches web end-to-end testing from first principles: what browser-driven E2E covers and how it differs from unit and integration tests, a decision table for choosing between Playwright, Cypress, Selenium WebDriver, WebdriverIO, Puppeteer, TestCafe and the BrowserStack / Sauce Labs / LambdaTest cloud grids based on files already present in the repo, install and first-run commands for each, and the flakiness traps (fixed sleeps, CSS and XPath selectors, state shared between tests) that sink new suites. Use when a web application has no E2E coverage yet, when picking or replacing an E2E framework, or when a first browser test needs to go green end to end.
webdriverio-testing
Authors WebdriverIO E2E tests - `npm init wdio@latest` scaffolding, services architecture (sauce, browserstack, appium, devtools), reporters (spec, allure, junit), built-in Mocha/Jasmine/Cucumber framework integrations. WebdriverIO sits between Selenium (W3C protocol) and Playwright (modern API) - Selenium-protocol-compatible with rich plugin ecosystem. Use when the team needs WebDriver protocol + service-based device-farm integration.