Search code examples
iosswifttestingxctestxcode-ui-testing

XCTestCase: Can't press custom bar button in navigation bar


I'm writing a test for an iOS application and I can't manage to click on a custom bar button. It is a bar button with a UIImageView inside. The image has an accessibilityIdentifier = "settingsBarImage" and the bar button has an accessibilityIdentifier = "settingsBarButton"

When I print the widget tree with print(app.debugDescription) the button exists and is hittable.

NavigationBar, 0x60000320b480, {{0.0, 44.0}, {375.0, 44.0}}, identifier: 'Overview'
     Button, 0x60000320b560, {{16.0, 51.0}, {30.0, 30.0}}, identifier: 'settingsBarButton', label: 'Your profile picture.'
     StaticText, 0x60000320b640, {{150.0, 55.7}, {75.0, 20.3}}, label: 'Overview'

I've tried:

app.navigationBars.button.firstMatch.tap()

app.navigationBars["Overview"].buttons["settingsBarButton"].tap()

app.buttons["settingsBarButton"].tap()

app.otherElement["settingsBarButton"].tap()

and every combination thereof.

And the result is always the same:

t =    14.74s Tap Button
t =    14.74s     Wait for com.sap.mobile.apps.ProjectCompanion to idle
t =    14.77s     Find the Button
t =    15.82s         Find the Button (retry 1)
t =    16.87s         Find the Button (retry 2)
t =    16.92s         Collecting extra data to assist test failure triage
t =    16.92s             Requesting snapshot of accessibility hierarchy for app with pid 89909
t =    16.95s             Requesting snapshot of accessibility hierarchy for app with pid 89909
t =    17.06s         Assertion Failure: OverviewScreenBase.swift:31: Failed to get matching snapshot: No matches found for first query match sequence: `Descendants matching type NavigationBar` -> `Descendants matching type Button`, given input App element pid: 89909 (no attribute values faulted in)
Possibly caused by runtime issues:

If anybody has experienced this issue, I would be very grateful.

Best regards, Chicken

Edit: After more experimenting, I have more information. When the settingsBarButton is created by running the application normally, isAccessibilityElement is returning true, but during a test, it returns false.


Solution

  • Maybe test if the button is actually working or if the test is failing correctly. If the button is working and the test is still failing then maybe you're targeting the wrong element. One thing you can try is trying to directly tap the element:

    app.buttons["settingsBarButton"].tap()
    

    If that also doesn't work, try:

    if app.otherElements["settingsBarButton"].exists {
        app.otherElements["settingsBarButton"].tap()
    }
    

    Also, it is possible that due to the page being loaded the element has not yet appeared. In this case, you can try to wait for the element to be loaded,

    let settingButton = app.buttons["settingsBarButton"]
    let predicate = NSPredicate(format: "exists == true")
    let theExpectation = expectation(for: predicate, evaluatedWith: settingButton, handler: nil)
    _ = XCTWaiter().wait(for: [theExpectation], timeout: 5)
    if settingButton.exists {
        settingButton.tap()
    }
    

    If the test is still failing, maybe it is not a test issue and the button tap is actually not working. So make sure to check your code as well.