playwright-lighthouse

repository·master·Indexed 43 days ago

https://github.com/abhinaba-ghosh/playwright-lighthouse

A utility for running Google Lighthouse audits programmatically within Playwright automation scripts. It enables integration of performance, accessibility, and SEO auditing into end-to-end testing workflows, supporting custom score thresholds, report generation in CSV, HTML, and JSON formats, and execution on platforms like LambdaTest.

Tokens
5.2K
Snippets
13
Records
14
Agent score
52%

What's inside playwright-lighthouse

  1. Run Lighthouse on authenticated routes

    master

    Lighthouse opens a new page for its audit, which means it does not automatically share the authentication state (cookies/localStorage) of your current Playwright page.

    To audit authenticated routes, you must use a persistent context (launchPersistentContext). This ensures that when Lighthouse opens a new page, the storage/session is persisted and available.

    import os from 'os';
    import path from 'path';
    import { playAudit } from 'playwright-lighthouse';
    import { chromium } from 'playwright';
    
    describe('audit example', () => {
      it('open browser', async () => {
        const userDataDir = path.join(os.tmpdir(), 'pw', String(Math.random()));
        const context = await chromium.launchPersistentContext(userDataDir, {
          args: ['--remote-debugging-port=9222'],
        });
        const page = await context.newPage();
        await page.goto('http://localhost:3000/');
    
        // Perform login steps here which will save to cookie or localStorage
    
        await playAudit({
          page: page,
          port: 9222,
        });
    
        await context.close();
      });
    });
  2. Run Lighthouse reports on LambdaTest

    master

    You can execute Lighthouse audits on the LambdaTest platform while running Playwright tests. This allows you to generate multiple reports within a single test execution on their infrastructure.

    Prerequisites

    1. Install the library:
      npm install playwright-lighthouse
    2. Set the LIGHTHOUSE_LAMBDATEST environment variable to true in your project environment:
      export LIGHTHOUSE_LAMBDATEST='true'

    Implementation Pattern

    Connect to LambdaTest using chromium.connect with the appropriate capabilities, perform your browser actions, and then call playAudit. You can use page.evaluate to communicate the test status (passed/failed) back to the LambdaTest dashboard based on whether playAudit meets your defined thresholds.

    import { chromium } from 'playwright';
    import { playAudit } from 'playwright-lighthouse';
    
    (async () => {
      let browser, page;
      try {
        const capabilities = {
          browserName: 'Chrome', // Browsers allowed: `Chrome`, `MicrosoftEdge` and `pw-chromium`
          browserVersion: 'latest',
          'LT:Options': {
            platform: 'Windows 11',
            build: 'Web Performance testing',
            name: 'Lighthouse test',
            user: process.env.LT_USERNAME,
            accessKey: process.env.LT_ACCESS_KEY,
            network: true,
            video: true,
            console: true,
          },
        };
    
        browser = await chromium.connect({
          wsEndpoint: `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent(JSON.stringify(capabilities))}`,
        });
    
        page = await browser.newPage();
    
        await page.goto('https://duckduckgo.com');
        // ... perform actions ...
    
        try {
          await playAudit({
            url: 'https://duckduckgo.com',
            page: page,
            thresholds: {
              performance: 50,
              accessibility: 50,
              'best-practices': 50,
              seo: 50,
              pwa: 10,
            },
            reports: {
              formats: {
                json: true,
                html: true,
                csv: true,
              },
            },
          });
    
          await page.evaluate(
            (_) => {},
            `lambdatest_action: ${JSON.stringify({ action: 'setTestStatus', arguments: { status: 'passed', remark: 'Web performance metrics are are above the thresholds.' } })}`
          );
        } catch (e) {
          await page.evaluate(
            (_) => {},
            `lambdatest_action: ${JSON.stringify({ action: 'setTestStatus', arguments: { status: 'failed', remark: e.stack } })}`
          );
          console.error(e);
        }
      } catch (e) {
        await page.evaluate(
          (_) => {},
          `lambdatest_action: ${JSON.stringify({ action: 'setTestStatus', arguments: { status: 'failed', remark: e.stack } })}`
        );
      } finally {
        await page.close();
        await browser.close();
      }
    })();
  3. Integrate with Playwright Test Runner

    master

    To use playwright-lighthouse with the Playwright Test Runner (especially for parallel execution), you should extend the test base with a custom fixture that assigns a unique port to each worker using get-port.

    For authenticated routes in the test runner, use launchPersistentContext within a fixture to ensure the Lighthouse audit can access the session.

    import { chromium } from 'playwright';
    import type { Browser } from 'playwright';
    import { playAudit } from 'playwright-lighthouse';
    import { test as base } from '@playwright/test';
    import getPort from 'get-port';
    
    export const lighthouseTest = base.extend<{}, { port: number; browser: Browser }>({
      port: [
        async ({}, use) => {
          const port = await getPort();
          await use(port);
        },
        { scope: 'worker' },
      ],
    
      browser: [
        async ({ port }, use) => {
          const browser = await chromium.launch({
            args: [`--remote-debugging-port=${port}`],
          });
          await use(browser);
        },
        { scope: 'worker' },
      ],
    });
    
    lighthouseTest.describe('Lighthouse', () => {
      lighthouseTest('should pass lighthouse tests', async ({ page, port }) => {
        await page.goto('http://example.com');
        await page.waitForSelector('#some-element');
        await playAudit({
          page,
          port,
        });
      });
    });
  4. Run Lighthouse audits on LambdaTest

    master

    If the environment variable LIGHTHOUSE_LAMBDATEST is set to 'true', the lighthouse() function will execute the audit using LambdaTest's specialized lighthouseReport action instead of running it locally via the Lighthouse library.

    This is triggered by evaluating a specific command on the Playwright page to communicate with the LambdaTest infrastructure.

  5. Generate Lighthouse audit reports in CSV, HTML, or JSON

    master

    The playAudit function can generate Lighthouse reports in multiple formats (CSV, HTML, and JSON) which are useful for CI/CD monitoring. You can configure the output formats, the report name, and the destination directory using the reports configuration object.

    By default, formats are all set to false. The name defaults to lighthouse-${new Date().getTime()} and the directory defaults to ${process.cwd()}/lighthouse.

    await playAudit({
      /* ... other configurations */
    
      reports: {
        formats: {
          json: true, //defaults to false
          html: true, //defaults to false
          csv: true, //defaults to false
        },
        name: `name-of-the-report`, //defaults to `lighthouse-${new Date().getTime()}`
        directory: `path/to/directory`, //defaults to `${process.cwd()}/lighthouse`
      },
    });
  6. Set performance thresholds for audits

    master

    By default, playAudit will fail the test if any Lighthouse metric score is below 100. You can customize these thresholds by passing a thresholds object.

    Available metric keys include:

    • performance
    • accessibility
    • best-practices
    • seo
    • pwa

    If a score falls below the value specified in the thresholds object, the test will fail.

    import { playAudit } from 'playwright-lighthouse';
    import playwright from 'playwright';
    
    describe('audit example', () => {
      it('open browser', async () => {
        const browser = await playwright['chromium'].launch({
          args: ['--remote-debugging-port=9222'],
        });
        const page = await browser.newPage();
        await page.goto('https://angular.io/');
    
        await playAudit({
          page: page,
          thresholds: {
            performance: 50,
            accessibility: 50,
            'best-practices': 50,
            seo: 50,
            pwa: 50,
          },
          port: 9222,
        });
    
        await browser.close();
      });
    });
  7. Use playAudit to audit a page

    master

    The core function playAudit allows you to run a Lighthouse audit on a Playwright page.

    Important Requirements:

    1. You must launch the browser with a --remote-debugging-port argument.
    2. You must provide the same port number to the playAudit function.
    import { playAudit } from 'playwright-lighthouse';
    import playwright from 'playwright';
    
    describe('audit example', () => {
      it('open browser', async () => {
        const browser = await playwright['chromium'].launch({
          args: ['--remote-debugging-port=9222'],
        });
        const page = await browser.newPage();
        await page.goto('https://angular.io/');
    
        await playAudit({
          page: page,
          port: 9222,
        });
    
        await browser.close();
      });
    });
  8. Retrieve the Lighthouse JSON result object

    master

    The playAudit function returns a Promise that resolves with the Lighthouse result object. This object contains the LHR (Lighthouse Report in JSON format), allowing you to programmatically inspect the audit results.

    const lighthouseReport = await playAudit({
      /* ... configurations */
    }); // lightHouse report contains the report results
  9. Pass custom Lighthouse options and configurations

    master

    You can pass arguments directly to the underlying Lighthouse module using the opts and config properties in the playAudit options object.

    • opts: Lighthouse options (e.g., { disableStorageReset: false }).
    • config: Lighthouse configuration objects (e.g., imported desktop configs).
    • thresholds: Custom metric thresholds.
    import lighthouseDesktopConfig from 'lighthouse/lighthouse-core/config/lr-desktop-config';
    
    await playAudit({
      thresholds: thresholdsConfig,
      opts: lighthouseOptions,
      config: lighthouseDesktopConfig,
    });
  10. Configure report generation

    master

    The reports object in the lighthouse() function controls how and where audit reports are saved. The function supports html, json, and csv formats.

    Report Configuration Object

    KeyTypeDescription
    formatsObjectAn object mapping format names to booleans. Set to true to enable that format (e.g., { html: true, json: true }).
    directorystringThe directory where reports will be saved. The directory is created recursively if it does not exist.
    namestringThe base filename for the reports (without the extension).

    Supported formats: html, json, csv.

    reports: {
      formats: {
        html: true,
        json: true,
        csv: false
      },
      directory: './audit-results',
      name: 'homepage-audit'
    }
  11. Run Lighthouse audits via the lighthouse() function

    master

    The lighthouse() function is the primary entrypoint for running Lighthouse audits within a Playwright environment. It executes the audit on a provided page and url, compares the resulting scores against defined thresholds, and can generate various report formats.

    Parameters

    ParameterTypeDescription
    pagePageThe Playwright page instance to run the audit on.
    urlstringThe URL to audit.
    thresholdsObjectAn object where keys are Lighthouse category names (e.g., performance) and values are the minimum acceptable scores (0-100). If opts.onlyCategories is not provided, the function will only run audits for the categories listed in thresholds.
    optsObjectOptions passed directly to the underlying Lighthouse library. Note that opts.port is automatically set to the value of cdpPort.
    configObjectThe Lighthouse configuration object.
    reportsObjectConfiguration for report generation. See Configure report generation for details.
    cdpPortnumberThe Chrome DevTools Protocol port.

    Return Value

    Returns a Promise that resolves to an object containing:

    • comparison: An object with errors (thresholds not met) and results (thresholds met).
    • results: The full Lighthouse Result object (lhr).
    import { lighthouse } from 'playwright-lighthouse';
    
    const results = await lighthouse({
      page, // Playwright Page instance
      url: 'https://example.com',
      thresholds: {
        performance: 90,
        accessibility: 90,
        best-practices: 90,
        seo: 90,
        pwa: 90
      },
      reports: {
        formats: { html: true, json: true },
        directory: './reports',
        name: 'my-audit'
      }
    });