Full Stack Development

End to End Testing (E2E)



by Tomas Trescak t.trescak@westernsydney.edu.au

E2E

/

Introduction

  • E2E vs. unit and integration tests
  • Playwright , Cypress, Selenium, Puppeteer ...
  • Simple Installation: pnpm playwright init
  • Simple configuration

E2E

/

Example

    import { test, expect } from '@playwright/test';

test('Homepage loads', async ({ page }) => {
  await page.goto('/');
  await expect(page.getByText('Welcome to BlogSphere')).toBeVisible();
  await expect(page.getByTestId('post-list')).toBeVisible();
});
  

E2E

/

What to Test

    import { test, expect } from '@playwright/test';

test('Filter posts by tag', async ({ page }) => {
  await page.goto('/tags');
  await page.getByRole('combobox', { name: 'Filter by Tag' })
    .selectOption('Tech');
  const posts = page.getByTestId('post-item');
  await expect(posts).toHaveCount(2);
  await expect(posts.first()).toContainText('Tech');
});

test('Publish a post', async ({ page }) => {
  await page.goto('/admin');
  await page.getByLabel('Post Title').fill('My First Post');
  await page.getByTestId('post-content').fill('Hello, world!');
  await page.getByRole('button', { name: 'Publish' }).click();
  await expect(page.getByText('Post published!')).toBeVisible();
});
  
  • Navigation flows
  • Form submissions
  • Dynamic content / reactivity

E2E

/

Locators

  • getByText : For buttons or links with stable text, like "Publish Post."
  • getByLabel : For form fields tied to labels, ensuring accessibility.
  • getByTestId : For dynamic or non-text elements, like a post editor (add data-testid in your HTML).
  • getByRole : For interactive elements (buttons, links) to test functionality and accessibility.
  • getByPlaceholder : For inputs with clear placeholders.
  • Fallback to locator: Only when no new locator fits (e.g., complex CSS or legacy code).

E2E

/

Locators

    import { test, expect } from '@playwright/test';

test('Delete a post', async ({ page }) => {
  await page.goto('/admin');
  
  // NEW
  await page.getByRole('button', { name: 'Delete Post' }).click();
  await expect(page.getByText("Deleted")).toBeVisible();

  // OLD
  await page.click('button#deletePost');
  await expect(page.locator('.success-message'))
    .toHaveText('Deleted!');
});
  

E2E

/

UI

    import { test, expect } from '@playwright/test';

test('Save admin login', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Username').fill('admin');
  await page.getByLabel('Password').fill('secret123');
  await page.getByRole('button', { name: 'Login' }).click();
  await expect(page.getByText('Admin Dashboard')).toBeVisible();
  await page.context().storageState({ path: 'admin-auth.json' });
});

test.use({ storageState: 'admin-auth.json' });
test('Check admin access', async ({ page }) => {
  await page.goto('/admin');
  await expect(page.getByText('Admin Dashboard')).toBeVisible();
});
  

E2E

/

UI

  • npx playwright test --ui

E2E

/

Visual Studio Code

E2E

/

CI/CD Github Actions

    name: Playwright Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with: { node-version: '18' }
      - run: pnpm install
      - run: pnpx playwright install --with-deps
      - run: pnpx playwright test
  

E2E

/

CI/CD Parallelisation

    name: Parallel Playwright Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3] // Split tests into 3 parts
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with: { node-version: '18' }
      - run: npm install
      - run: npx playwright install --with-deps
      - run: npx playwright test --shard=${{ matrix.shard }}/3
      - uses: actions/upload-artifact@v3
        with:
          name: test-results-shard-${{ matrix.shard }}
          path: playwright-report/
  test-example:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with: { node-version: '18' }
      - run: npm install
      - run: npx playwright install --with-deps
      - run: npx playwright test tests/filter-posts.spec.ts
  

E2E

/

Key Takeways

  • Test user journeys
  • Use new locators
  • Automate and debug
  • Parallelisation
  • Learn from Documentation