End-to-End Testing

Click the Real Buttons in a Real Browser

End-to-End Testing

Angular's old Protractor is gone — modern projects use Cypress or Playwright. Both have first-party schematics that drop straight into an Angular workspace.

4 min read Level 2/5 #angular#testing#e2e
What you'll learn
  • Install @cypress/schematic or @playwright/test
  • Run e2e in CI against a built app
  • Stub network calls in e2e for stable tests

End-to-end tests boot your app in a real browser and drive it like a user would — useful for smoke tests, critical flows, and regression coverage that unit tests can’t reach.

Pick a Runner

# Cypress
ng add @cypress/schematic

# Playwright
npm install -D @playwright/test
npx playwright install

Both add scripts and config. Run them with ng e2e (Cypress integrates with the Angular builder) or npx playwright test directly.

A Cypress Test

describe('Login', () => {
  it('logs in', () => {
    cy.visit('/login');
    cy.get('input[type=email]').type('ada@example.com');
    cy.get('input[type=password]').type('secret');
    cy.contains('Sign in').click();
    cy.url().should('include', '/dashboard');
  });
});

A Playwright test looks similar — await page.goto(), await page.getByLabel().fill(), await expect(page).toHaveURL(...).

Stub the Network

Real APIs are flaky. Intercept them so tests are deterministic.

// Cypress
cy.intercept('GET', '/api/users', { fixture: 'users.json' });

// Playwright
await page.route('/api/users', r => r.fulfill({ path: 'fixtures/users.json' }));

Wire It Into CI

In GitHub Actions: build the app once, serve the dist/ output, then run the e2e command against it. Avoid running ng serve in CI — it rebuilds on every change, which is slower and less representative of production.

Server-Side Rendering →