Core Concepts

The Event System

Events, Not Files

GPAL's philosophy is to publish, not persist. Every significant operation, element found, not found, action taken, exception raised, publishes an event. What you do with those events is entirely up to you: write to a file, insert to a database, display in a UI, send an email, or ignore them entirely. GPAL imposes nothing. An event carries a GPALEventType, and everything that receives events subscribes to the types it wants.

Event Types and Who Raises Them

GPALEventType is a flags enum, so a subscription is a set of types rather than a single level. The individual types are INFO, WARNING, ERROR, EXCEPTION, DEBUG, DEEPDEBUG, NOTICE, CAUTION, and FAILURE. Two named combinations save you spelling out the common cases. GPALALL is what GPAL itself raises: INFO, WARNING, ERROR and EXCEPTION. USERALL is what your workflow raises: NOTICE, CAUTION, FAILURE and EXCEPTION. The split matters because a workflow wants to see its own story without GPAL's running commentary underneath it. Publish your own events with GPAL.PublishSimpleEvent, which captures the calling method name and a screenshot for you, so your events arrive with the same context as GPAL's own.

// Handlers of your own, one for each channel

GPAL.WithInformationHandler((sender, e) => Console.WriteLine($"[{e.GPALEventType}] {e.Message}"))

.WithExceptionHandler((sender, e) => e.ScreenShot?.Save("exception-context.png"));


// Or the built-in ones, told which types they want

GPAL.WithPublishToConsole(GPALEventType.USERALL); // your workflow only

GPAL.WithPublishToDebug(GPALEventType.GPALALL); // what GPAL is doing, in the debugger

GPAL.WithPublishToConsole(GPALEventType.USERALL | GPALEventType.ERROR);


// Publish your own event into the same stream

GPAL.PublishSimpleEvent(GPALEventType.NOTICE, "Login step completed", browser, GPALObjectType.Browser);


// Dynamic values in a message go in brackets, so a message reads the same whatever is in them

GPAL.PublishSimpleEvent(GPALEventType.FAILURE, $"Could not download [{fileName}]");

NOTE

WithPublishToConsole and WithPublishToDebug both default to every type worth reading, so calling them with no argument is the quick way to see everything. Pass a type set once you know which half of the story you are watching. A logger is attached the same way, with GPAL.WithPublishToLogger.

What Every Event Carries

GPALEventArgs contains: GPALEventType, Message, DateTimeStamp, the current UOW and Selector, GPALObject (the Browser or Application that raised the event), the matched element list, a Screenshot of the browser at the moment of the event, ExceptionRaised on EXCEPTION events, and Tokens/TokenList for data-bearing events. The screenshot is included by default because its value on an exception, seeing exactly what the browser showed when something failed, is high enough to justify the overhead.

WARNING

If nothing is attached, every event is discarded. GPAL will never create log files, write to disk, or output to console on its own. Attach a handler, a console, or a logger before starting a workflow, or the run leaves no trace of itself.

💬 Ask GPAL