onmyway133 / blog

🍁 What you don't know is what you haven't learned
https://onmyway133.com/
MIT License
669 stars 33 forks source link

How to deal with animation in UITests in iOS #143

Open onmyway133 opened 6 years ago

onmyway133 commented 6 years ago

Today I was writing tests and get this error related to app idle

    t =    23.06s         Assertion Failure: <unknown>:0: Failed to scroll to visible (by AX action) Button, 0x6000003827d0, traits: 8858370049, label: 'cart', error: Error -25204 performing AXAction 2003 on element <XCAccessibilityElement: 0x7fc391a2bd60> pid: 91461, elementOrHash.elementID: 140658975676048.128

It turns out that the project uses a HUD that is performing some progress animation. Even it was being called HUD.hide(), the problem still exists.

   t =    31.55s     Wait for no.example.MyApp to idle
    t =    91.69s         App animations complete notification not received, will attempt to continue.
    t =    91.70s Tap Target Application 0x6040002a1260
    t =    91.70s     Wait for no.example.MyApp to id

No matter how I call sleep,wait`, still the problem

sleep(10)
app.tap()
_ = checkoutButton.waitForExistence(timeout: 10)

The fix is to disable animation. Start with setting argument when running tests

app.launchArguments.append("--UITests")
app.launch

Then in AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  if CommandLine.arguments.contains("--UITests") {
    UIView.setAnimationsEnabled(false)
  }
}
Jsayer7 commented 5 years ago

I can't seem to get this to work in Xcode 9.4.1.. Am I missing something here?

tmaly1980 commented 5 years ago

@onmyway133 My AppDelegate is in ObjC, so I'm not sure what I'd do:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

  NSURL *jsCodeLocation;

  #ifdef DEBUG
      jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; // works in both simulator AND connected phone on network via IP
  #else
      jsCodeLocation = [CodePush bundleURL];
  #endif
    //jsCodeLocation = [CodePush bundleURL];
    // jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Pushkah"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--UITests"]) {
    // DISABLE SOMEHOW?

  } else {
    printf("oops, animtions STILL GOING!!!!!!!!!!!!! =(");
  }

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;

  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  return YES;
}