Atata 1.14.0 is Released

November 10, 2021 by Yevgeniy Shunevych

Atata 1.14.0 is released with new global events functionality.


New Features

  • major #571 Global events functionality
  • major #572 Add AtataContext events
  • major #573 Add PageObject<TOwner> events
  • major #574 Add ScreenshotFileSavedEvent event
  • minor #576 Make AtataContext.UIComponentAccessChainScopeCache property public
  • minor #577 Add SubjectOf and DynamicSubjectOf methods to SubjectBase<TObject, TSubject> and Subject
  • minor #579 Add AggregateAssert method to SubjectBase<TObject, TSubject>

Changes and Enhancements

  • major #575 Make obsolete old event subscription methods of AtataContextBuilder
  • minor #578 Add assertionScopeName optional parameter to AggregateAssert methods of PageObject<TOwner>

Global Events

The functionality allows to subscribe to Atata built-in and custom events as well as publish events.


Added EventBus class with IEventBus interface with a set of methods:

public void Publish<TEvent>(TEvent eventData);

public object Subscribe<TEvent>(Action eventHandler);

public object Subscribe<TEvent>(Action<TEvent> eventHandler);

public object Subscribe<TEvent>(Action<TEvent, AtataContext> eventHandler);

public object Subscribe<TEvent, TEventHandler>()
    where TEventHandler : class, IEventHandler<TEvent>, new();

public object Subscribe<TEvent>(IEventHandler<TEvent> eventHandler);

public void Unsubscribe(object subscription);

public void UnsubscribeHandler(object eventHandler);

public void UnsubscribeAll<TEvent>();

public void UnsubscribeAll(Type eventType);

Added public IEventBus EventBus { get; } property to AtataContext, which can used to subscribe to and publish events at any time of test cycle.


The event handler interface to implement for event handler classes:

public interface IEventHandler<in TEvent>
    void Handle(TEvent eventData, AtataContext context);


The event handler interface to implement for conditional event handler classes:

public interface IConditionalEventHandler<in TEvent> : IEventHandler<TEvent>
    bool CanHandle(TEvent eventData, AtataContext context);


The builder of event subscriptions. Added public EventSubscriptionsAtataContextBuilder EventSubscriptions { get; } property to AtataContextBuilder, which provides the methods to subscribe to Atata and custom events during AtataContext building.

The list of its methods:

public EventSubscriptionsAtataContextBuilder Add<TEvent>(Action eventHandler);

public EventSubscriptionsAtataContextBuilder Add<TEvent>(Action<TEvent> eventHandler);

public EventSubscriptionsAtataContextBuilder Add<TEvent>(Action<TEvent, AtataContext> eventHandler);

public EventSubscriptionsAtataContextBuilder Add<TEvent, TEventHandler>()
    where TEventHandler : class, IEventHandler<TEvent>, new();

public EventSubscriptionsAtataContextBuilder Add<TEvent>(IEventHandler<TEvent> eventHandler);

public EventSubscriptionsAtataContextBuilder Add(Type eventHandlerType);

public EventSubscriptionsAtataContextBuilder Add(Type eventType, Type eventHandlerType);


Subscribe action event handler

    .EventSubscriptions.Add<DriverInitEvent>(e => e.Driver.Maximize());

Subscribe action event handler as method

Method can have no parameters, single event type parameter, or event type parameter with AtataContext parameter.


private static void OnDriverInitEvent()
private static void OnDriverInitEvent(DriverInitEvent eventData)
private static void OnDriverInitEvent(DriverInitEvent eventData, AtataContext context)

Then subscribe it:


Create and subscribe specific event handler class

Create an event handler class, for example for DriverInitEvent:

public class DriverInitEventHandler : IEventHandler<DriverInitEvent>
    public void Handle(DriverInitEvent eventData, AtataContext context)
        // TODO: Implement.

Subscribe it during AtataContext building:

    .EventSubscriptions.Add(new DriverInitEventHandler());

Create and subscribe universal event handler class

Create a univeral event handler class, which can be used to subscribe to any event type:

private class UniversalEventHandler : IEventHandler<object>
    public void Handle(object eventData, AtataContext context)
        // TODO: Implement.

Subscribe it during AtataContext building to different events:

    .EventSubscriptions.Add<DriverInitEvent>(new UniversalEventHandler())
    .EventSubscriptions.Add<AtataContextCleanUpEvent>(new UniversalEventHandler());

Built-in Events

AtataContext Events

  • AtataContextInitEvent - an event that occurs when AtataContext is started to initialize.
  • AtataContextInitCompletedEvent - an event that occurs when AtataContext is initialized.
  • AtataContextCleanUpEvent - an event that occurs when AtataContext is cleaning up.
  • DriverInitEvent - an event that occurs when AtataContext driver is initializing.

PageObject Events

  • PageObjectInitEvent - an event that occurs when PageObject<TOwner> is started to initialize.
  • PageObjectInitCompletedEvent - an event that occurs when PageObject<TOwner> is initialized.
  • PageObjectDeInitEvent - an event that occurs when PageObject<TOwner> is de-initialized.

Screenshot Events

  • ScreenshotFileSavedEvent - an event that occurs when a screenshot file is saved.

Old Event Subscription Methods Became Obsolete

Methods of AtataContextBuilder became obsolete:

  • OnBuilding -> Use EventSubscriptions.Add<AtataContextInitEvent>(...) instead.
  • OnBuilt -> Use EventSubscriptions.Add<AtataContextInitCompletedEvent>(...) instead.
  • OnDriverCreated -> Use EventSubscriptions.Add<DriverInitEvent>(...) instead.
  • OnCleanUp -> Use EventSubscriptions.Add<AtataContextCleanUpEvent>(...) instead.

The old methods will continue to work but will generate warnings on their usage.