2

I'm having problems with EarlGrey's synchronization feature. I'm trying to create a simple test example for my app that basically checks if the login button shows up.

func testExample() {
    let success = GREYCondition(name: "Wait for action view controller", block: { () -> Bool in
        if let rootVC = UIApplication.shared.keyWindow?.rootViewController, rootVC is ValuePropsViewController {
            return true
        }
        else {
            return false
        }
    }).wait(withTimeout: 10)
    GREYAssertTrue(success, reason: "Action view controller should appear within 5 seconds")
    EarlGrey.select(elementWithMatcher: grey_accessibilityID("loginButton")).assert(grey_sufficientlyVisible())
}

However, it always times out and I get the following error message. I check the screenshots and the correct screen is showing at failure.

Exception Name: AssertionFailedException
Exception Reason: Timed out while waiting to perform assertion.
Exception with Assertion: {
  "Assertion Criteria" : "assertWithMatcher: matcherForSufficientlyVisible(>=0.750000)",
  "Element Matcher" : "(respondsToSelector(accessibilityIdentifier) && accessibilityID('loginButton'))"
}

Exception Details: Error Trace: [
  {
    "Description" : "Failed to execute block because idling resources below are busy.",
    "Description Glossary" :     {
      "animateWithDuration:delay:options:animations:completion:" : "<NSObject: 0x610000203a30> caused the App to be in busy state for 6.8 seconds.",
      "performSelector @selector(tick) on VAAppDelegate" : "Delayed performSelector caused the App to be in busy state for 2 seconds."
    },
    "Domain" : "com.google.earlgrey.GREYUIThreadExecutorErrorDomain",
    "Code" : "0",
    "File Name" : "GREYUIThreadExecutor.m",
    "Function Name" : "-[GREYUIThreadExecutor executeSyncWithTimeout:block:error:]",
    "Line" : "235",
    "TestCase Class" : "EarlGreyVidaTests.MyFirstEarlGreyTest",
    "TestCase Method" : "testExample"
  },
  {
    "Description" : "Failed to execute assertion within 30 seconds.",
    "Domain" : "com.google.earlgrey.ElementInteractionErrorDomain",
    "Code" : "4",
    "File Name" : "GREYElementInteraction.m",
    "Function Name" : "-[GREYElementInteraction assert:error:]",
    "Line" : "418",
    "TestCase Class" : "EarlGreyVidaTests.MyFirstEarlGreyTest",
    "TestCase Method" : "testExample"
  }
]

It works if I turn off synchronization:

GREYConfiguration.sharedInstance().setValue(false, forConfigKey: kGREYConfigKeySynchronizationEnabled)

Is there something I'm doing wrong? All my tests seem to work well with synchronization off. Should I keep it off?

Lee Kang
  • 729
  • 9
  • 19

1 Answers1

10

You shouldn't turn the synchronization off - that's what makes EarlGrey EarlGrey, and makes your tests stable and useful.

However, it looks like you have some animations or delayed performSelector that EarlGrey is tracking to make it always think your app is busy. one thing you can tweak is, if you look at the header, GREYConfiguration.h, you can find various config variables you may change according to your app's behaviour.

Disclaimer: I am part of EarlGrey's team.

Hao
  • 161
  • 2
  • 5
  • thanks! I had a never ending performSelector in my appdelegate – Lee Kang Mar 13 '17 at 23:27
  • @LeeKang if your performSelector is scheduled every X seconds, you can decrease the threshold to X - 1 seconds so it will not be tracked, kGREYConfigKeyDelayedPerformMaxTrackableDuration – Hao Mar 14 '17 at 16:53
  • I had an issue similar to that! In my case I have a Timer scheduled to run a selector on a time interval of 0.3, I tried to set kGREYConfigKeyDelayedPerformMaxTrackableDuration to 0.2 or even 0.0 as suggested but the test still failed with "Failed to execute block because idling resources below are busy." description. In the end, I had to turn the synchronization off just for the specific test. – thacilima Sep 27 '19 at 11:24