PLAYWRIGHT Tutorial Course

Introduction to Playwright

Overview of Playwright

Playwright is an open-source automation library developed by Microsoft. It provides a high-level API for browser automation, enabling you to perform tasks such as web scraping, testing, and end-to-end automation across multiple browsers including Chromium, Firefox, and WebKit.

Key Features
  • Cross-browser testing: Supports Chromium, Firefox, and WebKit.
  • Headless and headful modes: Allows running tests in the background or with a visible UI.
  • Automated interaction: Provides capabilities to simulate user interactions like clicking, typing, and navigation.
  • Network interception: Enables interception and modification of network requests and responses.
  • Performance metrics: Allows capturing and analyzing performance data such as loading times and resource usage.
  • Device emulation: Supports emulating various devices and screen sizes for responsive design testing.
  • Multi-page and multi-tab support: Handles multiple pages and tabs in a single browser context.

Installation and Getting Started

To install Playwright, you need Node.js installed on your system. Once Node.js is installed, you can use either npm or yarn to install Playwright.
npm install playwright
Once Playwright is installed, you can start writing scripts to automate browser tasks. Below is a simple example to help you get started.
1const { chromium } = require('playwright');
2
3(async () => {
4    // Launch a new browser instance
5    const browser = await chromium.launch();
6    //    const browser = await firefox.launch(); // Launch Firefox
7    // const browser = await webkit.launch(); // Launch Safari
8
9    // Create a new browser context
10    const context = await browser.newContext();
11    
12    // Create a new page in the context
13    const page = await context.newPage();
14    
15    // Navigate to a URL
16    await page.goto('https://example.com');
17    
18    // Take a screenshot of the page
19    await page.screenshot({ path: 'example.png' });
20    
21    // Close the browser
22    await browser.close();
23})();
Run your script using Node.js:
node example.js

Multi-Browser Support

Playwright provides robust support for automating and testing across multiple browsers. This capability allows you to ensure that your web applications perform consistently across different browser environments. Playwright supports the following browsers:
  • Chromium - The open-source project that powers Google Chrome.
  • Firefox - Mozilla's open-source browser.
  • WebKit - The rendering engine used by Safari.

UI Automation with Playwright

Simulating User Actions

Playwright allows you to simulate various user actions to interact with web pages in an automated way. These actions include clicking buttons, typing text into input fields, selecting options, and more. Simulating user actions is crucial for testing and automating web applications to ensure they work as expected.
1const { chromium } = require('playwright');
2
3async function run() {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6    await page.goto('https://example.com');
7    await page.click('#my-button');
8    await page.type('#my-input', 'Hello, Playwright!');
9    await page.selectOption('#my-select', 'option1');
10    await page.hover('#my-hover-target');    
11    await page.dblclick('#my-double-click-target');
12    
13    await page.evaluate(() => {
14        document.querySelector('#my-scroll-target').scrollIntoView();
15    });
16
17
18
19
20    await browser.close();
21}
22
23run().catch(console.error);

Handling forms

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Go to the form page
8    await page.goto('https://example.com/feedback');
9
10    // Fill out the form
11    await page.fill('#name', 'John Doe');
12    await page.fill('#email', '[email protected]');
13    await page.fill('#message', 'This is a feedback message.');
14
15    // Submit the form
16    await page.click('#submit-button');
17
18    // Wait for confirmation
19    await page.waitForSelector('#confirmation-message');
20
21    console.log('Form submitted successfully');
22
23    await browser.close();
24})();

Alerts and Dialogs

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Listen for alerts and handle them
8    page.on('dialog', async dialog => {
9        console.log('Dialog message:', dialog.message());
10        await dialog.accept(); // or dialog.dismiss() to cancel
11    });
12
13    // Navigate to a page that triggers a dialog
14    await page.goto('https://example.com/dialog');
15
16    // Trigger the dialog
17    await page.click('#trigger-dialog-button');
18
19    await browser.close();
20})();

Screenshot and PDF

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Navigate to the page
8    await page.goto('https://example.com');
9
10    // Take a screenshot of the full page
11    await page.screenshot({ path: 'screenshot.png', fullPage: true });
12
13    // Generate a PDF of the page
14    await page.pdf({ path: 'page.pdf', format: 'A4' });
15
16    console.log('Screenshot and PDF generated');
17
18    await browser.close();
19})();

Getting attribute

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Navigate to the page
8    await page.goto('https://example.com');
9
10    // Click a button with a custom selector
11    await page.click('button[data-action="custom"]');
12
13    // Interact with a custom data attribute
14    const value = await page.getAttribute('div[data-role="special"]', 'data-value');
15    console.log('Custom data value:', value);
16
17    await browser.close();
18})();

Scraping Data

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Navigate to the target page
8    await page.goto('https://example.com/products');
9
10    // Extract product names and prices
11    const products = await page.evaluate(() => {
12        return Array.from(document.querySelectorAll('.product')).map(product => ({
13            name: product.querySelector('.product-name').textContent,
14            price: product.querySelector('.product-price').textContent
15        }));
16    });
17
18    console.log('Products:', products);
19
20    await browser.close();
21})();

Network Requests

Intercepting Network Requests

Intercepting network requests in Playwright allows you to monitor, modify, or block requests and responses. This feature is useful for testing scenarios such as simulating different server responses, verifying request details, or handling API interactions.
1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Intercept network requests
8    page.on('route', route => {
9        console.log('Intercepted request:', route.request().url());
10        route.continue(); // Continue with the request as is
11    });
12
13    await page.goto('https://example.com');
14    await browser.close();
15})();

Modifying the request

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Intercept and modify network requests
8    page.on('route', route => {
9        if (route.request().url().includes('example-api')) {
10            route.continue({
11                headers: {
12                    ...route.request().headers(),
13                    'Authorization': 'Bearer modified-token'
14                }
15            });
16        } else {
17            route.continue(); // Continue with the request as is
18        }
19    });
20
21    await page.goto('https://example.com');
22    await browser.close();
23})();

Blocking request

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Block network requests to a specific URL
8    page.on('route', route => {
9        if (route.request().url().includes('example-to-block')) {
10            route.abort(); // Block the request
11        } else {
12            route.continue(); // Continue with the request as is
13        }
14    });
15
16    await page.goto('https://example.com');
17    await browser.close();
18})();

Modifying response

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Intercept and modify network responses
8    page.on('route', async route => {
9        if (route.request().url().includes('example-api')) {
10            const response = await route.fetch(); // Fetch the original response
11            const body = await response.body(); // Get response body
12            const modifiedBody = body.toString().replace('original', 'modified'); // Modify response body
13
14            route.fulfill({
15                status: response.status(),
16                contentType: response.headers()['content-type'],
17                body: modifiedBody
18            });
19        } else {
20            route.continue(); // Continue with the request as is
21        }
22    });
23
24    await page.goto('https://example.com');
25    await browser.close();
26})();

Request and Response Events

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const page = await browser.newPage();
6
7    // Listen to request events
8    page.on('request', request => {
9        console.log('Request:', request.url());
10    });
11
12    // Listen to response events
13    page.on('response', response => {
14        console.log('Response:', response.url(), response.status());
15    });
16
17    await page.goto('https://example.com');
18    await browser.close();
19})();

Cross-Browser Testing

Setting Up Cross-Browser Tests

Install all supported Browsers
npx playwright install
Run tests on all Browsers
1const { chromium, firefox, webkit } = require('playwright');
2
3const runTest = async (browserType) => {
4    const browser = await browserType.launch();
5    const page = await browser.newPage();
6
7    await page.goto('https://example.com');
8    console.log(`Running test on ${browserType.name()}`);
9    await page.screenshot({ path: `screenshot-${browserType.name()}.png` });
10
11    await browser.close();
12};
13
14(async () => {
15    await runTest(chromium);
16    await runTest(firefox);
17    await runTest(webkit);
18})();

Running Tests in Parallel

Install dependency.
npm install @playwright/test
Create a test file.
1const { test, expect } = require('@playwright/test');
2
3test.describe('Cross-Browser Testing', () => {
4    test('should load example.com', async ({ browser }) => {
5        const context = await browser.newContext();
6        const page = await context.newPage();
7        await page.goto('https://example.com');
8        await expect(page).toHaveTitle(/Example Domain/);
9        await page.screenshot({ path: `screenshot-${browser.name()}.png` });
10    });
11});
Configure playwright.
1// playwright.config.js
2// playwright.config.js
3const { defineConfig } = require('@playwright/test');
4
5module.exports = defineConfig({
6    workers: 4,
7
8    projects: [
9        {
10            name: 'chromium',
11            use: {
12                browserName: 'chromium',
13                headless: false, // Run tests in headful mode
14                viewport: { width: 1280, height: 720 },
15            },
16        },
17        {
18            name: 'firefox',
19            use: {
20                browserName: 'firefox',
21                headless: true, // Run tests in headless mode
22                viewport: { width: 1280, height: 720 },
23            },
24        },
25        {
26            name: 'webkit',
27            use: {
28                browserName: 'webkit',
29                headless: true, // Run tests in headless mode
30                viewport: { width: 1280, height: 720 },
31            },
32        },
33    ],
34});
Run test. Since we have specified workers a 4, 4 tests will run in parallel.
npx playwright test

Device Emulation

Mobile Device Emulation

Mobile device emulation in Playwright allows you to simulate various mobile devices and test how your web application behaves on different screen sizes, resolutions, and user agents. Playwright provides built-in support for emulating mobile devices, making it easier to test responsive designs and mobile-specific features.
1const { chromium, devices } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        ...devices['iPhone 12'] // Use the device descriptor for iPhone 12
7    });
8    const page = await context.newPage();
9
10    await page.goto('https://example.com');
11    await page.screenshot({ path: 'iphone12-screenshot.png' });
12
13    console.log('Screenshot taken for iPhone 12.');
14
15    await browser.close();
16})();
Custom device emulation
1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667 }, // Custom viewport size
7        userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
8        deviceScaleFactor: 2, // Custom device scale factor
9        isMobile: true, // Emulate mobile device
10        hasTouch: true // Emulate touch screen
11    });
12    const page = await context.newPage();
13
14    await page.goto('https://example.com');
15    await page.screenshot({ path: 'custom-device-screenshot.png' });
16
17    console.log('Screenshot taken for custom device.');
18
19    await browser.close();
20})();
Testing responsiveness
1const { chromium, devices } = require('playwright');
2
3const viewports = [
4    devices['iPhone 12'],
5    devices['Pixel 5'],
6    { viewport: { width: 768, height: 1024 }, userAgent: 'Mozilla/5.0 (Tablet; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/604.1', isMobile: false, hasTouch: false }
7];
8
9(async () => {
10    const browser = await chromium.launch();
11
12    for (const device of viewports) {
13        const context = await browser.newContext({
14            ...device
15        });
16        const page = await context.newPage();
17
18        await page.goto('https://example.com');
19        await page.screenshot({ path: `screenshot-${device.name || 'custom'}.png` });
20
21        console.log(`Screenshot taken for ${device.name || 'custom device'}.`);
22
23        await context.close();
24    }
25
26    await browser.close();
27})();

Geolocation

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        geolocation: { latitude: 37.7749, longitude: -122.4194 }, // Coordinates for San Francisco
7        permissions: { 'geolocation': true } // Allow geolocation permissions
8    });
9    const page = await context.newPage();
10
11    await page.goto('https://example.com');
12    
13    // Perform actions or assertions related to geolocation
14    // Example: Check if the page displays location-based content
15
16    await page.screenshot({ path: 'geolocation-screenshot.png' });
17    console.log('Screenshot taken with geolocation settings.');
18
19    await browser.close();
20})();

Permissions

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        permissions: {
7            'geolocation': true, // Grant geolocation permission
8            'notifications': true, // Grant notifications permission
9            'camera': true, // Grant camera permission
10            'microphone': true // Grant microphone permission
11        }
12    });
13    const page = await context.newPage();
14
15    await page.goto('https://example.com');
16    
17    // Perform actions or assertions related to permissions
18    // Example: Check if the page requests and handles permissions correctly
19
20    await page.screenshot({ path: 'permissions-screenshot.png' });
21    console.log('Screenshot taken with permissions settings.');
22
23    await browser.close();
24})();

Deny Permission

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        permissions: {
7            'geolocation': false, // Deny geolocation permission
8            'notifications': false, // Deny notifications permission
9            'camera': false, // Deny camera permission
10            'microphone': false // Deny microphone permission
11        }
12    });
13    const page = await context.newPage();
14
15    await page.goto('https://example.com');
16    
17    // Perform actions or assertions related to permissions
18    // Example: Check if the page handles denied permissions correctly
19
20    await page.screenshot({ path: 'denied-permissions-screenshot.png' });
21    console.log('Screenshot taken with denied permissions settings.');
22
23    await browser.close();
24})();

Geolocation and Permissions in Playwright Test

1const { test, expect } = require('@playwright/test');
2
3test('should handle geolocation and permissions', async ({ page }) => {
4    await page.context().grantPermissions(['geolocation'], { origin: 'https://example.com' });
5    await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
6
7    await page.goto('https://example.com');
8
9    // Perform actions or assertions related to geolocation and permissions
10    await expect(page).toHaveTitle('Example Domain');
11    await page.screenshot({ path: 'playwright-test-screenshot.png' });
12});

Touchscreen Events Simulation

Simulating touchscreen events in Playwright allows you to test how your web application responds to touch interactions, such as taps, swipes, and multi-touch gestures. This is especially important for ensuring that your application provides a smooth user experience on mobile devices.

Basic Touchscreen setup

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667 }, // Mobile device dimensions
7        isMobile: true, // Emulate a mobile device
8        hasTouch: true // Enable touch events
9    });
10    const page = await context.newPage();
11
12    await page.goto('https://example.com');
13
14    // Perform touch actions here
15
16    await browser.close();
17})();

Simulating Tap Events

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667 },
7        isMobile: true,
8        hasTouch: true
9    });
10    const page = await context.newPage();
11
12    await page.goto('https://example.com');
13
14    // Simulate a tap on a button with the ID "submit-button"
15    await page.tap('#submit-button');
16
17    await browser.close();
18})();

Swipe gestures

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667 },
7        isMobile: true,
8        hasTouch: true
9    });
10    const page = await context.newPage();
11
12    await page.goto('https://example.com');
13
14    // Simulate a swipe from top to bottom
15    await page.mouse.move(200, 200); // Start position
16    await page.mouse.down();
17    await page.mouse.move(200, 500); // End position
18    await page.mouse.up();
19
20    await browser.close();
21})();

Pinch Zoom

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667, isMobile: true, hasTouch: true }
7    });
8    const page = await context.newPage();
9
10    await page.goto('https://example.com');
11
12    // Simulate pinch-to-zoom by changing the viewport scale
13    await page.setViewportSize({ width: 375, height: 667, deviceScaleFactor: 2 });
14
15    await browser.close();
16})();

Handling Touch Events

1const { chromium } = require('playwright');
2
3(async () => {
4    const browser = await chromium.launch();
5    const context = await browser.newContext({
6        viewport: { width: 375, height: 667 },
7        isMobile: true,
8        hasTouch: true
9    });
10    const page = await context.newPage();
11
12    await page.goto('https://example.com');
13
14    // Listen for touchstart event and log it
15    await page.evaluate(() => {
16        document.addEventListener('touchstart', () => {
17            console.log('Touch event detected');
18        });
19    });
20
21    // Simulate a tap to trigger the touchstart event
22    await page.tap('#touchable-element');
23
24    await browser.close();
25})();

Generating Test Reports

Integrating with Allure

Allure is a popular reporting tool that provides detailed and visually appealing reports for test results. Integrating Allure with Playwright allows you to generate insightful reports for your Playwright test suites.

Install Dependencies
npm install --save-dev @playwright/test allure-playwright
Configure Playwright
1//playwright.config.js
2const config = {
3    reporter: [
4        ['list'], // Default console output
5        ['allure-playwright'], // Add Allure reporter
6    ],
7    use: {
8        trace: 'on-first-retry', // Enable tracing to capture detailed information
9    },
10};
11
12module.exports = config;
Run tests and Generate reports
1npx playwright test
2npx allure generate allure-results --clean -o allure-report
3npx allure open allure-report
Allure results are generated in the allure-results directory by default.

Customizing Allure reports

1const { test } = require('@playwright/test');
2
3test('example test', async ({ page }) => {
4    await page.goto('https://example.com');
5    // Add Allure labels
6    allure.label('severity', 'critical');
7    allure.label('owner', 'team-name');
8});
9
10test('example test with attachment', async ({ page }) => {
11    await page.goto('https://example.com');
12    const screenshot = await page.screenshot();
13    allure.attachment('screenshot', screenshot, 'image/png');
14});

Recording Videos of Test Runs

1const { devices } = require('@playwright/test');
2
3const config = {
4    use: {
5        video: 'on', // Enable video recording for all tests
6        trace: 'on-first-retry', // Optional: Enable tracing
7        //video: "retain-on-failure" //record only on failure
8    },
9    projects: [
10        {
11            name: 'chromium',
12            use: { ...devices['Desktop Chrome'] },
13        },
14        {
15            name: 'firefox',
16            use: { ...devices['Desktop Firefox'] },
17        },
18        {
19            name: 'webkit',
20            use: { ...devices['Desktop Safari'] },
21        },
22    ],
23};
24
25module.exports = config;

Playwright CLI

Basic CLI Commands

1npx playwright test
2npx playwright test tests/example.spec.js
3npx playwright test --project=chromium
4npx playwright test --grep @my-tag
5npx playwright codegen
6npx playwright codegen https://example.com
7npx playwright codegen --browser=firefox https://example.com
8npx playwright install
9npx playwright install firefox
10npx playwright install --list
11npx playwright open
12npx playwright open https://example.com
13npx playwright open --browser=webkit https://example.com
14npx playwright show-trace trace.zip
15npx playwright show-trace path/to/trace.zip
16npm install @playwright/test@latest
17npm init playwright@latest
18npx playwright serve path/to/static/files
19npx playwright serve path/to/static/files --port=8080
20npx playwright show-report
21npx playwright show-report --output=my-report-dir

Debugging with Playwright CLI

Playwright provides a debug mode that helps you pause the test execution and inspect the current state of the browser.
1npx playwright test --debug
2npx playwright test --headed
You can also pause the test at specific point.
1const { test } = require('@playwright/test');
2
3test('my test', async ({ page }) => {
4    await page.goto('https://example.com');
5    await page.pause(); // Pauses execution here
6    await page.click('text=More information...');
7});
You can also start tracing in script.
1const { test } = require('@playwright/test');
2
3test('My Test with Tracing', async ({ page, browser }) => {
4  // Start tracing before navigating to the page
5  await browser.startTracing(page, { screenshots: true, snapshots: true });
6
7  await page.goto('https://example.com');
8  await page.click('text=More information...');
9
10  // Stop tracing and save it to a file
11  await browser.stopTracing({ path: 'trace.json' });
12});
Using config file
1module.exports = {
2    use: {
3        headless: false, // Run tests in headed mode by default
4        trace: 'on', // Enable tracing
5        //        trace: 'on-first-retry', // Enable trace only if test fails on the first retry
6
7    },
8    reporter: 'list',
9    debug: true, // Enable debugging mode
10};

Running Scripts with trace

1npx playwright show-trace trace.zip
2
3//run in slow motion
4npx playwright test --slow-mo=1000
5
6DEBUG=pw:api npx playwright test

Continuous Integration (CI)

Setting up Playwright in a Continuous Integration (CI) environment is essential for automating your testing process and ensuring that your web application works as expected across different browsers and platforms. Playwright is compatible with many CI services such as GitHub Actions, GitLab CI, Jenkins, Travis CI, and more. The general steps to set up Playwright in CI are similar across these platforms.

Using GitHub Actions

1name: Playwright Tests
2
3on:
4  push:
5    branches:
6      - main
7  pull_request:
8    branches:
9      - main
10
11jobs:
12  test:
13    runs-on: ubuntu-latest
14
15    steps:
16      - name: Checkout code
17        uses: actions/checkout@v2
18
19      - name: Set up Node.js
20        uses: actions/setup-node@v2
21        with:
22          node-version: '16'
23
24      - name: Install dependencies
25        run: npm install
26
27      - name: Install Playwright Browsers
28        run: npx playwright install --with-deps
29
30      - name: Run Playwright tests
31        run: npx playwright test

gitlab CI

1stages:
2  - test
3
4test-playwright:
5  image: mcr.microsoft.com/playwright:focal
6  stage: test
7  script:
8    - npm install
9    - npx playwright install --with-deps
10    - npx playwright test

Accessibility Testing

Running Accessibility Checks

To perform accessibility checks with Playwright, you can use libraries such as axe-core or @playwright/a11y. The most common approach is to use axe-core, a popular accessibility testing engine.
npm install axe-core playwright-axe
1const { injectAxe, checkA11y } = require('playwright-axe');
2
3const runAccessibilityChecks = async (page) => {
4  // Inject the axe-core script into the page
5  await injectAxe(page);
6  
7  // Run the accessibility checks
8  await checkA11y(page, null, {
9    detailedReport: true,
10    detailedReportOptions: {
11      html: true,
12    },
13  });
14};
15
16module.exports = runAccessibilityChecks;
Next, you can create a utility function to run axe-core in your Playwright tests.

Accessibility Utility

1const { injectAxe, checkA11y } = require('playwright-axe');
2
3const runAccessibilityChecks = async (page) => {
4  // Inject the axe-core script into the page
5  await injectAxe(page);
6  
7  // Run the accessibility checks
8  await checkA11y(page, null, {
9    detailedReport: true,
10    detailedReportOptions: {
11      html: true,
12    },
13  });
14};
15
16module.exports = runAccessibilityChecks;

Accessibility Test

1const { test, expect } = require('@playwright/test');
2const runAccessibilityChecks = require('./accessibility-utils');
3
4test('should pass accessibility checks', async ({ page }) => {
5  await page.goto('https://example.com');
6
7  // Run accessibility checks
8  await runAccessibilityChecks(page);
9
10  // Additional test assertions can go here
11  const title = await page.title();
12  expect(title).toBe('Example Domain');
13});

Generating Accessibility Reports

1const fs = require('fs');
2const { injectAxe, checkA11y } = require('playwright-axe');
3
4const runAccessibilityChecks = async (page) => {
5  await injectAxe(page);
6  
7  const results = await checkA11y(page, null, {
8    detailedReport: true,
9    detailedReportOptions: {
10      html: true,
11    },
12  });
13
14  fs.writeFileSync('accessibility-report.html', results.html);
15};
16
17module.exports = runAccessibilityChecks;

Collecting Performance Metrics

page.metrics API

1const { test } = require('@playwright/test');
2
3test('Collect performance metrics', async ({ page }) => {
4  await page.goto('https://example.com');
5
6  // Collect metrics after page load
7  const metrics = await page.metrics();
8  
9  console.log(metrics);
10});

Performance API

1const { test } = require('@playwright/test');
2
3test('Collect navigation timing', async ({ page }) => {
4  await page.goto('https://example.com');
5
6  // Evaluate performance timing in the browser context
7  const timing = await page.evaluate(() => JSON.stringify(window.performance.timing));
8  
9  console.log(JSON.parse(timing));
10});

Page Evaluate

1const { test } = require('@playwright/test');
2
3test('Collect custom performance metrics', async ({ page }) => {
4  await page.goto('https://example.com');
5
6  // Collect first paint time
7  const firstPaint = await page.evaluate(() => {
8    const [entry] = performance.getEntriesByType('paint');
9    return entry.startTime;
10  });
11
12  console.log(`First paint occurred at: ${firstPaint} ms`);
13});

Monitoring network requests

1const { test } = require('@playwright/test');
2
3test('Monitor network request timings', async ({ page }) => {
4  await page.route('**/*', route => {
5    route.continue();
6  });
7
8  page.on('requestfinished', async (request) => {
9    const response = await request.response();
10    const timing = await response.timing();
11    
12    console.log(`Request to ${request.url()} took ${timing.responseStart - timing.startTime} ms`);
13  });
14
15  await page.goto('https://example.com');
16});

Load Testing with Playwright

Built in Load testing

1const { chromium } = require('playwright');
2
3async function runTest() {
4  const browser = await chromium.launch();
5  const page = await browser.newPage();
6  await page.goto('https://example.com');
7
8  // Simulate user actions
9  await page.click('text=Some Button');
10  await page.fill('#input-field', 'Some Input');
11  await page.click('text=Submit');
12
13  await browser.close();
14}
15
16async function loadTest(concurrentUsers) {
17  const promises = [];
18  for (let i = 0; i < concurrentUsers; i++) {
19    promises.push(runTest());
20  }
21  await Promise.all(promises);
22  console.log(`${concurrentUsers} users tested`);
23}
24
25loadTest(100); // Simulate 100 users

Using Artillery

For more sophisticated load testing, you can integrate Playwright with dedicated load testing tools like Artillery, k6, or Gatling. These tools can manage high concurrency, generate reports, and provide more detailed insights.
npm install -g artillery
Artillery Config
1config:
2  target: 'https://example.com'
3  phases:
4    - duration: 60
5      arrivalRate: 10
6      rampTo: 50
7      name: "Ramp up the load"
8
9scenarios:
10  - flow:
11    - get:
12        url: "/"
13    - post:
14        url: "/api/login"
15        json:
16          username: "testuser"
17          password: "password"
Run test
artillery run artillery-config.yaml