Automation Engines

Driving a Browser Directly with PuppeteerClient

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;

NOTE

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

NOTE

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

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.

💬 Ask GPAL