xctestearlgrey

In EarlGrey, what's the non-polling way to wait for an element to appear?


Currently I wait for an element to appear like this:

let populated = GREYCondition(name: "Wait for UICollectionView to populate", block: { _ in
    var errorOrNil: NSError?

    EarlGrey().selectElementWithMatcher(collectionViewMatcher)
              .assertWithMatcher(grey_notNil(), error: &errorOrNil)

    let success = (errorOrNil == nil)
    return success
}).waitWithTimeout(20.0)

GREYAssertTrue(populated, reason: "Failed to populate UICollectionView in 20 seconds")

Which polls constantly for 20 seconds for collection view to populate. Is there a better, non-polling way of achieving this?


Solution

  • EarlGrey recommends using its synchronization for waiting for elements rather than using sleeps or conditional checks like waits wherever possible.

    EarlGrey has a variable kGREYConfigKeyInteractionTimeoutDuration value in GREYConfiguration that is set to 30 seconds and states -

     *  Configuration that holds timeout duration (in seconds) for action and assertions. Actions or
     *  assertions that are not scheduled within this time will fail due to timeout.
    

    Since you're waiting for 20 seconds for your check, you can instead simply change it to -

    EarlGrey().selectElementWithMatcher(collectionViewMatcher)
              .assertWithMatcher(grey_notNil(), error: &errorOrNil)
    

    and it'll be populated without a timeout.