.agents/skills/cypress/SKILL.md
Cypress E2E testing framework. Covers commands, assertions, and component testing. Use for end-to-end testing. USE WHEN: user mentions "cypress", "e2e test", "cy.get", "cy.visit", asks about "cypress intercept", "component testing", "cypress commands" DO NOT USE FOR: Unit tests - use `vitest` or `jest`; Multi-tab scenarios - Cypress doesn't support; Native mobile apps - use Appium; Performance testing - use dedicated tools
npx skillsauth add d-subrahmanyam/deno-fresh-microservices cypressInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:cypressfor comprehensive documentation.
vitest or jest for isolated testsdescribe('Login', () => {
beforeEach(() => {
cy.visit('/login');
});
it('should login successfully', () => {
cy.get('[data-testid="email"]').type('[email protected]');
cy.get('[data-testid="password"]').type('password123');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
cy.contains('Welcome back').should('be.visible');
});
it('should show error for invalid credentials', () => {
cy.get('[data-testid="email"]').type('[email protected]');
cy.get('[data-testid="password"]').type('wrong');
cy.get('button[type="submit"]').click();
cy.contains('Invalid credentials').should('be.visible');
});
});
// Selection
cy.get('.class');
cy.get('#id');
cy.get('[data-testid="element"]');
cy.contains('text');
cy.find('.child');
// Actions
cy.click();
cy.type('text');
cy.clear();
cy.check();
cy.select('option');
cy.scrollIntoView();
// Navigation
cy.visit('/page');
cy.go('back');
cy.reload();
cy.get('element')
.should('be.visible')
.should('have.text', 'Hello')
.should('have.class', 'active')
.should('have.attr', 'href', '/home')
.should('have.length', 3)
.should('contain', 'text')
.should('not.exist');
// Chained
cy.get('input').should('have.value', 'test').and('be.disabled');
// cypress/support/commands.ts
Cypress.Commands.add('login', (email: string, password: string) => {
cy.visit('/login');
cy.get('[data-testid="email"]').type(email);
cy.get('[data-testid="password"]').type(password);
cy.get('button[type="submit"]').click();
});
// Usage
cy.login('[email protected]', 'password');
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.visit('/users');
cy.wait('@getUsers');
cy.intercept('POST', '/api/users', { statusCode: 201 }).as('createUser');
// cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
viewportWidth: 1280,
viewportHeight: 720,
video: true,
screenshotOnRunFailure: true,
retries: {
runMode: 2, // CI retries
openMode: 0, // Local retries
},
env: {
apiUrl: 'http://localhost:3000/api',
},
},
component: {
devServer: {
framework: 'react',
bundler: 'vite',
},
},
});
// cypress/support/commands.ts
Cypress.Commands.add('login', (email: string, password: string) => {
// Programmatic login (faster than UI)
cy.request({
method: 'POST',
url: '/api/auth/login',
body: { email, password },
}).then(({ body }) => {
window.localStorage.setItem('token', body.token);
});
});
// Preserve auth between tests
Cypress.Commands.add('preserveAuth', () => {
cy.getCookie('session').then(cookie => {
if (cookie) {
Cypress.Cookies.preserveOnce('session');
}
});
});
// Usage
beforeEach(() => {
cy.login(Cypress.env('TEST_USER'), Cypress.env('TEST_PASS'));
});
// Intercept and mock
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.intercept('POST', '/api/users', (req) => {
req.reply({
statusCode: 201,
body: { id: '123', ...req.body },
});
}).as('createUser');
// Wait for API calls
cy.wait('@getUsers').its('response.statusCode').should('eq', 200);
// Spy without mocking
cy.intercept('GET', '/api/users').as('getUsers');
cy.wait('@getUsers').then((interception) => {
expect(interception.response.body).to.have.length.greaterThan(0);
});
# GitHub Actions
- name: Cypress run
uses: cypress-io/github-action@v5
with:
build: npm run build
start: npm start
wait-on: 'http://localhost:3000'
record: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
- name: Upload screenshots
uses: actions/upload-artifact@v3
if: failure()
with:
name: cypress-screenshots
path: cypress/screenshots
// Handle slow networks
cy.intercept('/api/**', (req) => {
req.on('response', (res) => {
res.setDelay(1000); // Simulate slow response
});
});
// Handle offline
cy.intercept('/api/**', { forceNetworkError: true });
// Retry failed requests
cy.request({
url: '/api/data',
retryOnStatusCodeFailure: true,
retryOnNetworkFailure: true,
});
| Metric | Target | |--------|--------| | E2E test pass rate | > 99% | | Test execution time | < 15min | | Flaky test rate | < 1% | | Video review on failure | 100% |
// Use data-testid for stable selectors
cy.get('[data-testid="submit-btn"]').click();
// Avoid arbitrary waits
// BAD: cy.wait(5000)
// GOOD: cy.get('[data-testid="result"]').should('be.visible')
// Chain assertions
cy.get('form')
.should('be.visible')
.find('input')
.should('have.length', 3);
// Custom assertions
cy.get('@createUser')
.its('request.body')
.should('deep.include', { name: 'John' });
| Anti-Pattern | Why It's Bad | Solution | |--------------|--------------|----------| | Arbitrary cy.wait(5000) | Slow, unreliable | Use cy.intercept aliases and cy.wait('@alias') | | Testing login UI every test | Extremely slow | Use programmatic login or cy.session | | Selecting by text content | Brittle, breaks on copy changes | Use data-testid or semantic selectors | | Not using cy.intercept | Tests depend on real API | Mock API responses for speed and reliability | | Chaining too many assertions | Hard to debug which failed | Break into separate assertions | | Not cleaning up data | Tests pollute each other | Reset DB state before/after tests | | Using .then() unnecessarily | Breaks Cypress retry logic | Use built-in commands when possible |
| Problem | Likely Cause | Solution | |---------|--------------|----------| | "element is detached from DOM" | Element re-rendered during action | Use cy.get() again, not stored reference | | "Timed out retrying" | Element not found or condition not met | Check selector, increase timeout if needed | | Flaky test | Race condition with API or DOM | Use cy.intercept, wait for specific state | | "CypressError: cy.visit() failed" | Server not running or wrong URL | Verify baseUrl in config, check server | | Test passes locally, fails in CI | Timing differences | Add explicit waits for network requests | | "Cannot read property of undefined" | Async command not properly chained | Ensure commands are chained with .then() |
development
Guidelines for building high-performance APIs with Fastify and TypeScript, covering validation, Prisma integration, and testing best practices
development
FastAPI modern Python web framework. Covers routing, Pydantic models, dependency injection, and async support. Use when building Python APIs. USE WHEN: user mentions "fastapi", "pydantic", "async python api", "python rest api", asks about "dependency injection python", "python openapi", "python swagger", "async endpoints", "python api validation", "fastapi middleware" DO NOT USE FOR: Django apps - use `django` instead, Flask apps - use `flask` instead, synchronous Python APIs without type hints, GraphQL-only APIs
tools
FastAPI integration testing specialist. Covers synchronous TestClient, async httpx AsyncClient, dependency injection overrides, auth testing (JWT, OAuth2, API keys), WebSocket testing, file uploads, background tasks, middleware testing, and HTTP mocking with respx, responses, and pytest-httpserver. USE WHEN: user mentions "FastAPI test", "TestClient", "httpx async test", "dependency override test", "respx mock", asks about testing FastAPI endpoints, authentication in tests, or HTTP client mocking. DO NOT USE FOR: Django - use `pytest-django`; pytest internals - use `pytest`; Container infrastructure - use `testcontainers-python`
development
Expert in FastAPI Python development with best practices for APIs and async operations