Atata 0.13.0 Released

June 27, 2017 by Yevgeniy Shunevych


Atata 0.13.0 has been released. Check the changelog and major features.

Changelog

Breaking Changes

  • break #50 Change default search of controls
  • break #55 Change TermCase.Title and add TermCase.Capitalized

New

  • minor #23 Add TraceLogAttribute
  • minor #26 Add SetRandom extension method for EditableField`2 with nullable data type
  • minor #27 Add support of RandomizeIncludeAttribute to string and number EditableField`2 controls
  • major #29 OuterXPath functionality
  • minor #30 Add Metadata to ControlList`2
  • minor #34 Add ComponentSize property to UIComponent`1
  • minor #35 Add ComponentLocation property to UIComponent`1
  • major #37 Add HierarchicalControl`2 and HierarchicalItem`2 controls
  • major #40 Add MulticastAttribute
  • major #43 Add Resolve method to UIComponentChildrenList`1
  • major #44 Add controls for hierarchical lists
  • minor #45 Add attribute properties to UIComponentAttributeProvider`1
  • major #46 Add ContentSourceAttribute
  • minor #48 Bool randomization
  • minor #49 Assertion exception type configuration
  • major #51 Add DragAndDropTo methods to Control`1
  • major #52 Behaviors for drag and drop
  • minor #54 Add Press method to PageObject`1

Changes

  • minor #24 Make UIComponent.Scope property public
  • minor #28 Update ILogManager error logging methods
  • minor #32 Set "./" OuterXPath to items of UnorderedList`2 and OrderedList`2
  • minor #36 Add IsVisible and Triggers properties to IUIComponent`1
  • minor #41 Inherit FindSettingsAttribute from MulticastAttribute
  • minor #47 Add indexers to ItemsControl`2
  • minor #53 Change log messages for AtataContext setup

Fixes

  • fix #31 Component attributes of inherited control type does not apply to sub-components of base type
  • fix #33 FindByCssStrategy throws exception in safely mode
  • fix #42 ControlType and ParentComponentType properties of ControlFindingAttribute doesn’t handle non-generic types

Hierarchical Controls

Added base HierarchicalControl<TItem, TOwner> and HierarchicalItem<TItem, TOwner> controls for interaction with structured HTML elements, like hierarchical ul/li trees, menus or other tree views.

Added specific controls for structured ul/li and ol/li lists:

  • HierarchicalUnorderedList<TItem, TOwner>
  • HierarchicalOrderedList<TItem, TOwner>
  • HierarchicalListItem<TItem, TOwner>
  • HierarchicalListItem<TOwner>

Example

HTML

<ul id="some-tree">
    <li>
        <span>Item 1</span>
        <ul>
            <li>
                <span>Item 1.1</span>
            <li>
                <span>Item 1.2</span>
            </li>
        </ul>
    </li>
    ...
</ul>
  • Item 1
    • Item 1.1
    • Item 1.2
  • Item 2
    • Item 2.1
      • Item 2.1.1
      • Item 2.1.2
    • Item 2.2

Page Object

using Atata;

namespace SampleApp.Tests
{
    using _ = TreePage;

    [Url("TreePage.html")]
    public class TreePage : Page<_>
    {
        [FindById("some-tree")]
        public HierarchicalUnorderedList<TreeItem, _> Tree { get; private set; }

        public class TreeItem : HierarchicalListItem<TreeItem, _>
        {
            [FindByXPath("./span[1]")]
            public Text<_> Name { get; private set; }
        }
    }
}

Test

Go.To<TreePage>().
    Tree.Children.Count.Should.Equal(2).
    Tree.Descendants.Count.Should.Equal(8).
    Tree[x => x.Name == "Item 1"][x => x.Name == "Item 1.1"].Should.Exist().
    Tree.Descendants.Should.Contain(x => x.Name == "Item 2.1.1").
    Tree[1][0][1].Name.Should.Equal("Item 2.1.2").
    Tree.Descendants.SelectData(x => x.Name).Should.Contain("Item 1.1", "Item 2.1", "Item 2.2");

Drag and Drop

Added the following methods to Control<TOwner>:

public TOwner DragAndDropTo(Func<TOwner, Control<TOwner>> targetSelector);

public TOwner DragAndDropTo(Control<TOwner> target);

public TOwner DragAndDropToOffset(int offsetX, int offsetY);

Example

Page Object

namespace SampleApp.Tests
{
    using _ = DragAndDropPage;

    [Url("DragAndDrop.html")]
    public class DragAndDropPage : Page<_>
    {
        [FindById]
        public ItemsControl<DragItem, _> DropContainer { get; private set; }

        [FindById]
        public ItemsControl<DragItem, _> DragItems { get; private set; }

        [ControlDefinition("span", ContainingClass = "drag-item")]
        public class DragItem : Control<_>
        {
        }
    }
}

Test

Go.To<DragAndDropPage>().
    DropContainer.Items.Should.BeEmpty().
    DragItems.Items.Should.HaveCount(2).
    DragItems[x => x.Content == "Drag item 1"].DragAndDropTo(x => x.DropContainer).
    DragItems[0].DragAndDropTo(x => x.DropContainer).
    DropContainer.Items.Should.HaveCount(2).
    DragItems.Items.Should.BeEmpty().
    DropContainer[1].Content.Should.Equal("Drag item 2");

Behaviors

See #52 Behaviors for drag and drop for customizing behavior of drag and drop. For example, in current Chrome and PhantomJS versions the default behavior can fail. So you can use DragAndDropUsingDomEventsAttribute to bypass that.

OuterXPath

Implemented functionality to set extra pre-XPath for control search. By default “.//” XPath is used as OuterXPath.

Examples

To find a control as a direct child of parent:

[FindSettings(OuterXPath = "./")]

Or:

[FindFirst(OuterXPath = "./")]

To find a first following sibling element:

[FindFirst(OuterXPath = "following-sibling::")]

To find element by class that is a direct child of some container:

[FindByClass("some-class", OuterXPath = ".//div[@id='some-container']/")]

ContentSourceAttribute

ContentSourceAttribute - specifies the content source of a component. It is used in UIComponent<TOwner> for Content property; and in Content<T, TOwner> control for value. ContentSourceAttribute is inherited from MulticastAttribute.

Can use one of the following ContentSource enum values:

  • Text - uses Text property of component scope IWebElement element.
  • TextContent - uses ‘textContent’ attribute of component scope IWebElement element.
  • InnerHtml - uses ‘innerHTML’ attribute of component scope IWebElement element.
  • Value - uses ‘value’ attribute of component scope IWebElement element.

Also can accept a name of attribute from which the value should be taken.

Examples

To get content of a hidden element:

[FindById("some-id", Visibility = Visibility.Any)]
[ContentSource(ContentSource.TextContent)]
public Text<_> HiddenDivUsingTextContent { get; private set; }

To get attribute value of element:

[FindById]
[ContentSource("data-id")]
public Content<int, _> ElementHavingDataId { get; private set; }

Multicast Attributes

MulticastAttribute - represents the base class for attributes that can be applied to component at any level (declared, parent component, assembly, global and component). It provides the following properties:

  • string[] TargetNames
  • string TargetName
  • Type[] TargetTypes
  • Type TargetType
  • Type[] TargetParentTypes
  • Type TargetParentType

Now using Metadata.Get<SomeMulticastAttribute>(AttributeLevels.All) will filter by target and return the most suitable attribute.

Attributes, inherited from MulticastAttribute, in this release are: FindSettingsAttribute, ContentSourceAttribute and DragAndDropBehaviorAttribute.

Lazy Initialization of Controls

Added method to UIComponentChildrenList<TOwner>:

public TControl Resolve<TControl>(string propertyName, Func<IEnumerable<Attribute>> additionalAttributesFactory = null);

It can be used for lazy initialization of controls:

public Control<_> SomeControl => Controls.Resolve<Control<_>>(nameof(SomeControl));