目录

DevTools 协议

本教程介绍如何将 Selenium、Playwright、Puppeteer 等自动化工具连接到 嵌入在 .NET 应用程序中的浏览器。

Selenium, Playwright, and Puppeteer normally start their own copy of Chrome and drive it. With DotNetBrowser the browser already exists: it runs inside your application and displays web pages in a BrowserView control. Rather than starting a browser, these tools attach to the one you have.

They attach over the Chrome DevTools Protocol, or CDP — the same protocol Chrome DevTools speaks. DotNetBrowser can expose a remote debugging endpoint on a local TCP port, and any CDP client can connect to it.

Once connected, the tool operates on the page your application already displays. Clicks, navigation, and script evaluation issued from the test code appear in the BrowserView control. That lets you run an existing test suite against the web UI inside your own application rather than against a standalone browser.

Opening the endpoint 

Set RemoteDebuggingPort on EngineOptions.Builder when you create the IEngine instance:

C#
VB
IEngine engine = EngineFactory.Create(
    new EngineOptions.Builder
    {
        RemoteDebuggingPort = 9222
    }.Build()
);
Dim engine As IEngine = EngineFactory.Create(
    New EngineOptions.Builder() With {
        .RemoteDebuggingPort = 9222
    }.Build()
)

Any free TCP port works. These tutorials use 9222 for Selenium and 9223 for Playwright and Puppeteer.

Address the endpoint as localhost or 127.0.0.1. Both normally work, but localhost can resolve to an address the endpoint is not listening on, which surfaces as a refused connection.

The Engine guide covers the same option in more detail. Its --remote-allow-origins switch is for clients that are themselves web pages, such as the DevTools front end: a browser attaches an Origin header, and Chromium answers 403 unless that origin is allowed. Selenium, Playwright, and Puppeteer send no Origin header, so these tutorials do not need the switch.

Security 

The remote debugging endpoint has no authentication. Any process on the same machine that can reach the port can control the pages in that engine. Enable it for local development and test runs, and keep it disabled in the builds you ship.

Attach, do not launch 

Every one of these tools offers two modes: start a browser, or connect to a running one. With DotNetBrowser you always use the second mode, and you work with the page that is already open.

ToolConnect APIThe already-open page
SeleniumChromeOptions.DebuggerAddressthe driver’s current page
PlaywrightIBrowserType.ConnectOverCDPAsyncContexts[0].Pages[0]
PuppeteerPuppeteer.ConnectAsync with ConnectOptions.BrowserURLthe first entry of PagesAsync()

A BrowserView displays the IBrowser instance it was initialized from, so that page is the one your users see. Asking the tool to open a page of its own does not work: NewPageAsync fails against DotNetBrowser in both Playwright and Puppeteer. Pages come from the engine, through IEngine.CreateBrowser.

These tutorials all assume a single page. If the engine has several browsers, or a popup has opened, the order of Pages and PagesAsync() is not guaranteed — match on the page URL rather than taking the first entry.

Match the Chromium version 

How closely the client has to track Chromium depends on the tool.

ChromeDriver is versioned against Chromium directly and refuses to attach to a build it does not recognize. DotNetBrowser 4.3.0 is based on Chromium 152.0.7977.65, so the Selenium.WebDriver.ChromeDriver package has to be built for that Chromium release. A mismatch is the most common reason a Selenium connection fails.

Playwright and Puppeteer tolerate a version gap. Each pins a Chromium build of its own but speaks a stable subset of the protocol to whatever it attaches to, so these tutorials use package versions built against much older Chromium releases and still connect. A feature that relies on a recent CDP command can still be missing from the older protocol build the client was written against.

Connect after the engine is running 

The endpoint accepts connections once the engine has started. The examples connect from a window Load handler or right after the first Navigation.LoadUrl call. That ordering happens to work, but nothing guarantees it, so retry rather than treating the first failure as fatal. The examples only log a failed attempt, to keep the code focused on the connection itself.

CDP calls are asynchronous and run off the UI thread. When a result has to reach the user interface, marshal it back the way your framework requires. Dispose the IBrowser and IEngine instances when the window closes.

Off-screen rendering 

RemoteDebuggingPort is an engine option and does not depend on the rendering mode. An engine created with RenderingMode.OffScreen exposes the endpoint in the same way, so a test host can drive a page with no window on screen. The code is the same; the only difference is that there is no BrowserView in which to watch the scenario run.

Tutorials for each tool 

Each tutorial covers one tool: the package to reference, the code that attaches to the engine, and the failure modes specific to that tool.

  • Selenium — attach a WebDriver session through ChromeDriver.
  • Playwright — connect Playwright for .NET over CDP.
  • Puppeteer — connect Puppeteer Sharp to a running engine.

The complete projects for all three are available in our repository: C#, VB.NET.