Tutorials

Tutorials

Driving the Browser Through the REST Client

GPAL.OttoMagicClient gives you the same browser actions as IBrowser, but expressed as REST calls against the OttoMagic engine - useful when the thing driving the browser isn't your C# process. This tutorial opens tabs, waits for the network to settle, and walks through Execute() versus the typed Execute<T>().

Complete Program

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

using GenerallyPositive;

using static GenerallyPositive.Enums;

using System.Threading;

GPAL

.WithUseOttoMagic(@"C:OttoMagic")

.WithPublishToConsole();

IRESTClient client = GPAL.OttoMagicClient

.WithName("OttoMagicClient")

.ToGPALObject();

// open a few tabs and let the network settle

client.GoTo("https://youtube.com").Execute();

client.CheckNetworkIdle().Execute();

client.NewTab("https://ebay.com").Execute();

client.CheckNetworkIdle().Execute();

// untyped Execute() - just confirms the call ran

client.Refresh().Execute();

// typed Execute<T>() - returns a strongly typed result

string currentUrl = client.GetCurrentUrl().Execute<string>();

bool atEndOfPage = client.IsEndOfPage().Execute<bool>();

// move between tabs and windows

client.GoToTab("https://example.com").Execute();

client.NextTab().Execute();

client.PreviousTab().Execute();

client.OpenWindow("https://deadmike.com").Execute();

Thread.Sleep(1_500);

client.NextWindow().Execute();

client.PreviousWindow().Execute();

client.CloseTab().Execute();

client.CloseWindow().Execute();

GPAL.OttoMagicClient: A Fluent REST Client

GPAL.OttoMagicClient.WithName(...).ToGPALObject() builds an IRESTClient configured to talk to the OttoMagic engine over REST instead of driving a local WebDriver directly. WithName labels the client in logs - useful once you have more than one client talking to the same engine. The result is the same fluent, chainable surface you've been using on IBrowser.

IRESTClient client = GPAL.OttoMagicClient

.WithName("OttoMagicClient")

.ToGPALObject();

GoTo, NewTab, and CheckNetworkIdle

GoTo navigates the active tab, and NewTab opens a fresh tab at a URL. Pages built with heavy client-side scripts keep making network requests after the initial load fires, so CheckNetworkIdle waits until the network has been quiet for a moment before the next step runs - which avoids acting on a half-loaded page.

client.GoTo("https://youtube.com").Execute();

client.CheckNetworkIdle().Execute();

client.NewTab("https://ebay.com").Execute();

client.CheckNetworkIdle().Execute();

TIP

Like WaitFor on IBrowser, CheckNetworkIdle is an ordinary chainable call - place it right after the navigation it should wait for, and again after any later step that triggers more network activity.

Execute() vs. Execute<T>()

Every REST call ends with Execute(). For calls that don't return useful data - Refresh, NewTab, GoTo - the plain untyped Execute() is enough; it just confirms the call completed. For calls that return information about the page, use the generic Execute<T>() so you get back a properly typed value instead of a raw object.

// untyped Execute() - just confirms the call ran

client.Refresh().Execute();

// typed Execute<T>() - returns a strongly typed result

string currentUrl = client.GetCurrentUrl().Execute<string>();

bool atEndOfPage = client.IsEndOfPage().Execute<bool>();

WARNING

Execute<T>() trusts you to ask for the right type - GetCurrentUrl returns a string, IsEndOfPage returns a bool. Asking for the wrong T won't be caught until the call runs.

Navigating Tabs and Windows

GoToTab jumps to the tab whose URL matches, while NextTab and PreviousTab cycle through open tabs in order. OpenWindow creates a separate browser window, and NextWindow / PreviousWindow cycle through windows the same way tabs cycle - useful when a workflow needs to juggle more than one window at once. CloseTab and CloseWindow clean up when a tab or window is no longer needed.

client.GoToTab("https://example.com").Execute();

client.NextTab().Execute();

client.PreviousTab().Execute();

client.OpenWindow("https://deadmike.com").Execute();

Thread.Sleep(1_500);

client.NextWindow().Execute();

client.PreviousWindow().Execute();

client.CloseTab().Execute();

client.CloseWindow().Execute();

AndThen: Chaining Without Breaking the Fluent Surface

Every call so far has ended with Execute() or Execute<T>(), and the next call starts a new statement on client. AndThen() (or its generic AndThen<T>()) executes the call you just built, then hands back the same client so you continue setting up the next call in the same chain - this is what makes GPAL.OttoMagicClient a genuinely fluent client rather than a one-call-per-statement wrapper. WithResultName("name") labels the result of the call that follows it - set the name first, then call the endpoint method - and GetExecutionResults() returns a ResultCollection holding every named result produced by the chain so far, read back with results["name"]. AndThen<T>() can also be the last call in a chain - it still executes and stores the named result - but when nothing follows it, Execute<T>() is the cleaner choice: it ends the chain and hands you the result directly, where the <T> is the type of the result being retrieved.

// AndThen() executes the call before it and returns the same client,

// so the chain continues without starting a new statement

client

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

.AndThen()

.CheckNetworkIdle()

.AndThen()

.WithResultName("url")

.GetCurrentUrl()

.Execute<string>(); // last call in the chain: Execute<T>() reads cleaner than AndThen<T>() here

// named results from anywhere in the chain are available afterward

var results = client.GetExecutionResults();

string currentUrl = (string)results["url"];