Atata 2.7.0 is Released

February 8, 2023 by Yevgeniy Shunevych


Atata 2.7.0 is released with an enhancement of navigation functionality, step feature and other improvements.

Changelog

New Features

  • minor #734 Add PathAndQuery and Relative properties to UriProvider<TOwner>
  • major #735 Add support of template variables in UrlAttribute and Go.To method’s url parameter
  • major #737 Support merging of page object’s NavigationUrl with Go.To method’s url parameter
  • minor #738 Add FillUriTemplateString methods to AtataContext
  • minor #741 Add RelativeUnescaped, Absolute and AbsoluteUnescaped properties to UriProvider<TOwner>
  • minor #742 Add GetComponents method to UriProvider<TOwner>
  • minor #745 Add Report property to AtataContext
  • major #746 Add Setup and Step methods to Report<TOwner>

Changes and Enhancements

  • major #736 Use Selenium.WebDriver package v4.8.0
  • major #739 Optimize FindByLabelStrategy to use one composite XPath query
  • minor #740 Rename UriProvider<TOwner>.AbsolutePath property to Path
  • minor #743 Add setter to TypingIntervalInSeconds property of TypesTextUsingSendKeysCharByCharAttribute and SetsValueUsingCharByCharTypingAttribute
  • minor #744 Update methods of PageObject<TOwner> to use internally Log.ExecuteSection method instead of Log.Info

Template Variables in UrlAttribute and Go.To Method’s url Parameter

From now on navigation URLs support template variables. The URL can be represented in a template format, like "/organization/{OrganizationId}/". The template is filled with AtataContext.Variables by using AtataContext.FillUriTemplateString(string) method (see #738).

In order to output a { use {{, and to output a } use }}.

Before navigation ensure that a variable is set in AtataContext.

Set Variable Directly Into AtataContext

AtataContext.Current.Variables["OrganizationId"] = 42;

Set Variable During AtataContext Configuration

AtataContext.Configure().
    AddVariable("OrganizationId", 42);

Set Variable in JSON Config

{
  "variables": {
    "OrganizationId": 42
  }
}

Use Template in UrlAttribute

[Url("/organization/{OrganizationId}/")]
public class OrganizationPage : Page<_>
{
}
Go.To<OrganizationPage>();

Use Template Within Go.To

Go.To<OrganizationPage>(url: "/organization/{OrganizationId}/");

Merging of Page Object’s NavigationUrl with Go.To Method’s url Parameter

Before this change, Go.To method’s url parameter always replaced page object’s NavigationUrl value.

Change

Go.To method’s url argument value merges with page object’s NavigationUrl if it starts with one of: ?, &, ;, #. For other cases url argument value replaces the NavigationUrl.

Example

[Url("/some/path?a=1")]
public class SomePage : Page<_>
{
}
Go.To<SomePage>(url: "/another/path?b=2"); // -> "/another/path?b=2"
Go.To<SomePage>(url: "?b=2"); // -> "/some/path?b=2"
Go.To<SomePage>(url: "&b=2"); // -> "/some/path?a=1&b=2"
Go.To<SomePage>(url: ";b=2"); // -> "/some/path?a=1;b=2"
Go.To<SomePage>(url: "#fragment"); // -> "/some/path?a=1#fragment"

Added Report Property to AtataContext

Added property to AtataContext similar to the Report property of PageObject<TOwner>:

public Report<AtataContext> Report { get; }

Usage

AtataContext.Current
    .Report.Info("...")
    .Report.PageSnapshot();

Added Setup and Step Methods to Report<TOwner>

public TOwner Setup(string message, Action<TOwner> action);

public TResult Setup<TResult>(string message, Func<TOwner, TResult> function);

public TOwner Step(string message, Action<TOwner> action);

public TResult Step<TResult>(string message, Func<TOwner, TResult> function);

Setup - executes the specified action and represents it in a log as a setup section with the specified message. The setup action time is not counted as pure test execution time.

Step - executes the specified action and represents it in a log as a section with the specified message.

Usage

AtataContext.Current.Report.Setup("Set up database for example", x =>
{
    // ...
});
Go.To<LoginPage>()
    .Report.Step("Fill credentials", x => x
        .Email.Set("...")
        .Password.Set("..."))
    .Report.Step("Login", x => x
        .Login.ClickAndGo());

Added Members to UriProvider<TOwner>

/// <summary>
/// Gets the absolute path and query provider of the URI.
/// For example: <c>"https://example.org/some/path?arg=val#frg"</c> -> <c>"/some/path?arg=val"</c>.
/// </summary>
public ValueProvider<string, TOwner> PathAndQuery { get; }

/// <summary>
/// Gets the relative URI provider of the URI.
/// For example: <c>"https://example.org/some/path?arg=val#frg"</c> -> <c>"/some/path?arg=val#frg"</c>.
/// </summary>
public ValueProvider<string, TOwner> Relative { get; }

/// <summary>
/// Gets the unescaped relative URI provider of the URI.
/// For example: <c>"https://example.org/some/path?arg=%3F"</c> -> <c>"/some/path?arg=?"</c>.
/// </summary>
public ValueProvider<string, TOwner> RelativeUnescaped { get; }

/// <summary>
/// Gets the absolute URI provider of the URI.
/// For example: <c>"https://example.org/some/path?arg=val#frg"</c> -> <c>"https://example.org/some/path?arg=val#frg"</c>.
/// </summary>
public ValueProvider<string, TOwner> Absolute { get; }

/// <summary>
/// Gets the unescaped absolute URI provider of the URI.
/// For example: <c>"https://example.org/some/path?arg=%3F"</c> -> <c>"https://example.org/some/path?arg=?"</c>.
/// </summary>
public ValueProvider<string, TOwner> AbsoluteUnescaped { get; }

/// <summary>
/// Gets the specified components of the URI using the specified escaping format for special characters.
/// </summary>
/// <param name="components">The components.</param>
/// <param name="format">The format.</param>
/// <returns>A <see cref="ValueProvider{TValue, TOwner}"/> of the components string.</returns>
public ValueProvider<string, TOwner> GetComponents(UriComponents components, UriFormat format = UriFormat.UriEscaped);