Atata 2.6.0 is released with WaitForAngular feature and simplification of page object navigation by dynamic URL.
Changelog
New Features
- major #728 Simplify page object navigation by dynamic URL
- major
#730 Add
WaitForAngular
methods toUIComponentScriptExecutor<TOwner>
- major
#731 Add
WaitForAngularAttribute
trigger attribute
Changes and Enhancements
- minor
#732 Replace
WaitForAngularJSAjaxAttribute
withWaitForAngularJSAttribute
Wait for Angular
Script.WaitForAngular()
method and WaitForAngularAttribute
trigger are added for Angular (v2+) waitings.
Trigger Usage
Apply to button after click:
[WaitForAngular(TriggerEvents.AfterClick)]
public Button<_> Save { get; private set;}
Apply to page object upon initialization:
[WaitForAngular(TriggerEvents.Init)]
public class SomePage : Page<_>
{
}
You can also apply the trigger globally for all Init
and AfterClick
events:
AtataContext.GlobalConfiguration
.Attributes.Global.Add(new WaitForAngularAttribute(TriggerEvents.Init | TriggerEvents.AfterClick));
Method Usage
Go.To<SomePage>()
.Script.WaitForAngular();
Simplification of Page Object Navigation by Dynamic URL
Current functionality of dynamic navigation requires to override Navigate
method
in a page object and call Go.ToUrl
method with the built URL.
Parameters for navigation should be passed through constructor and stored in fields.
Simplification is done by adding NavigationUrl
property which can be set directly
in constructor and the need for Navigate
method disappears.
Implementation
New members are added to PageObject<TOwner>
for a possibility to set a URL
in a page object constructor or in a static helper method:
protected string NavigationUrl { get; set; }
public TOwner AppendNavigationUrl(string urlPart);
public TOwner SetNavigationUrl(string url);
Log messages happening during navigation are also changed. Now they are written like sections, which can be useful to track the time of navigation.
PageObject<TOwner>
members that became obsolete:
NavigateOnInit
property.Navigate
method.
Old Usage Example
Before, you had to override Navigate
method and execute Go.ToUrl
there.
[Url(DefaultUrl)] // The default URL that will be used when no query is provided. Can be omitted.
public class GoogleSearchPage : Page<_>
{
private const string DefaultUrl = "/search";
private readonly string query;
public GoogleSearchPage(string query = null) =>
this.query = query;
protected override void Navigate()
{
if (query != null)
Go.ToUrl($"{DefaultUrl}?q={query}");
else
base.Navigate();
}
public static _ ByQuery(string query) =>
new($"q={query}");
}
New Usage Examples
Example 1
public class UserPage : Page<_>
{
public UserPage(int? id = null)
{
if (id.HasValue)
NavigationUrl = $"/user/{id}";
}
}
Go.To(new UserPage(42));
Example 2
public class UserPage : Page<_>
{
// Default constructor is needed for non-direct navigation, for example via link click.
public UserPage()
{
}
public UserPage(int id)
{
NavigationUrl = $"/user/{id}";
}
}
Go.To(new UserPage(42));
Example 3
public class UserPage : Page<_>
{
public static _ ById(int id) =>
new() { NavigationUrl = $"/user/{id}" };
}
Go.To(UserPage.ById(42));
Example 4
Static URL can be combined with dynamic part.
[Url("/search")]
public class GoogleSearchPage : Page<_>
{
public GoogleSearchPage(string query = null)
{
if (query != null)
NavigationUrl += $"?q={query}"; // "/search" + $"?q={query}" = "/search?q={query}"
}
}
Go.To<GoogleSearchPage>();
// Or:
Go.To(new GoogleSearchPage("keyword"));
Example 5
Similar to the previous example, but uses static method instead of constructor.
[Url("/search")]
public class GoogleSearchPage : Page<_>
{
public static _ WithQuery(string query) =>
new _().AppendNavigationUrl($"?q={query}");
}
Go.To<GoogleSearchPage>();
// Or:
Go.To(GoogleSearchPage.WithQuery("keyword"));