4

I have a close button on a ViewController that is being presented as a ChildViewController. I have this button's accessibility turned on and the accessibility identifier is closeButton. This button does not have any text, it just has an image.

I am attempting to test the presentation and dismissal of this view, but am running into an issue, the XCUITest cannot find the element. My test code is:

app.buttons["PresentChild"].tap()
XCTAssertTrue(app.otherElements["ChildViewController"].exists)
XCTAssertTrue(app.buttons["closeButton"].exists)

The first assert passes, but the second assert fails.

I tried to do the "Record UI Test" to select the button to have it be automatically generated, but then I just get an error saying Failed to find Matching Element. I tried erasing all the content on the simulator and deleting all derived data, and that didn't work either.

Does anyone know a workaround to this obvious bug in Xcode? I can't access the element through the recording, I can't access the element through the accessibility feature, I have zero idea how else to access this button.

scopchanov
  • 7,966
  • 10
  • 40
  • 68
  • 2
    Xcode takes a screenshot with every test failure. Go to the Test Navigator (`Cmd + 6`), right click on your failed test and choose **Jump to Report**. The very entry on the report should contain a screenshot that helps you understand the state of your application when it ran the second assert – Code Different Jun 18 '18 at 23:38
  • @CodeDifferent yeah, that didn't help much. Just confirmed that the close button was in fact displayed at the time of the XCTAssertTrue. –  Jun 19 '18 at 00:09
  • Is that Close button selectable by the user? Is there a semi-transparent view that covers the whole screen? Without seeing anything about your app, it's impossible to diagnose what the problem is. – Code Different Jun 19 '18 at 01:20
  • Yes, the button is selectable. No, there is not a view that covers the whole screen. If it helps, my view controller architecture goes `UITabBarController -> UINavigationViewController -> ParentViewController -> ChildViewController` The child view controller is added to the application by 1) adding the child's view via: `UIApplication.shared.keyWindow?.addSubview(childViewController.view)` and then 2) the child is moved to parent via: `childViewController.didMove(toParentViewController: parentViewController)` –  Jun 19 '18 at 15:26

1 Answers1

3

I don't know what is the exact problem with your assertion. But this steps may help you.

  • Put a breakpoint on this line XCTAssertTrue(app.otherElements["ChildViewController"].exists)
  • Now run the test case. When the control reaches this line, type this line in the debugger po XCUIApplication().buttons.debugDescription then tap the enter button
  • It will print all buttons in your current view. Now check whether the "closeButton" exists in that list
  • If it exists, check the identifier name. Make sure that it is "closeButton" (Identifier is case sensitive, also spaces in the identifiers matters)
  • If the identifier is right, try to find out the closeButton's exact view hierarchy. Means, instead of just checking like app.buttons["closeButton"].exists, try like app.navigationBars.otherElements["someName"].buttons["closeButton"].exists

(This seems funny, but giving the exact location path of the element is a good practice, and it will work sometimes)

Note: This error "Failed to find Matching Element" on UI recording will happen if the system can not locate the element with proper identifier while doing action on it. So my guess is, your closeButton does not have proper identifier or it is not added to the current window.

Cheers!!

Confused
  • 3,846
  • 7
  • 45
  • 72
  • I added a breakpoint in the test at that spot and did as you suggested. XCUITests is just simply not recognizing anything nested inside of the ChildViewController's main view. The hierarchy of the view controller goes: ViewController Scene --> View Controller --> View --> [Safe Area, TableView, Close Button]. I enabled the accessibility of the `view` and set the id as `ChildView`. When I debug this I first tried `po XCUIApplication().otherElements["ChildView"]` and it returned with some information. But if I append `.buttons` or `.tables` to that original command, nothing is found... –  Jun 20 '18 at 17:37