GPAL supports 7 stable automation engine variants across 3 technology stacks and works with Chrome, Edge, and Firefox. The same workflow code runs on any of the 19 resulting combinations - Firefox is not supported by the Puppeteer-based engines.
GPAL has four branching points: CallIfFound and CallIfNotFound respond to element discovery, WithStopOnNotFound terminates the workflow when an element is missing, and CallAfterFillIn branches per row during data-driven fill operations. All follow the same three-scope hierarchy.
GPAL settings flow from broad to specific. Configure once globally and override only where needed - at the browser or application object level, or at the individual selector level.
One fluent API retrieves credentials whether typed directly, stored in a password manager vault, or obtained via an OAuth/service-account/API-key flow - the consuming code stays the same.
GPALElement.Click() handles most callback interactions. ElementAssistant is for the cases where it can't - switching to JavaScript or hardware interaction when Selenium clicks are intercepted, downloading or uploading via a found element, or filling text into an input element your selector already located.
When a Selenium action throws, GPAL does not just give up - it logs an EXCEPTION event and retries the action, usually via JavaScript injection, so the workflow keeps moving. WithNoFallbackActions(true) turns this safety net off for workflows that should fail loudly at the first sign of trouble.
GPAL.yaml is created and loaded automatically every run. A handful of optional config files - credentialsConfig.json, LLMDigestRules.yaml, googleDorkingConfig.json - follow the same Load/Save pattern but are only written when you call Save(). GPALRESTAPI also keeps a single emergency crash log.
WithAllThatMatch controls how many elements GetGrid collects - on a single page, across multiple pages via WithNextPageButton, or via WithInfiniteScroll. The same number means different things depending on how many results the first page returns.
Selectors find elements - actions are what GPAL actually does to them. Clicking, typing, hovering, scraping into a grid, filling from a data source, and waiting are all actions, and every action runs against everything the current selectors matched.
Browsers and applications are only two of the things GPAL automates. Credentials, AI, REST, email, Excel, and file conversion are all separate subsystems reached through the same GPAL factory, using the same fluent pattern you already know.
The Event System says GPAL never writes logs on its own - GPAL.Logger is the built-in, opt-in tool for when you decide you do want a log. One fluent chain configures where entries go and in what format, then every .Log() call writes one more entry there.
After a location strategy finds candidate elements, match criteria filter that set to only the elements you actually want. This two-layer approach - find then filter - is specific to browser automation and keeps selectors both broad and precise.
WaitTime and AIModel look like enums - GPAL.WithWaitFor(WaitTime.Forever) or .WithModel(AIModel.Claude35Sonnet) - but they are actually small readonly structs with an implicit conversion from a plain value, so any string or number you type by hand works too. It is a pattern most C# developers have never needed, because most APIs do not face this exact problem.
A persistent selector is checked on every unit of work for the life of the session - use it for things that can pop up at any time and aren't part of the workflow itself, like cookie-consent banners or session-timeout dialogs.
CredentialServiceType.StaticKey is a simpler credential type for services that authenticate with one static API key. Supply the key via WithServiceKey, WithKeyFromEnv, or WithKeyFromApi - FetchAccessToken hands it back unchanged with no login step.
GPAL never writes files or logs anything on its own. Instead it publishes structured events to two channels - Information and Exception - that you subscribe to and handle however you choose.
GPAL's fluent interface is its defining characteristic. Every subsystem, every operation, every configuration option is expressed through the same chained method syntax - readable by anyone, consistent across 19 of the 21 possible engine and browser combinations.
Everything in GPAL starts with the GPAL static class - a single entry point that instantiates every subsystem and holds all global configuration through a clean fluent interface.
Selectors are how GPAL locates elements in a browser or desktop application. A single selector can define multiple location strategies - if the first finds nothing, GPAL automatically tries the next.
GPAL is the highest-level automation layer, but it sits on top of lower-level layers you can use directly for custom tooling or finer control. All layers are fluent and all map to the same set of operations.
A Unit of Work (UOW) is GPAL's atomic block - any number of selectors followed by any number of actions, all operating on the same matched set of elements, until the next WithSelector starts a new UOW. One selector can match a hundred elements, and one action then applies to all of them.
GPALFile, GPALUrl, GPALGrid, and GPALDatabase show up everywhere a typical API would hand you a raw string, path, or array. GPAL gives you an object instead - and that object carries real behavior the library uses directly.
Every With... setter in a fluent chain returns a configuration interface, not the finished object. ToGPALObject() - or an equivalent explicit cast - is the step that turns that configuration into a real, usable GPAL object. Both forms do exactly the same thing; which one to write is a matter of what reads best where it's used.