Cross-Browser Testing Tips and Tricks
Build a practical browser and device test matrix, automate key journeys with Playwright, and add accessibility and real-device checks.
Cross-browser testing means verifying that your site’s important tasks remain usable across the browsers, devices, and assistive technologies your audience uses. You do not need to test every possible combination or make every browser render identically. Define a support matrix from audience evidence, automate repeatable journeys across the major browser engines, and reserve hands-on checks for risks that emulation cannot represent.
1. Define what “supported” means
Before choosing browsers, agree on what must work. List the important user tasks: signing in, searching, purchasing, submitting a form, reading content, or whatever defines success for your product. Core tasks and accessible content should remain usable throughout the support range. Less essential visual effects can degrade gracefully on older browsers or constrained devices.
Write down the environments you intend to support: browser and version range, operating system, screen sizes, mobile orientation, and relevant assistive technology. Also state what “works” means for each task. MDN notes that testing every browser and device combination is practically impossible, so a documented and defensible support range is more useful than an unlimited promise. MDN’s introduction to cross-browser testing explains how to approach the problem.
2. Choose which browsers and devices to test
Use your own site analytics, customer research, and product requirements to select the matrix. There is no single browser-share list that applies to every audience, geography, or product. Start with environments that account for actual use, then add cases where the product’s audience or technical risks justify them.
| Dimension | How to choose coverage |
|---|---|
| Browser engines | Cover the engines represented in your support range. Playwright can run Chromium, Firefox, and WebKit projects. |
| Branded browsers | Add Chrome or Edge channels when the exact branded browser behavior is important to validate. |
| Operating systems | Include operating systems used by your audience, especially when fonts, media, input, or platform APIs matter. |
| Mobile and screen sizes | Choose representative phone and tablet profiles from usage data. Include portrait or landscape where the experience requires it. |
| Older versions | Include older browsers if your support policy or audience requires them; document the limit. |
| Assistive technology | Include keyboard-only and screen-reader navigation in the test plan, with relevant platform and versions recorded for defects. |
Keep the initial matrix small enough to run regularly. Expand it when analytics, user feedback, a release risk, or a platform-specific feature supplies a reason. Emulated profiles and responsive viewports are useful for broad coverage, but actual devices or a cloud device lab can be warranted for hardware, browser chrome, media playback, or touch behavior.
3. Automate repeatable journeys with Playwright
Automate the flows that matter most, and run them in each configured browser project in continuous integration. This runnable example uses Chromium, Firefox, and WebKit, plus a simple page title check. Replace the URL and assertion with a route and behavior from your application.
// playwright.config.js
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
use: {
baseURL: 'https://example.com',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
{ name: 'webkit', use: { browserName: 'webkit' } },
],
});
// tests/home.spec.js
import { test, expect } from '@playwright/test';
test('home page has a title and primary navigation', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/example/i);
await expect(page.getByRole('navigation')).toBeVisible();
});
Install Playwright and its browser builds together, then run the test suite:
npm install --save-dev @playwright/test
npx playwright install
npx playwright test
Playwright’s supported browser binaries are tied to its package version. When updating Playwright, install its corresponding browser builds as part of the same maintenance step. A Playwright WebKit run is not the branded Safari application; platform-dependent capabilities such as media codecs can also differ by operating system. Add Chrome or Edge channels if validating their branded behavior matters. See the Playwright browser documentation and test projects documentation.
Emulate devices when it answers the question
Playwright includes device profiles you can apply to a project for viewport, user-agent, and other emulated settings. For example:
// Add to playwright.config.js
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{ name: 'desktop-chromium', use: { browserName: 'chromium' } },
{ name: 'mobile-chromium', use: { ...devices['Pixel 7'], browserName: 'chromium' } },
],
});
Use a profile that matches the cases you want to cover and check the current Playwright device list. Emulation helps check responsive layout and common touch settings, but does not reproduce every real-device condition. Use physical devices or remote device testing when hardware, the operating system, browser chrome, or real media behavior is part of the risk.
4. Combine automated checks with manual review
Automation is most effective for repeatable behavior. During implementation, begin with a couple of stable local browsers, check features as they are built, and then expand to the agreed matrix. Do not leave all compatibility testing until release week.
- Run automated core journeys in the configured browser projects.
- Review layouts at representative viewport sizes, including narrow screens and any required orientation.
- Exercise touch interactions on a real device when gesture or input behavior matters.
- Check platform-dependent features on the relevant operating system and browser.
- Use a remote browser or device service when the required environment is not available locally and the coverage need justifies it.
When evaluating a remote testing service, compare its available browser, OS, and device combinations with your matrix; distinguish emulation from real devices; check whether the same journeys can run repeatedly in CI; and account for setup, maintenance, cost, and access. Supported combinations change, so confirm them in the service’s current documentation. BrowserStack’s browser and platform documentation describes its environment selection controls.
5. Include keyboard and screen-reader checks
Accessibility belongs in the browser test plan. At minimum, navigate key journeys without a mouse and confirm that focus stays visible, understandable, and usable. Then use a screen reader to check that controls and content can be navigated and understood.
- Tab through links, buttons, form fields, menus, and dialogs; confirm a sensible focus order.
- Operate controls with the keyboard and verify that dialogs and menus can be opened and dismissed.
- Check that form labels, instructions, and error messages are conveyed with the relevant controls.
- Use a screen reader to navigate headings, landmarks, links, and interactive controls.
- Record browser, operating system, assistive technology, and versions when reporting an accessibility issue.
For documented accessibility support, identify the relevant browser, platform, and assistive technology versions, along with supported usage and known limitations. See the W3C accessibility guidance for information on documenting evaluation and support.
6. Make failures reproducible
A compatibility defect is much easier to fix when the report identifies the environment and the steps that expose it. Record:
- The URL or route and the steps to reproduce.
- Expected behavior and actual behavior.
- Browser name and version, operating system, and device.
- Viewport size and orientation for layout or mobile issues.
- Assistive technology and version for accessibility findings.
- A screenshot, trace, or short recording when it clarifies the issue.
Keep one report per distinct failure where possible. If a failure appears in one browser only, include the last known working environment and whether it reproduces in a clean session. This gives the team a specific environment to rerun after the fix.
7. Troubleshooting cross-browser test failures
| Symptom | Likely cause | What to do |
|---|---|---|
| Browser executable is missing | The installed Playwright package does not have its matching browser builds installed. | Run npx playwright install after installing or updating Playwright. In CI, include the browser installation in the setup job. |
| Works in Chromium but fails in WebKit or Firefox | A browser-specific behavior, unsupported feature, timing assumption, or test selector issue. | Inspect the failing trace and browser console. Confirm the feature is supported in the target browser and wait for a meaningful condition instead of assuming a fixed load time. |
| WebKit result differs from Safari | Playwright WebKit is not the branded Safari application, and operating-system capabilities can differ. | Test on the relevant Safari and operating-system combination when that exact environment is in scope. |
| Mobile test passes but a device still fails | Emulation does not reproduce all hardware, browser chrome, touch, or OS behavior. | Reproduce on an actual target device or a remote device environment. |
| Layout assertion is flaky | Fonts, images, animation, or network timing have not settled before the assertion. | Wait for the element or state that matters, disable nonessential animation in test setup where appropriate, and capture a trace on failure. |
| Media works on one platform only | Codec or media capability differs by browser and operating system. | Test the supported OS/browser combinations directly and provide a supported fallback where needed. |
| Keyboard users cannot reach a control | The element may not be keyboard-operable, or focus order and focus styling may be incorrect. | Use the keyboard-only pass to find the interaction and focus defect, then verify the corrected journey with keyboard and assistive technology. |
8. Performance, reliability, and cost
Each browser project adds execution time and browser upkeep. Keep the regular CI suite focused on critical journeys, and run broader coverage on a schedule or before higher-risk releases if running every case on every change is too slow. Parallel execution can reduce wall-clock time but uses more compute; balance that against CI capacity and the need for stable, repeatable runs.
Reliability depends on matching browser builds to Playwright, using explicit waits for application states, and capturing traces or screenshots when failures occur. Avoid treating a passing emulated viewport as proof of real-device behavior. The test matrix itself needs maintenance as audience usage, supported browser versions, and platform capabilities change.
Local automation uses your own development and CI resources. Remote testing can supply environments you cannot access locally, but introduces a service cost and configuration to evaluate. Choose it against a concrete coverage need; no universal browser list or fixed service price is established here.
Or skip the browser setup
For screenshots of a page across your review workflow, ScreenshotNeo is a website screenshot API and MCP server. A screenshot can help compare visible output, but it does not replace interactive browser tests, real-device checks, or accessibility testing. The one-call API can return an image or PDF; see the ScreenshotNeo API documentation for options.
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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step 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. Its MCP server provides screenshot, page-info, and PDF tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does cross-browser testing mean every browser must look identical?
No. Prioritize functional and accessible behavior across the agreed support range. Visual differences can be acceptable when they do not prevent important tasks.
Is a responsive viewport test the same as testing a phone?
No. A viewport is useful for layout coverage, but it cannot represent every device, OS, touch, hardware, or browser-chrome condition.
How often should the support matrix change?
Review it when audience data, product requirements, supported browser policies, or platform capabilities change, and document why environments were added or removed.


