UIAutomation and XCTestCase: how to wait for a button to activate
Asked Answered
M

4

8

I'm writing a UIAutomation test case and I need to wait for the user to be activated before continuing. There doesn't seem to be a nice way to check for a button to change to the enabled state.

Whats the best was to wait for something to happen in the UI before checking it's status?

Neither dispatch_after nor NSTimer seem to work. They just block then fail.

Morea answered 8/7, 2015 at 18:7 Comment(0)
D
17

It's actually pretty easy if you use NSPredicates and expectations. You can even set a timeout value. This example shows you how to do it with a 5 second timeout.

let exists = NSPredicate(format:"enabled == true")
expectationForPredicate(exists, evaluatedWithObject: app.tables.textFields["MY_FIELD_NAME"], handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)
Demantoid answered 16/10, 2015 at 0:35 Comment(0)
C
0

The better way to wait and check an element isn't the delay() function, but the pushTimeout() one. Apple recommends to use the second function. Here is a code sample:

UIATarget.localTarget().pushTimeout(10)
button.tap()
UIATarget.localTarget().popTimeout()

Apple will repeatedly try to tap the button and will wait up to 10 seconds. Here's a link to the documentation.

Crenulate answered 18/9, 2015 at 11:18 Comment(0)
M
0

Etienne's answer is correct but in my scenario it required something extra.

I'm using React Native and had a <TouchableWithoutFeedback disabled={true}> component. However I could see that whenever XCUI tried to check its state it considered it enabled. Indeed, using a breakpoint and checking element.IsEnabled clearly contradicted what I was seeing in the UI.

Using AccessibilityState will achieve this however, for example:

<TouchableWithoutFeedback
   accessibilityState={{
      disabled: this.props.disabled,
   }}
>

Experienced with RN 0.62.2

Mandal answered 28/7, 2020 at 20:35 Comment(0)
R
-4

You should be able to implement a while loop to check for the condition you want (e.g. button enabled). That will stop the test case progress until the while condition is met and the tests will continue. Build in a delay to slow polling and make sure you have a timeout so you don't get stuck indefinitely.

Pseudocode:

While (/*button is disabled*/) {
    if (/*timeout condition met*/) {
        /*handle error*/
        break;
    }

    UIATarget.delay(<duration in seconds>);
}
Regionalism answered 8/7, 2015 at 18:30 Comment(6)
Thanks! I did't know about the delay function.Morea
Hmm actually I can't find UITarget.delay anywhere.Morea
Sorry it's UIATarget. Corrected in answer. developer.apple.com/library/ios/documentation/ToolsLanguages/…Regionalism
@Zaph0d42 If you found my answer efficient and helpful, please select it as your accepted answer. Thanks!Regionalism
Hey Murdock. Thanks for the help. UIATarget is part of the Javascript UITesting from Xcode 6. I should have made it clear that I was using the new UIAutomation that is part of the XCTest framework in Xcode 7. There isn't a delay function there AFAICT. So I don't think that it's the correct answer.Morea
This is a very manual way of doing it. You can actually do it using build in features. See NSPredecate and look up for Expectations work.Demantoid

© 2022 - 2024 — McMap. All rights reserved.