Search code examples
xamarin.iosios-ui-automationxamarin.uitest

Xamarin.UITest: How to select a next element of the current node


Is there any way to select a next element of the current node using Xamarin.UITest.Queries.AppQuery?

Here is a REPL source:

[CalabashRootView > ... > UIView]                                              
  [UILabel]
  [UIButton] label: "arrow prev"
    [UIImageView] id: "arrow-prev.png"
  [iLobby_iOS_Controls_UIAnimatedButtonView]
  [UILabel] label: "Tell us about yourself",  text: "Tell us about yourself"
  [UILabel] label: "FIRST AND LAST NAME",  text: "FIRST AND LAST NAME"
  [UILabel] label: "*",  text: "*"
  [UITextField]
    [UIImageView]
    [_UITextFieldContentView]
    [UIAccessibilityTextFieldElement]
  [UILabel] label: "COMPANY",  text: "COMPANY"
  [UITextField]
    [UIImageView]
    [_UITextFieldContentView]
    [UIAccessibilityTextFieldElement]

The challenge is select UITextField element next to UILabel

I looking for a similar way like xPath do. In my case it would look like:

//UILabel[@text='FIRST AND LAST NAME']/following::UITextField

Any Idea? Our app is written in Xamarin.iOS (no Xamarin.Forms).


Solution

  • Explanation

    The best way to identify UI controls with Xamarin.UITest is to assign a unique identifier to each control in the source code of the app.

    In Xamarin.iOS, we can assign the AccessibilityIdentifier property in our apps' source code, then reference it using x => x.Marked in Xamarin.UITest.

    Setting the AccessibilityIdentifier, Xamarin.iOS

    There are a few ways to set the AccessibilityIdentifier in Xamarin.iOS.

    Each way accomplishes the same result. Use whichever method works best for your current code base.

    For this example, I am setting the AccessibilityIdentifier to FirstAndLastNameLabel for my UILabel.

    1. Storyboards, Visual Studio (Mac)

    enter image description here

    2. Storyboards, Xcode

    enter image description here

    3. In Code

    var firstAndLastNameLabel = new UILabel
    {
        AccessibilityIdentifier = "FirstAndLastNameLabel"
    };
    

    Referencing Unique Identifier in Xamarin.UITest

    After we've created a unique identifier for each UI control, we can then reference it in Xamarin.UITest using x => x.Marked;

    readonly System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery> firstAndLastNameLabelQuery = x => x.Marked("FirstAndLastNameLabel");
    
    public string GetFirstAndLastNameLabelText()
    {
        var label = app.Query(firstAndLastNameLabelQuery)?.FirstOrDefault();
        return label?.Text ?? string.Empty;
    }
    

    Additional Information

    Using Marked in Xamarin.UITest

    https://learn.microsoft.com/appcenter/test-cloud/uitest/#using-marked-to-locate-views

    AccessibilityIdentifier API

    An identifier can be used to uniquely identify an element in the scripts you write using the UI Automation interfaces

    https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier?language=objc