Core Concepts

Conditional Logic

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. CallIfFound and CallIfNotFound follow a three-scope cascade -- selector, UOW, and global. CallAfterFillIn is a single per-UOW delegate where only Terminate has a defined effect.

Element Callbacks

CallIfFound fires after a selector finds and matches elements. You receive the browser or application object, the current UOW, and the matched element list. CallIfNotFound fires when a selector finds no elements after all strategies are tried. Both can be attached at the selector level, the UOW level, or globally on GPAL. Return CallIfStatus.Handled to stop further callback propagation, or NotHandled to allow broader-scope handlers to also fire.

Three Scopes and Row Branching

Callbacks stack across three scopes -- selector, UOW, and global -- firing in order unless one returns Handled. CallAfterFillIn is a fourth point: it fires after each row of tokens is consumed during FillInFrom, giving you a per-record branching point to submit, evaluate, or continue.

// Selector-level: handle a cookie banner if present

var cookieBanner = GPAL.Selector

.WithCSS("#cookie-accept")

.CallIfFound((browser, uow, elements) => {

browser.LeftClick(elements[0]);

return CallIfStatus.Handled;

})

.CallIfNotFound((browser, uow, selector) => {

return CallIfStatus.Handled; // no banner - fine

})

.ToGPALObject();

// CallAfterFillIn: branch per row during a data-driven fill

browser.WithSelector(nameField)

.WithSelector(emailField)

.FillInFrom("contacts.csv")

.CallAfterFillIn((browser, uow, tokens) => {

browser.LeftClick(submitBtn);

return CallIfStatus.Handled;

});

TIP

CallAfterFillIn fires once per consumed row of data, not once per element. It runs after every row regardless of what was filled. Use it to take action after each record is processed.

Stop On Not Found

WithStopOnNotFound is a setting, not a callback. It terminates the workflow immediately when a selector yields no results, without invoking any callback. It follows the same three-scope hierarchy: set it globally on GPAL, on a browser or application instance, or per selector. The most specific setting wins. A common pattern is to set it false globally (non-critical selectors can miss) and true on specific selectors where a missing element means something is fundamentally wrong.

WARNING

When WithStopOnNotFound(true) is in effect and a selector finds nothing, the workflow halts before CallIfNotFound is invoked. If you need to log or handle the not-found case before stopping, use CallIfNotFound and throw or return from there instead.