ScreenshotNeo

BlogHow-to

How to Test a Website in Multiple Browsers

Build a practical browser test matrix with Playwright, understand what device emulation can and cannot prove, and know when to test on real browsers and devices.

By the ScreenshotNeo team4 October 20269 min read

To test a website in multiple browsers, choose a risk-based matrix, run the same critical user journeys in Chromium, Firefox, and WebKit, and add branded browsers, operating systems, or real devices when your audience or a feature requires them. Playwright can run one test suite across configured browser projects; its device emulation helps cover responsive layouts, but it does not prove behavior on every physical device or branded browser.

This guide shows how to set up that workflow, interpret its limits, record browser-specific defects, and choose when hosted or real-device testing is worth adding.

1. Choose a browser test matrix

Testing every browser version, operating system, and screen size is rarely practical. Start with the combinations most likely to expose defects and most important to your users. A useful test plan records the browser or engine, version, operating system, viewport or device, and whether the run uses emulation or the target environment.

Dimension Starting point Add coverage when
Browser engine Chromium, Firefox, WebKit A defect, audience segment, or browser feature calls for more specific coverage
Branded browser Use the engine projects for broad automated checks You need to validate current Chrome or Edge releases, Safari behavior, codecs, or enterprise policies
Viewport and device Representative desktop and mobile sizes Your analytics or product requirements identify a high-priority screen size, device, or orientation
Operating system The platform assumptions of your local and emulated runs OS integration, fonts, input behavior, or a reported issue makes the platform relevant
Version The browser binaries supported by your installed Playwright version You need current branded releases or a known older version used by customers

Pick critical user journeys before adding more combinations. Depending on the site, these might include loading important pages, navigation, sign-in, forms, search, checkout or booking, and media or interactive controls. This is a practical planning checklist, not a universal required set. A small set of representative journeys across a deliberate matrix is easier to maintain than a large collection of low-value permutations.

Playwright documents Chromium, Firefox, and WebKit browser projects, and can also use branded Chrome and Edge channels when installed. Its Firefox build uses patches and is not the branded Firefox build; its WebKit is based on upstream WebKit and is not branded Safari. Chromium can also differ from official Chrome and Edge binaries, including for codec-related behavior. Use the engine projects for useful automated coverage, then test the branded browser or target platform directly when that difference matters. See the Playwright browser documentation.

2. Set up Playwright projects

The example below runs one test file against desktop Chromium, Firefox, WebKit, and a representative mobile device preset. It uses Playwright Test with JavaScript. The mobile project is emulated and should be treated as responsive and input coverage, not as a physical-device certification.

  1. Install Playwright Test and its browser binaries.
  2. Add a project for each engine or device profile that matters to your matrix.
  3. Write tests around user-visible outcomes and run the configured projects in CI.
npm init playwright@latest
npx playwright install

Create or replace playwright.config.js:

const { defineConfig, devices } = require('@playwright/test');

module.exports = defineConfig({
  testDir: './tests',
  fullyParallel: true,
  reporter: 'list',
  use: {
    baseURL: 'http://127.0.0.1:3000',
    trace: 'retain-on-failure',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium-desktop',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox-desktop',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit-desktop',
      use: { ...devices['Desktop Safari'] },
    },
    {
      name: 'mobile-chromium-emulated',
      use: { ...devices['Pixel 7'] },
    },
  ],
});

Device preset names and their parameters are supplied by the installed Playwright version. If a preset is unavailable in your version, choose one present in devices or define its viewport and device settings explicitly. To run the app before tests, configure webServer in the Playwright config or start the server in your CI job.

Create tests/smoke.spec.js:

const { test, expect } = require('@playwright/test');

test('homepage navigation and contact form work', async ({ page }) => {
  await page.goto('/');

  await expect(page).toHaveTitle(/Example/);
  await page.getByRole('link', { name: 'Contact' }).click();
  await expect(page).toHaveURL(/contact/);

  await page.getByLabel('Email').fill('developer@example.com');
  await page.getByLabel('Message').fill('Browser matrix smoke test');
  await page.getByRole('button', { name: 'Send' }).click();
  await expect(page.getByText('Message sent')).toBeVisible();
});

Replace the title, labels, routes, and success state with elements from your application. Prefer accessible roles and labels so tests reflect how users interact with the page. Run all configured projects with:

npx playwright test

Run a focused browser project while debugging:

npx playwright test --project=webkit-desktop
npx playwright test --project=mobile-chromium-emulated

Playwright runs all configured projects by default. When the suite grows, keep the full matrix for important smoke and regression journeys, and use a smaller quick subset for rapid local feedback if runtime becomes an issue.

3. Add branded browsers and device emulation thoughtfully

When you need current branded Chrome or Edge behavior, install the browser and define a channel project. The channel is a deliberate addition to the engine matrix:

const { defineConfig } = require('@playwright/test');

module.exports = defineConfig({
  projects: [
    {
      name: 'chrome-stable',
      use: { browserName: 'chromium', channel: 'chrome' },
    },
    {
      name: 'edge-stable',
      use: { browserName: 'chromium', channel: 'msedge' },
    },
  ],
});

Install the required branded browser channel as described in the Playwright browser setup guide. Whether a particular channel is available depends on the machine or CI image. Keep browser binaries aligned with the installed Playwright version; after upgrading Playwright, install its matching browsers again.

Playwright emulation can set user agent, screen size, viewport, touch support, locale, timezone, geolocation, permissions, and color scheme. Presets assume particular platform details, so inspect and override parameters when those assumptions do not match your test. For example, define a narrow viewport and dark color scheme:

use: {
  viewport: { width: 390, height: 844 },
  isMobile: true,
  hasTouch: true,
  colorScheme: 'dark',
  locale: 'en-US',
  timezoneId: 'America/New_York',
}

See the Playwright emulation guide for the available emulated parameters. Emulation is useful for responsive layouts and common mobile settings. It does not reproduce every OS integration, physical device characteristic, browser policy, or branded browser behavior. Use an appropriate target environment when the test depends on those details.

4. Inspect failures and keep useful evidence

A failing test is a lead, not yet a diagnosis. For each reproducible difference, record:

  • Browser name or engine and browser version.
  • Operating system, viewport or device, and whether the run was emulated.
  • The test steps and the expected and observed behavior.
  • Relevant console messages and failed network requests.
  • A screenshot or Playwright trace when available.

The configuration above retains traces on failure and captures a screenshot only when a test fails. Open a trace with:

npx playwright show-trace path/to/trace.zip

After a fix, rerun the same steps in the failing environment and the core matrix. This checks both the specific regression and the shared path through the other engines.

5. When local automation is not enough

Local Playwright is a practical starting point when you can install the needed browsers and mainly need repeatable automated checks. A hosted browser service can help when you need combinations or manual access that are inconvenient to maintain locally. BrowserStack documents manual cross-browser testing, browser automation, responsive and visual testing, accessibility offerings, and Playwright automation. Its available browser, OS, device, and version combinations can change, so check its current support matrix before depending on a particular configuration. Its documentation also explains how to configure browsers and devices.

Choose a hosted grid based on the combinations your users need, CI integration, breadth of versions and operating systems, and the effort your team can spend maintaining local environments. It is optional; it does not replace choosing a useful test matrix.

6. Or skip the browser setup

If your immediate goal is a clean visual capture of a page across URLs or viewports, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. It complements browser tests by producing captures; it does not replace assertions that a workflow works in a browser.

For the do-it-yourself workflow above, use Playwright to exercise the site. For a screenshot without installing browser binaries, make one API request. See the ScreenshotNeo API docs for options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners are accepted before capture, and known consent platforms, newsletter popups, and chat widgets are removed; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.

7. Troubleshooting browser test failures

Symptom Likely cause What to do
Browser executable is missing The Playwright package is installed but its matching browser binaries are not. Run npx playwright install; after a Playwright upgrade, install browsers again.
A test passes in Chromium but fails in WebKit or Firefox The page may rely on engine-specific behavior, timing, fonts, or unsupported assumptions. Reproduce in the failing project, inspect the trace and console/network errors, and verify the behavior in the target browser if the distinction matters.
Mobile layout test behaves like desktop The project may set only a narrow viewport, without matching touch or mobile parameters. Use an appropriate device preset or configure viewport, user agent, touch, and mobile parameters intentionally.
Branded channel cannot be launched Chrome or Edge may not be installed or available in the environment. Install the requested channel in the machine or CI image and check the Playwright browser setup documentation.
Test times out on navigation The page may wait on long-lived network activity, a slow dependency, or an incorrect server URL. Confirm the app is reachable and wait for a meaningful page element rather than assuming every request finishes. Investigate slow or failed requests in the trace.
Emulated device passes but a phone fails Emulation does not reproduce all hardware, OS, browser, codec, or policy behavior. Retest on the target device and browser for the feature that depends on those characteristics.
Results change after a dependency update Playwright, its browser binaries, or the app changed between runs. Keep versions controlled in CI, reinstall matching browsers after upgrades, and record the browser version with failure evidence.

8. Performance, reliability, and cost

Each additional project multiplies the browser work for tests that run in every project. Begin with a compact core matrix, reserve extra branded channels or device profiles for relevant risks, and parallelize where your CI capacity allows. Fully parallel runs can shorten elapsed time but use more concurrent resources; tune workers to the runner rather than assuming more is always faster.

Reliability improves when the suite waits for user-visible states, uses stable locators, and captures failure evidence. Avoid treating a single green run as proof of universal compatibility: it covers the configured browser versions, environments, and journeys only. Revisit the matrix when audience data, supported browsers, or product features change.

Local Playwright has no per-capture API fee, but browser installation, CI compute, test maintenance, and any hosted grid are operational costs. For visual snapshots of pages, ScreenshotNeo offers a free allowance and paid tiers listed on its site; its billing rule is that only clean shots are billed, with response headers indicating verdict and billing status. Compare a screenshot capture service with a browser automation grid according to the task: captures are useful for visual output, while interaction and compatibility assertions require browser tests.

FAQ

How do I test my website in different browsers?

Configure Playwright projects for Chromium, Firefox, and WebKit, then run the same critical journeys with npx playwright test. Add branded browsers and target platforms when your requirements call for them.

Can I test multiple browsers automatically?

Yes. Playwright Test runs all configured projects by default, so a shared test suite can run across the engines and device profiles you define.

Does Playwright WebKit prove that my site works in Safari?

No. Playwright WebKit is useful automated coverage, but it is not branded Safari. Validate on an appropriate Apple environment when Safari-specific behavior is important.

Can a screenshot API replace cross-browser tests?

No. A screenshot API captures rendered output. Use browser automation to assert interactions and behavior across browser projects; use captures when you need image or PDF output.