ScreenshotNeo

BlogHow-to

How to Test a Local Website in Different Browsers

Run the same meaningful checks across Chromium, Firefox, and WebKit, emulate mobile viewports, and use remote browsers when local coverage is not enough.

By the ScreenshotNeo team4 October 20269 min read

To test a local website in different browsers, start its development server, then run the same important user flows in separate browser projects. Playwright can run Chromium, Firefox, and WebKit locally, and can target branded Google Chrome and Microsoft Edge. Add device emulation for responsive checks. If a remote browser or physical device must reach a private local site, use a hosted testing service with a local tunnel such as BrowserStack Local Testing.

This guide uses Playwright for repeatable local checks. It also explains what browser emulation can and cannot establish, when remote testing helps, and how to capture a page without setting up a browser yourself.

1. Start the local website

Start the development server using the command for your framework. Keep it running while you test, and note the local address it prints, for example http://127.0.0.1:3000. There is no universal start command: it depends on the project.

Check that the page loads in your ordinary browser before adding automation. If it does not, fix the server, port, or application error first. Playwright will not make an unavailable local server reachable.

2. Install Playwright and its browser binaries

For a JavaScript or TypeScript project, install Playwright Test and the browser builds used by the project:

npm init playwright@latest
npx playwright install

The setup command creates a sample configuration and test. Follow its prompts, or add Playwright Test to an existing project. Install the browser binaries after installing or updating Playwright so the framework and browsers are aligned. Playwright documents Chromium, Firefox, and WebKit projects, as well as branded Chrome and Edge channels. A Playwright-downloaded Chromium build alone does not prove that branded Chrome behavior was checked. See the Playwright browser documentation.

3. Configure browser projects

In playwright.config.ts, define the browsers that reflect your support commitments. This example runs the same tests in Chromium, Firefox, and WebKit:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  use: {
    baseURL: 'http://127.0.0.1:3000',
    trace: 'retain-on-failure',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
  },
});

Change command and both URLs to match your app. If you already start the server separately, you can omit webServer. The configuration tells Playwright to start and wait for the server when needed; it does not define how your application itself is launched.

To target installed branded browsers, add projects with channels:

projects: [
  { name: 'chrome', use: { ...devices['Desktop Chrome'], channel: 'chrome' } },
  { name: 'edge', use: { ...devices['Desktop Edge'], channel: 'msedge' } },
]

Use a channel only when that branded browser is installed and available in the environment. Browser and channel availability can vary by operating system. Keep the project names explicit so reports show which target produced a result.

4. Write a meaningful cross-browser test

A useful test performs an action and checks the resulting state. A page-load assertion alone may miss a broken menu, form, or checkout step. Playwright describes its tests as actions followed by assertions against expectations; its locators and actions include waiting for elements to become actionable. See the Playwright test guide.

Create tests/homepage.spec.ts and adapt selectors and expected content to your site:

import { test, expect } from '@playwright/test';

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

  await expect(page).toHaveTitle(/Example/);
  await expect(page.getByRole('navigation')).toBeVisible();

  await page.getByRole('link', { name: 'Sign up' }).click();
  await expect(page).toHaveURL(/signup/);

  await page.getByLabel('Email').fill('developer@example.com');
  await page.getByRole('button', { name: 'Create account' }).click();
  await expect(page.getByText('Check your email')).toBeVisible();
});

Replace the example title, accessible names, route, and confirmation with real values from your application. Prefer role, label, and text locators that reflect how a user identifies controls. If the same action should work in each browser, keep one test and run it across projects rather than maintaining subtly different copies.

Run all configured projects with:

npx playwright test

Run one project or one test file while investigating:

npx playwright test --project=firefox
a
npx playwright test tests/homepage.spec.ts --project=webkit

Remove the stray a line if copying the first command separately; the intended project command is:

npx playwright test --project=firefox

Open the HTML report after a run with:

npx playwright show-report

5. Check responsive layouts with emulation

Browser projects can use device presets or explicit viewport sizes. For example, add a mobile-sized WebKit project:

{
  name: 'mobile-webkit-emulation',
  use: {
    ...devices['iPhone 13'],
  },
}

Or set a viewport directly:

{
  name: 'small-viewport',
  use: {
    browserName: 'chromium',
    viewport: { width: 390, height: 844 },
    isMobile: true,
    hasTouch: true,
  },
}

Choose viewport widths around your own layout breakpoints and test the interactions that matter: navigation expansion, dialogs, form controls, scrolling, and content overflow. Playwright emulation can configure viewport, screen, user agent, touch, and other environment properties. This is an emulation workflow; it does not establish that a physical phone or tablet was tested. See the Playwright emulation documentation.

6. Run the same checks and interpret failures

  1. Pick the browser engines and branded browsers your users or support commitments require.
  2. Run the same important user journeys in each configured project.
  3. Inspect failures, traces, and screenshots to identify whether the cause is browser behavior, an app defect, test data, or a timing problem.
  4. Fix the root cause, then rerun the same flow across the matrix.
  5. Update Playwright and its browser binaries together when refreshing the test environment.

A passing emulated mobile project is useful evidence about configured browser behavior and responsive layout. It is not evidence from every browser version, operating system, or physical device. Define the matrix from your audience and product support needs rather than assuming a small local set covers every combination.

7. Test a local site on remote devices

Local Playwright is often enough for automated coverage. Use remote testing when you need a browser or device unavailable on your machine, interactive inspection, or access to a private site from a hosted browser. BrowserStack documents Local Testing, which uses a tunnel so its cloud browsers and devices can reach localhost or private-network hosts. Its Live offering supports interactive browser and device testing. Review the provider’s current documentation and service terms when setting it up: BrowserStack Local Testing and BrowserStack Live Local Testing.

The general workflow is to start the local server, start the provider’s local tunnel client using its documented setup, and launch the remote session with the tunnel enabled. Then navigate the remote browser to the forwarded local address and exercise the flow. Tunnel commands and supported configurations depend on the provider and account, so use its current instructions rather than copying a guessed command.

For a public deployment or staging environment, remote browsers can visit the reachable URL directly. Do not expose a private development service publicly just to make a remote session work when a documented tunnel is available.

8. Choose the right level of coverage

Need Good starting approach What it tells you
Catch regressions across browser engines Playwright projects for Chromium, Firefox, and WebKit Whether the same automated flows pass in those configured projects
Check branded Chrome or Edge behavior Playwright browser channels Behavior in the installed branded target, subject to its environment
Review responsive behavior quickly Playwright viewport and device emulation Layout and interactions under configured device parameters
Inspect an actual remote device or unavailable browser Hosted browser/device testing with a local tunnel if the site is private Interactive behavior on the remote target selected

Automation makes the same checks repeatable. Manual remote sessions are useful for exploration and visual inspection. Neither approach makes an unspecified browser matrix complete; select versions and devices that match your users.

Or skip the browser setup

If you need a page image rather than an interactive cross-browser test, ScreenshotNeo is a website screenshot API and MCP server. A single GET request captures a URL as an image or PDF. Its screenshot is not a substitute for running browser tests, but it can remove browser installation and capture setup for page previews.

See the ScreenshotNeo API documentation. Example request:

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);

Replace YOUR_API_KEY with your key and change the target URL. The Node.js example uses Bun’s file writer; in Node.js, save the returned bytes with writeFile from node:fs/promises.

  • Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed. Response headers identify the page verdict and billing status.
  • An MCP server provides screenshot tools for AI agents and MCP clients.
  • The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

Performance, reliability, and cost

Running three browser projects takes more time and resources than running one. During development, target the browser or test you are investigating; run the broader matrix in CI or before release according to your project’s needs. Keep the test set focused on user journeys whose regressions matter. Reuse a browser installation in a stable CI image where practical, and keep its Playwright version and browser binaries in sync.

Reliable tests need a running server, stable test data, selectors tied to user-visible semantics, and assertions about expected state. Avoid arbitrary sleeps as a general synchronization strategy: they can make a suite slow and still miss variable load times. Use Playwright’s built-in waiting and actionability behavior, and inspect traces or screenshots when a test is intermittent. A failed remote tunnel or unavailable browser is an environment failure to diagnose separately from an application compatibility defect.

Local Playwright requires maintaining the framework, browser binaries, and test environment. Hosted testing adds a third-party service and its applicable plan or usage costs; the cited documentation does not establish a neutral price comparison. ScreenshotNeo provides a free allowance and paid plans as described above, but screenshot capture answers a different question from interactive compatibility testing.

Troubleshooting

Symptom Likely cause Fix
Navigation to localhost fails The dev server is stopped, using another port, or bound to an address the test cannot reach. Start the server, verify the printed URL in a browser, and align baseURL, webServer.url, and the actual port.
Playwright says a browser executable is missing The browser binaries were not installed for the current Playwright version or environment. Run npx playwright install after installing or updating Playwright.
Chrome or Edge channel cannot launch The branded browser is not installed or available in that environment. Install the required browser where supported, or use the corresponding Playwright browser project and label the target accurately.
A test times out on a click or locator The element is absent, covered, not actionable, or the expected page state never occurs. Check the selector and application state, inspect the trace, and assert the intended visible result. Do not mask a real failure by only increasing the timeout.
A test passes in one engine and fails in another There may be a browser-specific app issue, unsupported assumption, timing defect, or test setup difference. Reproduce the failing project, inspect its trace, and compare the browser-specific behavior before changing application code or test expectations.
Remote browser cannot reach a private local URL The tunnel is not connected, or the session is not configured to use it. Follow the provider’s current Local Testing setup, verify the tunnel is active, and use the address and session options it documents.
Mobile layout looks right in emulation but wrong on a phone Emulation does not establish physical-device behavior; device browser, OS, hardware, or input differences may matter. Reproduce on the relevant remote or physical device when that coverage is required.

FAQ

Can I test a localhost site in remote browsers?

Yes. A hosted service with a local tunnel can connect remote browsers to a private local site. BrowserStack documents this for Local Testing; follow its current setup steps for the browser session you need.

Does Playwright WebKit mean I tested Safari on an iPhone?

No. A WebKit project and device emulation are useful configured targets, but they do not prove testing on a physical iPhone or every Safari version. Use a remote or physical device when that distinction matters.

Should every test run in every browser?

Run critical user flows across the engines and branded browsers your support commitments require. Keep the matrix intentional so it provides useful coverage without duplicating low-value checks.

Can a screenshot API verify that a form works?

No. A screenshot captures page appearance. Use interactive browser automation or a remote browser session to exercise and assert form behavior.