From qa-web-e2e
Authors Cypress E2E tests - `npm install cypress`, `cypress.config.ts` setup, `cy.*` command chains, automatic-waiting commands, time-travel debugger via Cypress GUI, custom commands for reusable patterns, Cypress Cloud for parallel/recording. Per Cypress''''s positioning: "fast, consistent and reliable tests that are flake-free" via in-browser execution architecture.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qa-web-e2e:cypress-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Per [cy-overview][cy]:
Per cy-overview:
"Cypress is described as 'a next generation front end testing tool built for the modern web.'"
Differentiators (cy-overview):
- Time Travel Debugging: "Cypress takes snapshots as your tests run. Hover over commands in the Command Log to see exactly what happened at each step."
- Automatic Waiting: "Never add waits or sleeps to your tests. Cypress automatically waits for commands and assertions before moving on."
- Reliability: "The testing approach avoids Selenium/WebDriver architecture, resulting in fast, consistent and reliable tests that are flake-free."
For cross-browser including WebKit, see
playwright-testing.
npm install --save-dev cypress
npx cypress open # first run scaffolds the project
The interactive setup creates cypress.config.ts + cypress/
directory.
// 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',
},
},
});
// cypress/e2e/checkout.cy.ts
describe('Checkout flow', () => {
beforeEach(() => {
cy.visit('/login');
cy.get('[data-testid="email"]').type('[email protected]');
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, assertions auto-wait - no cy.wait(2000)
needed.
For accessibility-first selectors (per the team's
e2e-selector-quality-critic
convention):
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('[email protected]');
findByRole (from cypress-testing-library) is the Cypress
equivalent of Playwright's getByRole - preferred for
accessibility-aware testing.
// 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('[email protected]', 'pwd');
});
cy.session(...) caches the auth state across tests - reuse the
login result, avoid re-running the login flow.
# 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 chrome
Per cy-overview: "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.
# Record run to Cypress Cloud
npx cypress run --record --key <CYPRESS_RECORD_KEY>
# Parallel
npx cypress run --record --parallel
Cloud provides:
OSS alternative: currents-integration
covers similar analytics for both Cypress + Playwright.
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/screenshots
| 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. |
appium-testing.currents-integration.playwright-testing,
selenium-testing,
webdriverio-testing -
alternative E2E frameworks.currents-integration - OSS analytics alternative to Cypress Cloud.e2e-selector-quality-critic - selector convention.npx claudepluginhub testland/qa --plugin qa-web-e2eProvides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.