Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use chromium.connectOverCDP() when a Chromium-based browser is already running with a Chrome DevTools Protocol (CDP) endpoint. Use browserType.connect() when the browser was started by Playwright’s launchServer() and you have its Playwright WebSocket endpoint. If you only need login cookies and local storage to survive between runs, launch a dedicated persistent context instead of attaching to somebody else’s live process.

The connection method, endpoint type, browser engine, and security model must match. A successful connection does not guarantee that the expected context or tab exists, so always inspect browser.contexts() and context.pages() before automating.

Choose the right Playwright connection method

Playwright has three different solutions that are often confused:

Situation Use Important constraint
A browser was started with Playwright launchServer() browserType.connect(wsEndpoint) The connecting and launching Playwright installations must have matching major and minor versions.
An existing Chrome, Chromium, Edge, Electron, or another Chromium-based browser exposes CDP chromium.connectOverCDP(endpoint) CDP is Chromium-only and has lower fidelity than Playwright’s own protocol.
You need cookies and local storage to persist, but do not need a user’s live process launchPersistentContext(userDataDir) This launches a browser with that profile; it does not attach to a separate running process.
You need a logged-in state for later runs Save and load Playwright authentication state State files can contain cookies and headers that can impersonate an account.

The endpoint tells you which path is possible. A ws:// URL returned by Playwright’s browser server belongs to connect(). A Chrome debugging HTTP URL such as http://localhost:9222, or a CDP browser WebSocket URL containing /devtools/browser/, belongs to connectOverCDP().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Search+ For Google
  • google search
  • google map
  • google plus
  • youtube music
  • youtube

Attach to an existing Chrome or Chromium session with CDP

1. Start the browser with remote debugging

The browser must already be running with remote debugging enabled. A typical Chromium launch uses a dedicated profile and a local debugging port:

google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/playwright-profile"

Executable names and flags vary by operating system and browser distribution. Use a separate automation profile rather than your normal Chrome profile. Recent Chrome policy changes make automating the regular default profile unsupported and can cause pages not to load or the browser to exit.

Keep the endpoint bound to localhost unless you have deliberately implemented access control. Anyone who can reach a debugging endpoint may be able to control the browser and the operating-system user behind it.

2. Connect and select a context and page

Install Playwright, then use the Chromium binding because CDP attachment is supported for Chromium-based browsers:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install playwright
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.connectOverCDP('http://localhost:9222');
  const contexts = browser.contexts();

  if (contexts.length === 0) {
    throw new Error('The browser is connected, but it has no available context.');
  }

  const context = contexts[0];
  const pages = context.pages();

  if (pages.length === 0) {
    throw new Error('The context is connected, but it has no open pages.');
  }

  const page = pages[0];
  console.log('Attached to:', await page.title(), page.url());
  await page.screenshot({ path: 'attached-page.png', fullPage: true });
  await browser.close();
})();

browser.close() closes Playwright’s connection. It is preferable to closing the user’s browser process when you are attaching to an existing session; still, test the behavior in your environment before using it in a critical workflow.

Use the CDP WebSocket endpoint

If your infrastructure provides a CDP WebSocket URL instead of the HTTP discovery URL, pass it directly:

const browser = await chromium.connectOverCDP(
  'ws://localhost:9222/devtools/browser/your-browser-id'
);

The exact browser ID is generated by the running browser. Do not guess it; obtain the endpoint from the browser’s debugging discovery output or the service that launched the browser.

Reuse a particular tab

Existing sessions can have several tabs. Inspect their URLs and choose deliberately rather than assuming index zero:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Amazon Silk - Web Browser
  • Easily control web videos and music with Alexa or your Fire TV remote
  • Watch videos from any website on the best screen in your home
  • Bookmark sites and save passwords to quickly access your favorite content
for (const [index, candidate] of context.pages().entries()) {
  console.log(index, await candidate.title(), candidate.url());
}

const page = context.pages().find(p => p.url().startsWith('https://app.example.com'));
if (!page) throw new Error('Target application tab was not found.');

Pages can open or close after you connect, so handle a missing tab as a normal runtime condition.

Connect to a browser launched by Playwright

When you control the launch, Playwright’s own browser-server protocol is usually the better connection path. Start a server and print its WebSocket endpoint:

const { chromium } = require('playwright');

(async () => {
  const browserServer = await chromium.launchServer({ headless: true });
  console.log(browserServer.wsEndpoint());
  // Keep the process alive while another process connects.
})();

In another process, pass that endpoint to chromium.connect():

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.connect('ws://127.0.0.1:PORT/your-endpoint');
  const context = browser.contexts()[0];
  const page = context.pages()[0] || await context.newPage();
  console.log(await page.title());
  await browser.close();
})();

The launching and connecting Playwright versions need matching major and minor versions. This is a Playwright WebSocket endpoint, not a Chrome CDP endpoint; using the wrong method produces connection errors or an unusable session. Playwright’s BrowserType API documents both methods and their endpoint formats.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python equivalents

The Python binding exposes the same concepts as connect and connect_over_cdp. Install it with:

pip install playwright
playwright install chromium

Attach to an existing Chromium process

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp("http://localhost:9222")
    contexts = browser.contexts
    if not contexts:
        raise RuntimeError("No browser context is available")

    context = contexts[0]
    pages = context.pages
    if not pages:
        raise RuntimeError("No open page is available")

    page = pages[0]
    print(page.title(), page.url)
    page.screenshot(path="attached-page.png", full_page=True)
    browser.close()

Connect to a Playwright browser server

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect("ws://127.0.0.1:PORT/your-endpoint")
    context = browser.contexts[0]
    page = context.pages[0] if context.pages else context.new_page()
    print(page.title())
    browser.close()

For asynchronous Python, use async_playwright() and await the corresponding methods. Binding-specific signatures are listed in the Python BrowserType API.

Reuse authentication without taking over a live browser

If the actual requirement is “stay logged in between test runs,” a persistent context or saved authentication state is safer and more repeatable than attaching to a person’s open browser.

Persistent context with an isolated profile

const { chromium } = require('playwright');

(async () => {
  const context = await chromium.launchPersistentContext('./automation-profile', {
    headless: false
  });
  const page = context.pages()[0] || await context.newPage();
  await page.goto('https://app.example.com');
  // Log in once; cookies and local storage remain in ./automation-profile.
  await context.close();
})();

Browsers generally do not allow multiple instances to launch with the same user-data directory. Never point this at a profile that another browser process is using.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Save and load storage state

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://app.example.com/login');
  // Complete login, then:
  await context.storageState({ path: 'playwright/.auth/user.json' });
  await browser.close();
})();
const browser = await chromium.launch();
const context = await browser.newContext({
  storageState: 'playwright/.auth/user.json'
});

Protect the state file, restrict its permissions, and exclude it from source control. Playwright’s authentication guide explains the storage-state workflow and its security implications.

CDP limitations and protocol fidelity

Playwright states that “Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers.” CDP attachment is also “significantly lower fidelity than the Playwright protocol connection via browserType.connect().” That does not mean every feature fails, but advanced behavior can differ. If you control the browser launch and need the fullest Playwright behavior, prefer launchServer() plus connect().

CDP can still attach to Chromium-based Chrome, Edge, Electron, and similar browsers. It cannot attach to Firefox or WebKit through this method. Browser launch arguments also matter: an externally launched browser that lacks arguments expected by Playwright may behave differently from a Playwright-launched browser.

Operational checklist for a reliable attachment

  • Confirm the browser engine is Chromium-based before choosing CDP.
  • Verify the endpoint from the running process; do not infer a WebSocket path.
  • Use a dedicated profile directory and avoid concurrent launches with that directory.
  • Check that at least one context and page exist after connecting.
  • Identify tabs by URL, title, or another condition instead of relying on tab order.
  • Keep debugging URLs private and local or protect them with network controls.
  • Store authentication state outside the repository with restricted permissions.
  • Pin compatible Playwright versions when using browserType.connect().
  • Use explicit waits for application readiness rather than assuming the first page is usable.

Troubleshooting common failures

“ECONNREFUSED” or a timeout

Cause: Nothing is listening on the host and port, the browser was not started with remote debugging, or a firewall/container boundary blocks the address.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix: Start the browser with the intended debugging option, confirm the endpoint from the same machine or network namespace, and test the exact host and port. Do not expose a debugging port publicly just to make a connection work.

“WebSocket error” when using connect()

Cause: A CDP URL was supplied to the Playwright-protocol method, or the Playwright major/minor versions do not match.

Fix: Use connectOverCDP() for a Chrome debugging endpoint. For a Playwright browser server, obtain browserServer.wsEndpoint() and install matching Playwright versions on both sides.

The browser connects but no page is found

Cause: The browser has no open tabs, the target tab closed, or the endpoint represents a different context than expected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix: Inspect browser.contexts() and context.pages(), create a page when appropriate, and select by URL or another reliable condition.

Pages fail to load or Chrome exits

Cause: The regular Chrome profile is being automated, two processes are using one profile, or the externally launched browser lacks suitable launch arguments.

Fix: Stop conflicting processes, create a separate automation profile, and launch a clean browser for automation. Do not reuse the user’s default profile.

A feature behaves differently after CDP attachment

Cause: CDP has lower protocol fidelity than Playwright’s own connection.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix: Reduce assumptions about advanced behavior, verify the specific operation in the current Playwright documentation, or move the workflow to a Playwright-launched browser server.

Authentication disappears

Cause: The browser was started with a temporary profile, the wrong context was selected, or saved state was not loaded.

Fix: Use an isolated persistent context for a profile that should survive restarts, or save and load storageState. Treat the resulting file as a credential.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and security considerations

Attaching avoids launching a second browser and can let you reuse an already authenticated tab, which is useful for interactive debugging and extension-enabled sessions. It also couples your script to the lifetime, profile, tabs, and launch flags of another process. A user closing a tab or navigating away can invalidate assumptions mid-run.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Downloader for Fire, Browser...
  • Directly enter the URL of the desired file
  • Store frequently visited URLs in the favorites section for easy retrieval
  • Open the downloaded files in the file manager

For unattended jobs, a Playwright-controlled browser with a known profile or a saved authentication state is normally more deterministic. For remote execution, a CDP endpoint may be supplied by a hosted browser service, but verify that service’s current endpoint, authentication, browser version, and data-isolation terms before relying on it.

Protect both debugging endpoints and authentication files as sensitive credentials. A reachable browser-control endpoint can permit actions as the operating-system user running Chrome, while storage-state files can contain reusable cookies and headers.

Or skip the browser setup

If your goal is a clean image or PDF of a URL rather than interaction with a live tab, ScreenshotNeo returns a screenshot through one GET request. It accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the result in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the complete parameter list in the ScreenshotNeo documentation. This cURL call captures Stripe as WebP:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in Python:

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)

And Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo includes full-page capture with lazy images, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and page-range controls, custom CSS and JavaScript, clicks, selector or network-idle waits, request and ad blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and familiar parameter names for easier migration.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can Playwright attach to an already open Firefox or WebKit session?

Not with connectOverCDP(); Playwright documents CDP attachment for Chromium-based browsers only. Use a Playwright browser server or another supported workflow for non-Chromium engines.

Does connecting over CDP preserve the existing login?

It can expose the contexts and tabs belonging to the running Chromium profile, including their current cookies and storage. The result depends on how that browser was launched and which context you select; for repeatable unattended authentication, use persistent context storage or saved authentication state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can two scripts connect to the same browser?

A browser may accept multiple protocol clients, but concurrent scripts can navigate or close the same pages unexpectedly. Coordinate ownership of tabs and profiles, and avoid sharing a profile directory between separately launched browser processes.

Quick Recap

Bestseller No. 1
Search+ For Google
Search+ For Google
google search; google map; google plus; youtube music; youtube; gmail
Bestseller No. 2
Amazon Silk - Web Browser
Amazon Silk - Web Browser
Easily control web videos and music with Alexa or your Fire TV remote; Watch videos from any website on the best screen in your home
SaleBestseller No. 3
Bestseller No. 5
Downloader for Fire, Browser...
Downloader for Fire, Browser...
Directly enter the URL of the desired file; Store frequently visited URLs in the favorites section for easy retrieval

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.