UI Testing - Wait for Element to Exist

Experimenting with a UI test that was recorded for the Logon screen in our app. The test runs fine when stepping through in the debugger.


When running in real time the logon step takes longer than the app waits for idle to finish.


Is there a step that can be used to wait for an element on the next screen to exist?


Something similar to this step in calabash - wait_for_element_exists(element_query, options = {})


Whats the best practice approach for solving this problem with the new UI Testing capability?

Excellent question, I would love to know the best practice around this as well.


For now, as ugly as it is, I am hard-coding a "wait" while background activity occurs. I do this by pressing my HUD (activity indicator) for a certain number of seconds via

XCUIApplication *app = [[UIApplication alloc] init];
[app launch];
[app.buttons[@"HUD"] pressForDuration:2.0f];


This is obviously not sutainable. Any time there is a longer than two second network request the test will fail making this very brittle.


All other suggestions are welcome.

Hi Steve - your question inspired me to throw together an XCTestCase category method that functions as you described. You can check it out here:


https://github.com/daniel-hall/DHTestingAdditions/blob/master/DHTestingAdditions/XCTestCase%2BDHTestingAdditions.m


Using it is as simple as adding a line inside your test method like this:


[self waitUntilElementExists:someElement withTimeout:5.0f];
[someElement tap]; //<-- This is guaranteed not to run unless / until 'someElement' actually exists and is reachable.

This method works by running the run loop as long as the element provided does not exist yet, and will only proceed to the next line of your test when the specified element either exists, or the timeout interval expires (which will fail the test).


Hope it's helpful!

This is awesome, Daniel, great addition!


I did a post on UI Testing in Xcode 7 - I'll make sure to add this awesome snippet.


P.S. Where did you learn about CFRunLoopRunInMode? I've never heard of ticking the run loop that way.

I solved similar problem by sending a `tap` event to an element. It looks like the UI test waits for the element to appear before proceeding with the rest of the test.


Here is a similar question I asked on Stackoverflow.


http://stackoverflow.com/questions/31261286/how-to-check-for-the-presence-of-static-text-displayed-from-the-network-in-ui-te

also worth considering how you can limit how long of a delay you have. Users wont generally enjoy waiting for more then a few seconds (likely the reason for how long the timeout is set at).

For those who come across this thread like I did there's been an update with beta 4.


https://twitter.com/joar_at_work/status/623716723787587585


Haven't tried it yet though

It works! Here's a quick example:


XCUIElement *label = self.app.staticTexts[@"Hello, world!"]; 
NSPredicate *exists = [NSPredicate predicateWithFormat:@"exists == 1"]; 

[self expectationForPredicate:exists evaluatedWithObject:label handler:nil]; 
[self waitForExpectationsWithTimeout:5 handler:nil];


Here we create a query to wait for a label with text "Hello, world!" to appear. The predicate matches when the element exists (

element.exists == YES
).


We then pass the predicate in while and evaluate it on the label. Finally, we kick off the waiting game with -

waitForExpectationsWithTimeout:handler:
.


If five seconds pass before the expectation is met then the test will fai. You can also attach a handler block in that gets called when the expectation fails or times out.

Are there any facilities using the new concurrency primitives to improve this syntax?

Hello all,

Engineer on the XCTest team here. joemasilotti's answer above is correct, but the fastest way to achieve this is probably to use the XCUIElement.waitForExistence(timeout:) method:

https://developer.apple.com/documentation/xctest/xcuielement/2879412-waitforexistence

This method is synchronous, but should achieve what you are trying to do. Will keep an eye on this thread for other feedback.

UI Testing - Wait for Element to Exist
 
 
Q