Tutorials

Tutorials

Driving a Browser Directly with PuppeteerClient

Under the high-level IBrowser fluent interface sits IPuppeteerClient - a thinner layer that exposes browser actions almost one-to-one with PuppeteerCommunicator's API. This tutorial gets an IPuppeteerClient from a browser, chains a few navigation and interaction calls with AndThen, and reads results back from individual calls.

Complete Program

Here's the whole workflow, start to finish. Each piece is broken down and explained below.

using GenerallyPositive;

using GenerallyPositive.Browser;

using static GenerallyPositive.Enums;

GPAL.WithPublishToConsole(GPALEventType.INFO | GPALEventType.ERROR | GPALEventType.WARNING | GPALEventType.DEBUG)

.WithPublishStackTrace();

IBrowser browser = GPAL.Browser

.WithBrowserType(BrowserType.Chrome)

.WithUseAutomationEngine(AutomationEngine.PuppeteerPort)

.WithUseDebugPort(0xdead)

.WithNetworkIdleMaxConnections(0)

.WithWaitOnIdleConnection()

.ToGPALObject();

browser.GoTo(""); // launches with the default page

IPuppeteerClient client = browser.PuppeteerClient;

var result = client

.GoTo("https://example.com")

.AndThen().CheckNetworkIdle()

.AndThen().GoTo("https://example.org")

.Execute();

result = client.NewTab("https://example.com").AndThen().CheckNetworkIdle().Execute();

result = client.NextTab().Execute();

bool clickable = client.IsClickable("#search-input").Execute<bool>();

bool displayed = client.IsDisplayed("#search-input").Execute<bool>();

result = client.FillInOverwrite("#search-input").WithText("hello world").Execute();

result = client.SubmitForm("#search-form").Execute();

result = client.ScrollWindow(0, 200).Execute();

result = client.PageDown(2).Execute();

browser.Close(true);

Get the PuppeteerClient From an Existing Browser

You don't construct an IPuppeteerClient directly - you get one off a live IBrowser. browser.PuppeteerClient hands you a client wired to the same automation engine and session as the browser, so anything it does happens in that browser.

IBrowser browser = GPAL.Browser

.WithBrowserType(BrowserType.Chrome)

.WithUseAutomationEngine(AutomationEngine.PuppeteerPort)

.WithUseDebugPort(0xdead)

.WithNetworkIdleMaxConnections(0)

.WithWaitOnIdleConnection()

.ToGPALObject();

browser.GoTo("");

IPuppeteerClient client = browser.PuppeteerClient;

TIP

WithUseDebugPort sets the Chrome DevTools port GPAL connects to. This pairs with AutomationEngine.PuppeteerPort, which talks to Chrome over that port rather than a piped connection.

AndThen Chains Multiple Steps Into One Call

AndThen() lets you queue up several actions - navigate, then wait for the network to go idle, then navigate again - and send them as one chained operation, finishing with Execute(). This is the lower-level equivalent of the multi-step chains you see on IBrowser.

var result = client

.GoTo("https://example.com")

.AndThen().CheckNetworkIdle()

.AndThen().GoTo("https://example.org")

.Execute();

result = client.NewTab("https://example.com").AndThen().CheckNetworkIdle().Execute();

result = client.NextTab().Execute();

TIP

AndThen() queues another step in the same call; Execute() (or Execute<T>()) sends everything queued so far and returns the result. A chain should always end in Execute or Execute<T>.

Read State, Then Act on the Page

Execute<bool>() returns a typed result for queries like IsClickable and IsDisplayed - handy for checking an element's state before interacting with it. FillInOverwrite, SubmitForm, ScrollWindow, and PageDown are the same interaction primitives IBrowser builds its higher-level actions on top of.

bool clickable = client.IsClickable("#search-input").Execute<bool>();

bool displayed = client.IsDisplayed("#search-input").Execute<bool>();

result = client.FillInOverwrite("#search-input").WithText("hello world").Execute();

result = client.SubmitForm("#search-form").Execute();

result = client.ScrollWindow(0, 200).Execute();

result = client.PageDown(2).Execute();

Closing Down

Close(true) on the IBrowser shuts down the underlying driver process once the workflow is finished, regardless of whether you drove it through IBrowser or IPuppeteerClient.

browser.Close(true);

WARNING

Passing true kills the running web driver process. Use true when the workflow is completely done; use false if another workflow in the same run still needs that driver.