Skip to content

E2E Test using Playwright

Full Stack edited this page Apr 25, 2025 · 3 revisions

Here’s a typical project structure for a React project that uses Playwright for end-to-end (E2E) testing. This structure ensures a clean separation of concerns and organizes your code and tests effectively.


Project Structure

my-react-app/
├── public/                     # Static assets (e.g., index.html, images)
├── src/                        # Source code for the React app
│   ├── components/             # Reusable React components
│   │   ├── Header.jsx
│   │   ├── Footer.jsx
│   │   └── ...
│   ├── pages/                  # Page-level components
│   │   ├── Home.jsx
│   │   ├── About.jsx
│   │   └── ...
│   ├── hooks/                  # Custom React hooks
│   │   └── useAuth.js
│   ├── context/                # React Context for global state
│   │   └── AuthContext.js
│   ├── services/               # API calls and external services
│   │   └── api.js
│   ├── styles/                 # Global and component-specific styles
│   │   └── main.css
│   ├── App.jsx                 # Main React component
│   ├── index.js                # Entry point for React
│   └── ...
├── tests/                      # All test-related files
│   ├── e2e/                    # Playwright end-to-end tests
│   │   ├── example.spec.js     # Example Playwright test
│   │   ├── fixtures/           # Playwright fixtures (e.g., test data)
│   │   │   └── userData.js
│   │   ├── pages/              # Page Object Models for Playwright
│   │   │   ├── HomePage.js
│   │   │   ├── LoginPage.js
│   │   │   └── ...
│   │   └── playwright.config.js # Playwright configuration
│   ├── unit/                   # Unit tests (e.g., Jest or React Testing Library)
│   │   ├── components/         # Unit tests for components
│   │   │   └── Header.test.js
│   │   ├── hooks/              # Unit tests for custom hooks
│   │   │   └── useAuth.test.js
│   │   └── ...
│   └── integration/            # Integration tests (optional)
├── .github/                    # GitHub workflows (e.g., CI/CD pipelines)
│   └── workflows/
│       └── playwright.yml      # GitHub Actions for Playwright tests
├── .vscode/                    # VS Code settings and extensions
│   └── settings.json
├── node_modules/               # Installed dependencies
├── .env                        # Environment variables
├── .gitignore                  # Files to ignore in Git
├── package.json                # Project dependencies and scripts
├── package-lock.json           # Lockfile for dependencies
├── README.md                   # Project documentation
└── playwright-report/          # Playwright test reports (auto-generated)

Key Folders and Files

1. **

src

**

  • Contains all the React application code.
  • Organized into components/, pages/, hooks/, context/, and services/ for modularity.

2. tests/e2e/

  • Contains Playwright end-to-end tests.
  • playwright.config.js: Configuration file for Playwright (e.g., browser settings, base URL).
  • pages/: Page Object Models (POM) for Playwright tests to encapsulate page-specific logic.
  • fixtures/: Test data or reusable utilities for Playwright tests.

3. tests/unit/

  • Contains unit tests for React components, hooks, and other logic.
  • Use Jest and React Testing Library for unit testing.

4. playwright-report/

  • Auto-generated folder for Playwright test reports (e.g., HTML reports).

5. .github/workflows/

  • Contains CI/CD pipelines for running Playwright tests in GitHub Actions.

Example Playwright Configuration (playwright.config.js)

// tests/e2e/playwright.config.js
const { defineConfig } = require('@playwright/test');

module.exports = defineConfig({
  testDir: './tests/e2e',
  timeout: 30000,
  retries: 2,
  use: {
    baseURL: 'http://localhost:3000',
    headless: true,
    viewport: { width: 1280, height: 720 },
    actionTimeout: 5000,
    trace: 'on-first-retry',
  },
  reporter: [['html', { outputFolder: 'playwright-report' }]],
});

Example Playwright Test (example.spec.js)

// tests/e2e/example.spec.js
const { test, expect } = require('@playwright/test');

test('homepage has title and links to about page', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/React App/);

  const aboutLink = page.locator('text=About');
  await expect(aboutLink).toBeVisible();
  await aboutLink.click();

  await expect(page).toHaveURL(/about/);
});

Example Page Object Model (HomePage.js)

// tests/e2e/pages/HomePage.js
class HomePage {
  constructor(page) {
    this.page = page;
    this.aboutLink = page.locator('text=About');
  }

  async navigate() {
    await this.page.goto('/');
  }

  async clickAbout() {
    await this.aboutLink.click();
  }
}

module.exports = HomePage;

Example GitHub Actions Workflow (playwright.yml)

# .github/workflows/playwright.yml
name: Playwright Tests

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Install dependencies
        run: npm install

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload Playwright report
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: playwright-report
          path: playwright-report

Scripts in package.json

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "e2e": "npx playwright test",
  "e2e:report": "npx playwright show-report"
}

Benefits of This Structure:

  1. Modularity: Clear separation of React app code and tests.
  2. Scalability: Easy to add more tests, components, or pages.
  3. Maintainability: Organized folder structure for better readability.
  4. CI/CD Ready: GitHub Actions workflow for automated testing.
Clone this wiki locally