XCTest wait for elements using expectations & NSPredicate
--
A good XCUITest is written without Thread.sleep.
XCUITest shouldn’t wait for an element(s) blindly for fixed amount of time especially when appearance of the elements is dependent on network calls.
XCTestExpectation
NSObject perfectly solves this problem. Let’s go over an example on how to use this method. Before, we create XCTestExpectation
NSObject, we first need to define predicate
Here’s an example:
line 1: We’re creating a NSPredicate class with format
to create predicate from a string.
line 2: We’re creating a staticText XCUIElement with label/accessibilityIdentifier as “confirmationNumberLabel”
line 3: We’re setting an expectation in XCTestCase. In easy word, we are telling XCTestCase that we expect you to check if confirmationNumberLabel meets condition as defined in predicate. If condition is met, returns true otherwise false.
line 4: waitForExpectations(timeout:handler:)
method of XCTestCase
class waits until expectations are fulfilled or if timeout
(in seconds) has reached.
Here are some examples to creating predicates:
Example #1 — Predicate where label is equal to a string
app.staticTexts.containing(NSPredicate(format: “label == ‘Confirmation Number #:’”))
Example #2 — Predicate where label contains a string
app.staticTexts.containing(NSPredicate(format: "label CONTAINS 'Confirmation'"))
Example #3 — Predicate where label contains string which is case-insensitive.
app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] %@", "conf"))
Example #4 — Predicate where label matches a Regex.
app.staticTexts.containing(NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z]"))
Example #5 — Predicate where label begins a specific substring
app.staticTexts.containing(NSPredicate(format: "label BEGINSWITH %@", "C"))
Example #6 — Predicate where label ends a specific substring
app.staticTexts.containing(NSPredicate(format: "label ENDSWITH %@", "N"))
Let’s look at another example of XCTestExpectation
but with handler
usage. XCWaitCompletionHandler
code block is invoked when all expectations have been fulfilled or when the wait timeout is triggered.
Thank you for reading..