Agent-skills cypress-skill
install
source · Clone the upstream repo
git clone https://github.com/LambdaTest/agent-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/LambdaTest/agent-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/cypress-skill" ~/.claude/skills/lambdatest-agent-skills-cypress-skill && rm -rf "$T"
manifest:
cypress-skill/SKILL.mdsource content
Cypress Automation Skill
You are a senior QA automation architect specializing in Cypress.
Step 1 — Execution Target
User says "test" / "automate" │ ├─ Mentions "cloud", "TestMu", "LambdaTest", "cross-browser"? │ └─ TestMu AI cloud via cypress-cli plugin │ ├─ Mentions "locally", "open", "headed"? │ └─ Local: npx cypress open │ └─ Ambiguous? → Default local, mention cloud option
Step 2 — Test Type
| Signal | Type | Config |
|---|---|---|
| "E2E", "end-to-end", page URL | E2E test | |
| "component", "React", "Vue" | Component test | |
| "API test", "cy.request" | API test via Cypress | |
Core Patterns
Command Chaining — CRITICAL
// ✅ Cypress chains — no await, no async cy.visit('/login'); cy.get('#username').type('user@test.com'); cy.get('#password').type('password123'); cy.get('button[type="submit"]').click(); cy.url().should('include', '/dashboard'); // ❌ NEVER use async/await with cy commands // ❌ NEVER assign cy.get() to a variable for later use
Selector Priority
1. cy.get('[data-cy="submit"]') ← Best practice 2. cy.get('[data-testid="submit"]') ← Also good 3. cy.contains('Submit') ← Text-based 4. cy.get('#submit-btn') ← ID 5. cy.get('.btn-primary') ← Class (fragile)
Anti-Patterns
| Bad | Good | Why |
|---|---|---|
| + | Arbitrary waits |
| Chain directly | Cypress is async |
with cy | Chain if needed | Different async model |
| Testing 3rd party sites | Stub/mock instead | Flaky, slow |
Single with everything | Multiple focused specs | Better isolation |
Basic Test Structure
describe('Login', () => { beforeEach(() => { cy.visit('/login'); }); it('should login with valid credentials', () => { cy.get('[data-cy="username"]').type('user@test.com'); cy.get('[data-cy="password"]').type('password123'); cy.get('[data-cy="submit"]').click(); cy.url().should('include', '/dashboard'); cy.get('[data-cy="welcome"]').should('contain', 'Welcome'); }); it('should show error for invalid credentials', () => { cy.get('[data-cy="username"]').type('wrong@test.com'); cy.get('[data-cy="password"]').type('wrong'); cy.get('[data-cy="submit"]').click(); cy.get('[data-cy="error"]').should('be.visible'); }); });
Network Interception
// Stub API response cy.intercept('POST', '/api/login', { statusCode: 200, body: { token: 'fake-jwt', user: { name: 'Test User' } }, }).as('loginRequest'); cy.get('[data-cy="submit"]').click(); cy.wait('@loginRequest').its('request.body').should('deep.include', { email: 'user@test.com', }); // Wait for real API cy.intercept('GET', '/api/dashboard').as('dashboardLoad'); cy.visit('/dashboard'); cy.wait('@dashboardLoad');
Custom Commands
// cypress/support/commands.js Cypress.Commands.add('login', (email, password) => { cy.session([email, password], () => { cy.visit('/login'); cy.get('[data-cy="username"]').type(email); cy.get('[data-cy="password"]').type(password); cy.get('[data-cy="submit"]').click(); cy.url().should('include', '/dashboard'); }); }); // Usage in tests cy.login('user@test.com', 'password123');
TestMu AI Cloud
// cypress.config.js module.exports = { e2e: { setupNodeEvents(on, config) { // LambdaTest plugin }, }, }; // lambdatest-config.json { "lambdatest_auth": { "username": "${LT_USERNAME}", "access_key": "${LT_ACCESS_KEY}" }, "browsers": [ { "browser": "Chrome", "platform": "Windows 11", "versions": ["latest"] }, { "browser": "Firefox", "platform": "macOS Sequoia", "versions": ["latest"] } ], "run_settings": { "build_name": "Cypress Build", "parallels": 5, "specs": "cypress/e2e/**/*.cy.js" } }
Run on cloud:
npx lambdatest-cypress run
Validation Workflow
- No arbitrary waits: Zero
— use interceptscy.wait(number) - Selectors: Prefer
attributesdata-cy - No async/await: Pure Cypress chaining
- Assertions: Use
chains, not manual checks.should() - Isolation: Each test independent, use
for authcy.session()
Quick Reference
| Task | Command |
|---|---|
| Open interactive | |
| Run headless | |
| Run specific spec | |
| Run in browser | |
| Component tests | |
| Environment vars | |
| Fixtures | |
| File upload | |
| Viewport | or |
| Screenshot | |
Reference Files
| File | When to Read |
|---|---|
| LambdaTest Cypress CLI, parallel, config |
| React/Vue/Angular component tests |
| Advanced commands, overwrite, TypeScript |
| Retry-ability, detached DOM, race conditions |
Advanced Playbook
For production-grade patterns, see
reference/playbook.md:
| Section | What's Inside |
|---|---|
| §1 Production Config | Multi-env configs, setupNodeEvents |
| §2 Auth with cy.session() | UI login, API login, validation |
| §3 Page Object Pattern | Fluent page classes, barrel exports |
| §4 Network Interception | Mock, modify, delay, wait for API |
| §5 Component Testing | React/Vue mount, stubs, variants |
| §6 Custom Commands | TypeScript declarations, drag-drop |
| §7 DB Reset & Seeding | API reset, Cypress tasks, Prisma |
| §8 Time Control | cy.clock(), cy.tick() |
| §9 File Operations | Upload, drag-drop, download verify |
| §10 iframe & Shadow DOM | Content access patterns |
| §11 Accessibility | cypress-axe, WCAG audits |
| §12 Visual Regression | Percy, cypress-image-snapshot |
| §13 CI/CD | GitHub Actions matrix + Cypress Cloud parallel |
| §14 Debugging Table | 11 common problems with fixes |
| §15 Best Practices | 15-item production checklist |