How to upgrade to Atata 2 considering breaking changes.
The first migration step is to ensure or upgrade your Atata to v1.14.0. Then fix all Atata warnings telling that some class/member is obsolete, as those items should be removed in v2.
The Atata package now targets .NET Standard 2.0, which supports .NET 5+, .NET Framework 4.6.1+ and .NET Core/Standard 2.0+. Dropped support of .NET 4.0 - .NET 4.6.
Thus, if your project uses the .NET Framework version prior to 4.6.1, either upgrade the project to the newer version or just stay with Atata v1.
The biggest change in Atata 2 is the upgrade of Selenium.WebDriver to v4. Please check out the Upgrade to Selenium 4 to see what changed and make appropriate modifications after the upgrade to Atata v2. Pay attention to driver configuration changes. All WebDriver configuration changes are reflected in Atata and Atata.Configuration.Json. Check out the updated Atata.Configuration.Json / JSON Schema if you use Atata JSON configuration files.
IWebDriver
is used instead of RemoteWebDriver
A usage of RemoteWebDriver
was everywhere replaced with IWebDriver
:
AtataContext.Driver
propertyUIComponent.Driver
propertyTriggerContext<TOwner>.Driver
propertyAtataContextBuilder.UseDriver
methodsIDriverFactory.Create
methodDriverAtataContextBuilder<TBuilder>.CreateDriver
methodDriverAtataContextBuilder<TBuilder, TService, TOptions>.CreateDriver
methodDriver.ExecuteScript(...)
-> Driver.AsScriptExecutor().ExecuteScript(...)
Driver.GetScreenshot()
-> Driver.AsScreenshotTaker().GetScreenshot()
Most other properties and methods of RemoteWebDriver
are also present in IWebDriver
.
Visibility
is changed from Visible
to Any
In Atata v1 when Visibility
of control is not specified explicitly, Visibility.Visible
is used by default to find the control’s element, which filters only visible elements. That is useful filtering in a case when you have hidden HTML elements on a page and don’t want Atata to find and interact with hidden elements. But a drawback of such filtering is performance decrease, as each element visibility check is a separate WebDriver command request.
Ensure that you want this feature to be enabled for your website under test. If you have a lot of hidden/invisible HTML elements (for example, check grey HTML tags in browser developer tools) and you still want Atata to filter them out, you may consider disabling this feature. Right after the upgrade to Atata v2, run all your tests and check out the test failures. If there are not many failures because of elements visibility, and they can be solved by setting Visibility.Visible
to particular controls, then you are good to go with this feature. Otherwise, you can consider the ability to disable this feature globally.
Visible
by default globallyVisibility.Any
behavior can be easily reverted to the one with Visibility.Visible
filter that was in Atata v1 by one of the following ways:
UseDefaultControlVisibility
configuration method:
AtataContext.GlobalConfiguration.
UseDefaultControlVisibility(Visibility.Visible);
{
"defaultControlVisibility": "Visible"
}
Visible
to particular controlsFindAttribute
[FindBy("some-id")]
->
[FindBy("some-id", Visibility = Visibility.Visible)]
ControlDefinitionAttribute
[ControlDefinition("li")]
->
[ControlDefinition("li", Visibility = Visibility.Visible)]
FindSettingsAttribute
[FindSettings(OuterXPath = "./")]
->
[FindSettings(OuterXPath = "./", Visibility = Visibility.Visible)]
FindOnlyVisibleAttribute
[FindBy("some-id")]
public TextInput<_> Name { get; private set; }
->
[FindBy("some-id")]
[FindOnlyVisible]
public TextInput<_> Name { get; private set; }
You can also declare [FindOnlyVisible(TargetAllChildren = true)]
on page object or parent control to target it to all child controls.
var input = page.Find<TextInput<SomePage>>(new FindByNameAttribute("name1"));
->
var input = page.Find<TextInput<SomePage>>(new FindByNameAttribute("name1").Visible());
""
is returned instead of null
as value of string-based field componentIn Atata v1, when input or content field is empty, null
is returned as a value.
In Atata v2, an empty string is returned instead.
Take into account to change the assertions like:
SomeInput.Should.BeNull();
to:
SomeInput.Should.BeEmpty();
ComponentScopeLocateOptions
-> ComponentScopeFindOptions
ComponentScopeLocateResult
-> ComponentScopeFindResult
XPathComponentScopeLocateStrategy
-> XPathComponentScopeFindStrategy
FindAttribute.CreateStrategy()
-> FindAttribute.CreateStrategy(UIComponentMetadata metadata)
FindAttribute.BuildComponentName()
-> FindAttribute.BuildComponentName(UIComponentMetadata metadata)
AddLogConsumer(...)
-> LogConsumers.Add(...)
AddScreenshotConsumer(...)
-> ScreenshotConsumers.Add(...)
AddScreenshotFileSaving()
-> ScreenshotConsumers.AddFile()
LogConsumerInfo
-> LogConsumerConfiguration
AtataBuildingContext.LogConsumers
-> AtataBuildingContext.LogConsumerConfigurations
AtataContextInitEvent
-> AtataContextInitStartedEvent
DataProvider<TData, TOwner>
-> ValueProvider<TData, TOwner>
IDataProvider<out TData, out TOwner>
-> IObjectProvider<TData, TOwner>
UIComponent<TOwner>.GetOrCreateDataProvider<TValue>(providerName, valueGetFunction)
-> UIComponent<TOwner>.CreateValueProvider<TValue>(providerName, valueGetFunction)
UIComponent<TOwner>.CreateDataProvider<TValue>(providerName, valueGetFunction)
-> UIComponent<TOwner>.CreateValueProvider<TValue>(providerName, valueGetFunction)
IUIComponent<TOwner>.GetOrCreateDataProvider<TValue>(providerName, valueGetFunction)
-> UIComponent<TOwner>.CreateValueProvider<TValue>(providerName, valueGetFunction)
DataVerificationProvider<TData, TOwner>
-> ObjectVerificationProvider<TObject, TOwner>
IDataVerificationProvider<TData, TOwner>
-> IObjectVerificationProvider<TObject, TOwner>
IObjectProvider<TObject>.Value
-> IObjectProvider<TObject>.Object
IObjectProvider<TObject, TOwner>.IsValueDynamic
-> IObjectProvider<TObject, TOwner>.IsDynamic
IObjectSource<TObject>.Value
-> IObjectSource<TObject>.Object
EnumerableProvider<TItem, TOwner>
-> EnumerableValueProvider<TItem, TOwner>
[Wait(...)]
-> [WaitSeconds(...)]
ExtendedStringFormatter
-> AtataTemplateStringFormatter
ContentSource
values: FirstChildTextNode
, LastChildTextNode
and ChildTextNodesTrimmedAndSpaceJoined
""
instead of null
as value of string-based field componentTriggers
property of UIComponent<TOwner>
LogConsumerInfo
to LogConsumerConfiguration
DirectorySubject.Directories
property to SubdirectoriesProvider
DirectorySubject.Files
property to DirectoryFilesProvider
ExtendedStringFormatter
to AtataTemplateStringFormatter
ApplyMetadata
method from UIComponent
InitValueTermOptions
method with GetValueTermOptions
in Field<T, TOwner>
ValueTermOptions
property from IDataProvider<out TData, out TOwner>
and all classes implementing itTitleTermFormatter
to not lowercase “from” and “with”IPropertySettings
with IHasOptionalProperties
PropertyBag
UIComponentMetadata
parameter to CreateStrategy
and BuildComponentName
method of FindAttribute
Properties
property from MulticastAttribute
RemoteWebDriverLoggingExtensions
with IJavaScriptExecutorLoggingExtensions
RemoteWebDriver
usage with IWebDriver
WithCapability
method of DriverAtataContextBuilder<TBuilder, TService, TOptions>
with AddAdditionalBrowserOption
WithGlobalCapability
method of driver AtataContextBuilder
’s with AddAdditionalOption
AtataContext.ModeOfCurrent
property to AtataContextModeOfCurrent.AsyncLocal
WaitAttribute
to WaitSecondsAttribute
Component
property from IDataProvider<out TData, out TOwner>
IDataProvider<out TData, out TOwner>
with IObjectProvider<out TObject, out TOwner>
DataProvider<TData, TOwner>
and IDataProvider<TData, TOwner>
ControlList<TItem, TOwner>
from IEnumerableProvider<TItem, TOwner>
instead of IDataProvider<TData, TOwner>
DataVerificationProvider<TData, TOwner>
to ObjectVerificationProvider<TObject, TOwner>
Value
property of IObjectProvider<out TObject>
to Object
IsValueDynamic
property of IObjectProvider<out TObject, out TOwner>
to IsDynamic
Value
property of IObjectSource<out TObject>
to Object
EnumerableProvider<TItem, TOwner>
to EnumerableValueProvider<TItem, TOwner>
VerificationKind
property from IVerificationProvider<out TOwner>
IVerificationProvider<out TOwner>.GetRetryOptions
methodGetShouldText
method from IVerificationProvider<out TOwner>
ReportFailure
method from IVerificationProvider<out TOwner>
WithProperties
method of AtataContextBuilder<TContext>
to extension methodAtataContextBuilder
to new LogConsumersAtataContextBuilder
AtataContextBuilder
to new ScreenshotConsumersAtataContextBuilder
{build-start}
folder in AtataContext.Artifacts
directory path to yyyyMMddTHHmmss
FileScreenshotConsumer
and NLogFileConsumer
to use AtataContext.Artifacts
as a default DirectoryPathBuilder
Visible
to Any
AtataContextInitEvent
to AtataContextInitStartedEvent
Feel free to use any contact channel if you have problems with migration.