I'm trying to create a tree walker using XCode 7's XCTest UI testing functionality that systematically explores a deterministic tree of table views to a specified depth. It almost works, except that I cannot reliably detect whether or not the tap on any given element has actually triggered a transition to a new screen. I have a hacky method that works most of the time, which is to detect that either the nav bar label has changed OR that the number of menu elements has changed.
The first test has false negatives, because successive screens can have identical nav bar labels (the codebase I'm walking is not mine). The second test has false positives, because sometimes clicking on a table element does not transition to another table/screen but instead adds extra elements to the current screen.
After doing some reading, it seemed that using accessibility labels might be the way to go. So I set a UID for the nav bar's accessibility label in the application code (in viewDidAppear) and then test for it in the UI test code. It feels like this ought to work, but I only ever get back a value of nil in the test code.
I will freely confess that I am a noob when it comes to UI testing and am mainly cutting/pasting/adapting other people's code without having a clear understanding of what I'm doing. So I'm probably making some kind of naive blunder, in the accessibility label code itself and possibly at the conceptual level for detecting that the screen has changed; maybe there's something much simpler/more idiomatic I could be doing.
In the application:
- (void)viewDidAppear: (BOOL)animated {
[super viewDidAppear: animated];
//...
UINavigationBar* navBar = self.navigationController.navigationBar;
if( navBar )
{
static NSInteger s_UID = 0;
navBar.topItem.accessibilityLabel = [NSString stringWithFormat:@"UID-%ld", s_UID++];
}
}
In the XCTest UI test:
- (NSString*) navBarAccessibilityLabel: (XCUIApplication*) app
{
NSString* result = NULL;
XCUIElementQuery *navBars = app.navigationBars;
XCUIElement* firstElem = [navBars.staticTexts elementBoundByIndex:0];
if( firstElem )
{
result = (NSString*)firstElem.accessibilityLabel; // This is always nil
}
return result;
}
Note that firstElem IS found, and that I am able to extract e.g. firstElem.label from it very happily.
Any help appreciated.