sodcalculator

10 Tech How-To

Cross Browser Testing with Playwright: Step-by-Step

Guide 10-38734 · Updated · Step by step

This guide walks you through setting up and running cross-browser tests with Playwright, so you can verify your web app works correctly in Chromium, Firefox, and WebKit from a single test suite. You’ll learn how to configure projects, run tests in parallel, and debug failures across browsers.

What You’ll Need

  • Node.js (version 16 or later) installed on your machine
  • A code editor (VS Code recommended)
  • Basic knowledge of JavaScript or TypeScript
  • An existing web app or a test page to run tests against

Step-by-Step

  1. Install Playwright
    Open your terminal in your project folder and run:
    npm init -y then npm install -D @playwright/test. This installs the test runner and the Playwright library.
  2. Install browsers
    Run npx playwright install. This downloads Chromium, Firefox, and WebKit binaries. You can install only specific browsers with npx playwright install chromium firefox if you want to save disk space.
  3. Create a configuration file
    Playwright uses a config file, usually playwright.config.js or playwright.config.ts. You can generate a starter config with npx playwright init or create it manually.
  4. Define browser projects
    In the config file, add a projects array. Each entry defines a browser and its settings. For example:
    projects: [
      { name: 'chromium', use: { browserName: 'chromium' } },
      { name: 'firefox', use: { browserName: 'firefox' } },
      { name: 'webkit', use: { browserName: 'webkit' } }
    ]
  5. Set base URL and viewport
    In the use block at the top level, set baseURL to your app’s URL and viewport to a typical desktop size (e.g., 1280×720). You can override per project if needed.
  6. Write your first test
    Create a tests folder and add a file like homepage.spec.js. Write a simple test:
    import { test, expect } from '@playwright/test';
    
    test('homepage loads', async ({ page }) => {
      await page.goto('/');
      await expect(page).toHaveTitle(/My App/);
    });
  7. Run tests in all browsers
    Run npx playwright test. Playwright will run the test in each project (browser) sequentially by default. To speed up, add workers: 3 in the config to run in parallel.
  8. Run tests in a single browser
    To debug in one browser only, use npx playwright test --project=chromium. This is useful when a test fails only in one browser.
  9. View the HTML report
    After a run, Playwright generates an HTML report. Run npx playwright show-report to open it. It shows pass/fail status per browser, test duration, and any screenshots or traces.
  10. Take screenshots on failure
    Add screenshot: 'only-on-failure' to the use block in your config. This captures a screenshot automatically when a test fails, helping you spot visual differences.
  11. Record a trace for debugging
    Set trace: 'on-first-retry' in the config. Traces record a full timeline of the test, including network requests and DOM snapshots. You can open them with npx playwright show-trace.
  12. Test responsive layouts
    Add a project for mobile viewport, e.g., { name: 'mobile', use: { browserName: 'chromium', viewport: { width: 375, height: 812 } } }. This allows you to test the same page on a phone-like viewport.
  13. Use environment variables for URLs
    Instead of hardcoding URLs, use process.env.BASE_URL in your config. This lets you run tests against different environments (staging, production) without editing code.
  14. Integrate with CI
    Add a GitHub Actions workflow or similar. Use npx playwright install --with-deps to install browsers and system dependencies. Then run npx playwright test in the CI pipeline.

Common Mistakes

  • Forgetting to install browsers – Running tests without npx playwright install will throw an error about missing executables.
  • Hardcoding viewport sizes – If you don’t set a viewport, Playwright uses a default (1280×720). But you might forget to test mobile sizes, leading to layout issues in production.
  • Using browser-specific APIs without checks – For example, calling page.pdf() only works in Chromium. Guard such calls with a check on browserName.
  • Not using --project when debugging – Running all browsers when you only need to debug one slows down your feedback loop.
  • Ignoring trace files – Traces are extremely helpful but often overlooked. Enable them and actually open them when a test fails.

Tips

  • Start with Chromium only while writing tests, then run all browsers once the tests are stable. This saves time during development.
  • Use test.describe to group tests that are specific to a browser, e.g., test.describe('WebKit only', () => { test.skip(({ browserName }) => browserName !== 'webkit'); ... }).
  • Set retries: 2 in the config to handle flaky tests automatically, especially in CI where network latency varies.
  • Use Playwright’s expect with auto-waiting. Avoid manual waitForTimeout; instead, wait for elements to be visible or enabled.
  • Keep your test data isolated. Use API requests to set up data before tests, rather than relying on UI interactions.
  • Run npx playwright test --headed to watch the test run in a visible browser window. This helps you see exactly what’s happening.

Troubleshooting

Tests fail only in WebKit but not Chromium
This usually indicates a browser-specific behavior, like CSS differences or unsupported JavaScript features. Open the trace for the WebKit run to see the exact failure point. Check the console logs for errors that might be specific to WebKit’s engine.

Browser binaries not found
Run npx playwright install again. If you’re in a CI environment, you may need to run npx playwright install --with-deps to install system libraries.

Tests are slow
Increase the number of workers in the config. Also, avoid using page.waitForTimeout(); instead, use expect(locator).toBeVisible() which waits automatically. Consider using fullyParallel: true for independent tests.

Cannot find the HTML report
The report is saved in playwright-report folder by default. Run npx playwright show-report to open it. If you don’t see the folder, ensure you didn’t set reporter: 'line' which doesn’t generate HTML.

Tests pass locally but fail in CI
Common causes: missing system dependencies, different screen resolution, or network restrictions. In CI, use npx playwright install --with-deps and set a fixed viewport in your config. Also, check if your CI has a headless environment – Playwright runs headless by default, so that’s usually fine.

Frequently Asked Questions

Do I need to install all three browsers?

No, you can install only the ones you need. But to truly test cross-browser compatibility, you should at least test Chromium and Firefox. WebKit is important if your users are on Safari.

Can I test on real mobile devices?

Playwright can emulate mobile viewports and user agents, but it doesn’t run on actual iOS or Android devices. For real device testing, you’d need a cloud service like BrowserStack or Sauce Labs, which integrate with Playwright.

How do I run tests in parallel across browsers?

Set workers: 4 in your config. Playwright will run tests in parallel, but each test file runs in a separate worker. By default, tests within a file run sequentially.

What is the difference between --project and --browser?

--project refers to a named project in your config, which can have its own browser and settings. --browser is a shortcut to run a specific browser (chromium, firefox, webkit) without defining a project.

Can I test on Safari for Windows?

No, Safari is only available on macOS. Playwright’s WebKit build is a close approximation, but it’s not exactly Safari. For accurate Safari testing, you need a macOS machine or a cloud service.

How do I take a screenshot of a specific element?

Use await page.locator('selector').screenshot({ path: 'element.png' }). This captures only that element, which is useful for visual regression testing.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →