e2e-testing

Build reliable, fast, and maintainable end-to-end test suites with Playwright and Cypress.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "e2e-testing" with this command: npx skills add eyadsibai/ltk/eyadsibai-ltk-e2e-testing

E2E Testing Patterns

Build reliable, fast, and maintainable end-to-end test suites with Playwright and Cypress.

What to Test with E2E

Good for:

  • Critical user journeys (login, checkout, signup)

  • Complex interactions (drag-and-drop, multi-step forms)

  • Cross-browser compatibility

  • Real API integration

Not for:

  • Unit-level logic (use unit tests)

  • API contracts (use integration tests)

  • Edge cases (too slow)

Playwright Configuration

// playwright.config.ts export default defineConfig({ testDir: './e2e', timeout: 30000, fullyParallel: true, retries: process.env.CI ? 2 : 0, use: { baseURL: 'http://localhost:3000', trace: 'on-first-retry', screenshot: 'only-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'mobile', use: { ...devices['iPhone 13'] } }, ], });

Page Object Model

export class LoginPage { readonly page: Page; readonly emailInput: Locator; readonly loginButton: Locator;

constructor(page: Page) {
    this.page = page;
    this.emailInput = page.getByLabel('Email');
    this.loginButton = page.getByRole('button', { name: 'Login' });
}

async login(email: string, password: string) {
    await this.emailInput.fill(email);
    await this.page.getByLabel('Password').fill(password);
    await this.loginButton.click();
}

}

Waiting Strategies

// Bad: Fixed timeouts await page.waitForTimeout(3000); // Flaky!

// Good: Wait for conditions await expect(page.getByText('Welcome')).toBeVisible(); await page.waitForURL('/dashboard');

// Wait for API response const responsePromise = page.waitForResponse( r => r.url().includes('/api/users') && r.status() === 200 ); await page.click('button'); await responsePromise;

Network Mocking

test('displays error when API fails', async ({ page }) => { await page.route('**/api/users', route => { route.fulfill({ status: 500, body: JSON.stringify({ error: 'Server Error' }), }); });

await page.goto('/users');
await expect(page.getByText('Failed to load')).toBeVisible();

});

Visual Regression

test('homepage looks correct', async ({ page }) => { await page.goto('/'); await expect(page).toHaveScreenshot('homepage.png', { fullPage: true, maxDiffPixels: 100, }); });

Accessibility Testing

import AxeBuilder from '@axe-core/playwright';

test('no accessibility violations', async ({ page }) => { await page.goto('/'); const results = await new AxeBuilder({ page }).analyze(); expect(results.violations).toEqual([]); });

Best Practices

  • Use Data Attributes: data-testid for stable selectors

  • Test User Behavior: Click, type, see - not implementation

  • Keep Tests Independent: Each test runs in isolation

  • Clean Up Test Data: Create and destroy per test

  • Use Page Objects: Encapsulate page logic

  • Optimize for Speed: Mock when possible, parallel execution

Bad vs Good Selectors

// Bad cy.get('.btn.btn-primary.submit-button').click(); cy.get('div > form > div:nth-child(2) > input').type('text');

// Good cy.getByRole('button', { name: 'Submit' }).click(); cy.get('[data-testid="email-input"]').type('user@example.com');

Debugging

Headed mode

npx playwright test --headed

Debug mode (step through)

npx playwright test --debug

Trace viewer

npx playwright show-trace trace.zip

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

document-processing

No summary provided by upstream source.

Repository SourceNeeds Review
General

stripe-payments

No summary provided by upstream source.

Repository SourceNeeds Review
General

file-organization

No summary provided by upstream source.

Repository SourceNeeds Review