E2E Test using Playwright - FullstackCodingGuy/Developer-Fundamentals GitHub Wiki
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.
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)
- Contains all the React application code.
- Organized into
components/
,pages/
,hooks/
,context/
, andservices/
for modularity.
- 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.
- Contains unit tests for React components, hooks, and other logic.
- Use Jest and React Testing Library for unit testing.
- Auto-generated folder for Playwright test reports (e.g., HTML reports).
- Contains CI/CD pipelines for running Playwright tests in GitHub Actions.
// 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' }]],
});
// 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/);
});
// 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;
# .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": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"e2e": "npx playwright test",
"e2e:report": "npx playwright show-report"
}
- Modularity: Clear separation of React app code and tests.
- Scalability: Easy to add more tests, components, or pages.
- Maintainability: Organized folder structure for better readability.
- CI/CD Ready: GitHub Actions workflow for automated testing.
read
To debug your Playwright test, you can use the following approaches:
Playwright provides a built-in debug mode that pauses the test execution and opens the browser for inspection.
npx playwright test --debug
- The browser will open in non-headless mode.
- You can step through the test interactively.
- Playwright Inspector will appear, allowing you to inspect elements, view logs, and replay actions.
Focus on a single test by adding .only
to the test you want to debug.
test.only('should allow selecting a fund manager', async () => {
// Select a fund manager
await fundManagerSelector.selectFundManager('Fund Manager 1'); // Replace with actual value
// Verify the selection
// await fundManagerSelector.verifySelectedFundManager('Fund Manager 1');
});
npx playwright test
This will run only the specified test.
Insert page.pause()
in your test to pause execution and open the Playwright Inspector.
test('should allow selecting a fund manager', async ({ page }) => {
await page.pause(); // Pauses the test and opens the inspector
// Select a fund manager
await fundManagerSelector.selectFundManager('Fund Manager 1'); // Replace with actual value
// Verify the selection
// await fundManagerSelector.verifySelectedFundManager('Fund Manager 1');
});
npx playwright test
By default, Playwright runs tests in headless mode. You can disable headless mode to see the browser actions.
npx playwright test --headed
Add console.log
statements in your test or Page Object Model to log values and actions.
test('should allow selecting a fund manager', async () => {
console.log('Starting test: should allow selecting a fund manager');
// Select a fund manager
await fundManagerSelector.selectFundManager('Fund Manager 1');
console.log('Selected Fund Manager 1');
// Verify the selection
// await fundManagerSelector.verifySelectedFundManager('Fund Manager 1');
console.log('Verified selection');
});
Enable tracing to capture detailed logs, screenshots, and videos of the test execution.
npx playwright test --trace on
- Open the trace viewer:
npx playwright show-trace trace.zip
If the test fails, Playwright will display the error stack trace in the terminal. Use this information to identify the issue.
Ensure the FundManagerSelectorPage
class is correctly implemented and imported. If the FundManagerSelectorPage
is not working as expected, debug it separately.
const FundManagerSelectorPage = require('./FundManagerSelectorPage');
console.log(FundManagerSelectorPage); // Verify the import
If you want to debug only the
FundManagerSelector.spec.js
file, run it directly:
npx playwright test tests/e2e/tests/FundManagerSelector.spec.js
If you're using Visual Studio Code, you can debug Playwright tests with breakpoints.
- Open the
FundManagerSelector.spec.js
file in VS Code.
2. Add breakpoints by clicking on the left margin of the editor.
3. Create a launch.json
file for Playwright debugging:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Playwright Tests",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/@playwright/test/lib/cli.js",
"args": ["test", "--project=chromium"],
"cwd": "${workspaceFolder}",
"env": {
"PWDEBUG": "1"
}
}
]
}
- Start debugging by pressing
F5
.
- Add
page.pause()
inside the test to inspect the browser. - Run the test in debug mode:
npx playwright test --debug
- Add
console.log
statements to verify the flow of the test. - Ensure the
FundManagerSelectorPage
is correctly implemented and imported.