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.
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);
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;
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() 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();
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>.
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();
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);
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.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();