Recommended Free Tools
Use the connection method that matches the remote endpoint’s protocol. A Playwright WebSocket created with launchServer() connects through browserType.connect(). An existing Chromium browser exposing Chrome DevTools Protocol (CDP) connects through chromium.connectOverCDP(). In Playwright Test, put the remote WebSocket URL in use.connectOptions.wsEndpoint.
The distinction matters: native Playwright connections provide the best feature fidelity but require matching Playwright major and minor versions. CDP works only with Chromium and Playwright describes it as “significantly lower fidelity” than its native protocol connection (Playwright BrowserType API).
Choose the protocol before writing code
A service’s WebSocket URL does not, by itself, tell you which Playwright API to call. Read the provider’s endpoint documentation and identify whether it exposes the Playwright protocol or CDP.
| Remote endpoint | Use | Important trade-off |
|---|---|---|
Playwright protocol from launchServer() |
browserType.connect(endpoint) |
Client and server must use matching Playwright major and minor versions. |
| Chromium CDP HTTP or WebSocket endpoint | chromium.connectOverCDP(endpointURL) |
Chromium only and lower Playwright feature fidelity. |
Use the native protocol when you need Firefox or WebKit, Playwright-specific behavior, request routing, or the most complete API surface. Use CDP when an existing Chromium instance or managed service documents CDP and your test does not depend on features unavailable through that connection.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Connect to a Playwright browser server
Start the browser server on the machine that owns the browser, then give its WebSocket endpoint to the client process. This example starts and connects locally; in a deployment, run the server on the remote host and expose it only across a protected network.
const { chromium } = require('playwright');
const browserServer = await chromium.launchServer();
const wsEndpoint = browserServer.wsEndpoint();
const browser = await chromium.connect(wsEndpoint);
try {
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
} finally {
await browser.close();
await browserServer.close();
}
Run the server and client separately
In a real remote setup, the browser host creates the server and publishes the endpoint returned by wsEndpoint() to an authorized client. The connecting project must use the same Playwright major and minor version as the server. Playwright’s compatibility example treats version 1.2.3 as compatible with the 1.2.x line; do not assume compatibility across different minor versions.
The server listens on localhost by default. Binding it to a network address makes the browser RPC reachable to systems that can access that listener. Restrict the firewall and private network route, and use a hard-to-guess WebSocket path. Playwright warns that anyone who knows the configured wsPath can control the operating-system user running the browser (BrowserType API security notes).
Keep the browser lifecycle on the correct side
A client that connects to an already-running server should close its browser connection when finished. Whether that action terminates the underlying browser depends on how the remote service manages it. If your process owns launchServer(), close both the browser connection and the server as shown above. A managed provider normally owns the server lifecycle, so follow its shutdown semantics instead of trying to launch a second browser.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsConnect to an existing Chromium browser over CDP
For a browser started with a CDP debugging endpoint, call chromium.connectOverCDP(). The endpoint can be an HTTP URL such as http://browser-host:9222 or a CDP WebSocket URL.
const { chromium } = require('playwright');
const browser = await chromium.connectOverCDP('http://browser-host:9222');
try {
const contexts = browser.contexts();
const context = contexts[0] ?? await browser.newContext();
const page = context.pages()[0] ?? await context.newPage();
await page.goto('https://example.com');
console.log(await page.title());
} finally {
await browser.close();
}
An existing CDP browser may already contain a default context and open pages, so inspect browser.contexts() and context.pages() before creating new ones. CDP supports Chromium only. A browser launched externally with arguments that differ from Playwright’s curated launch configuration can also exhibit broken or missing functionality.
Rank #2
When CDP is the wrong choice
- You need Firefox or WebKit.
- Your suite depends on features such as Playwright request routing that the provider exposes only through its native endpoint.
- You need identical behavior across Playwright versions and the provider offers a version-matched native endpoint.
Playwright’s documentation characterizes CDP as significantly lower fidelity than browserType.connect(); treat that as a feature boundary, not merely a performance setting (official API documentation).
Run Playwright Test against a remote browser
Playwright Test can supply its normal browser, context, and page fixtures from a remote browser. Set use.connectOptions.wsEndpoint in the test configuration.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
connectOptions: {
wsEndpoint: process.env.PLAYWRIGHT_WS_ENDPOINT!,
},
},
});
Store the endpoint in an environment variable or your CI secret store, not in source control. The remote browser must be reachable from the test runner. Launch-only settings such as headless and channel do not change a browser that has already started remotely; configure those on the browser host or through the provider (TestOptions connectOptions).
Example test
import { test, expect } from '@playwright/test';
test('opens the remote browser', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
});
For parallel workers, confirm the remote service’s concurrency allowance and isolation model. A shared browser context can leak cookies, local storage, or pages between tests; prefer a fresh context per worker or the isolation mechanism documented by the provider.
Browserless connection patterns
Browserless documents its default managed Chromium WebSocket endpoint as CDP, so connect with chromium.connectOverCDP() and keep the token in an environment variable. Its examples use playwright-core, which does not bundle local browser binaries.
const { chromium } = require('playwright-core');
const endpoint = `wss://production-sfo.browserless.io?token=${process.env.BROWSERLESS_TOKEN}`;
const browser = await chromium.connectOverCDP(endpoint);
const context = browser.contexts()[0] ?? await browser.newContext();
const page = context.pages()[0] ?? await context.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
For Browserless’s native Playwright protocol, its documentation uses the /chromium/playwright path with connect(); it also documents /firefox/playwright and /webkit/playwright. Browserless identifies page.route(), APIRequestContext, and non-Chromium browsers as cases that require the native protocol rather than its default CDP endpoint (Browserless Connect Playwright).
Rank #3
Choose the nearest documented region to reduce network latency. Endpoint paths, regions, concurrency limits, pricing, and service capabilities can change, so verify the current provider documentation before deployment (Browserless connection URLs).
Or skip the browser setup
If your goal is a static website image or PDF rather than an interactive Playwright session, ScreenshotNeo returns a screenshot from one GET request. Its API accepts a URL and can produce PNG, JPEG, WebP, or PDF. The call below uses the documented endpoint; see the ScreenshotNeo API documentation for all 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}`);
Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
Security checklist for remote browser endpoints
- Keep Playwright and CDP endpoints on a private network or behind an allowlist and authenticated gateway.
- Never commit provider tokens, signed URLs, cookies, or authorization headers.
- Use a non-obvious WebSocket path and rotate credentials when access changes.
- Assume anyone who can connect can navigate pages, read session data, and control the host user.
- Separate test accounts and browser profiles from production credentials.
- Use TLS for connections crossing an untrusted network and verify the provider’s certificate.
Performance and reliability considerations
Network distance
Every navigation, action, and assertion crosses the client-to-browser network. Place the test runner near the browser region, avoid unnecessary round trips, and wait for a meaningful readiness signal rather than an arbitrary long delay.
Contexts and cleanup
Reuse a connection for a test run when the provider supports it, but create isolated contexts for independent tests. Close pages and contexts in teardown so abandoned sessions do not consume remote capacity.
Timeouts and retries
Set explicit navigation and action timeouts appropriate to the remote network. A retry can recover a transient transport failure, but it cannot fix an invalid protocol, an expired token, or a page that consistently fails to load. Log the endpoint host, protocol, browser version, and failure stage without logging secrets.
Cost and capacity
Managed services commonly meter concurrency, browser time, or session usage; the supplied provider documentation does not establish a universal pricing or reliability figure. Check the current service terms and concurrency limits, then size workers so parallel tests do not queue unexpectedly.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting remote Playwright connections
connect() fails against a service URL
Confirm the endpoint protocol and path. Browserless’s default endpoint is CDP, so use connectOverCDP(); retain connect() only with its documented /playwright endpoint.
Native connection reports a version mismatch
Install matching Playwright major and minor versions on the client and the browser server. Rebuild the remote image or update the client rather than mixing minor releases.
page.route() does not intercept requests
Check whether you connected through CDP. Browserless documents routing as a native Playwright-protocol capability; switch to its native endpoint when routing is required.
Advanced APIs behave differently
CDP is lower fidelity, and externally supplied browser arguments can conflict with Playwright expectations. Try the native protocol or launch the browser with the provider’s recommended arguments.
Connection refused or times out
Verify that the server is listening on an address reachable from the client. Playwright’s launch server defaults to localhost, so a remote client cannot reach it until you deliberately bind and permit the network listener. Check firewall, security-group, proxy, and WebSocket upgrade rules.
Playwright Test ignores headless or channel
Those are launch options. With connectOptions, the browser already exists remotely; change its host or provider configuration instead.
Authentication or authorization errors
Check that the token is present, URL-encoded, unexpired, and associated with the correct region or endpoint. Keep it out of logs and source control, and test the endpoint from the same network as the runner.
Tests see another test’s cookies or pages
Inspect the remote context model. Create a new context per test or worker, close old pages, and avoid sharing a persistent profile unless shared state is intentional.
Connection decision guide
- Ask the provider whether the URL is Playwright protocol or CDP.
- For Playwright protocol, verify matching major and minor versions and call
browserType.connect(). - For a Chromium CDP endpoint, call
chromium.connectOverCDP()and test the APIs your suite needs. - For Playwright Test, set
use.connectOptions.wsEndpointand move launch settings to the remote host. - Lock down the endpoint, store credentials as secrets, and validate context isolation before enabling parallel workers.
Frequently Asked Questions
Can I connect Playwright to a remote Firefox or WebKit browser?
Yes, but the remote service must expose the Playwright protocol. CDP connections through chromium.connectOverCDP() are Chromium-only.
Does a remote WebSocket URL always use connect()?
No. The URL scheme is insufficient; use the protocol and path documented by the service. A WebSocket URL can point to a CDP endpoint.
Should I install playwright or playwright-core?
Use the package your provider documents. Browserless examples use playwright-core because the managed service supplies the browser binary; a local Playwright installation is appropriate when you manage the browser yourself.
The Bottom Line
Match the API to the endpoint: native Playwright protocol for browserType.connect(), Chromium CDP for chromium.connectOverCDP(), and use.connectOptions.wsEndpoint for Playwright Test. Version-match native clients, expect lower fidelity from CDP, and protect every remote endpoint as a full browser-control interface.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.




