4

I'm beginning to experiment with EarlGrey a little bit, having done UI Testing using the XCUITest for some months now. I'm running into the classic problem of being unable to dismiss system alerts, which is strange as it looks as though Google implemented a matcher for system alerts called grey_systemAlertViewShown(). I'm trying to detect system alerts using GREYCondition. Here's what I've tried:

    - (void)waitForAndDismissSystemAlertForSeconds:(NSInteger)seconds {
    GREYCondition *interactableCondition = [GREYCondition conditionWithName:@"isInteractable" block:^BOOL{
        // Fails if element is not interactable
        NSError *error;
        [[EarlGrey selectElementWithMatcher:grey_systemAlertViewShown()] assertWithMatcher:grey_interactable() error:&error];

        if (error) {
            return NO;
        } else {
            NSError *allowButtonError;
            [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Allow")] assertWithMatcher:grey_notNil() error:&allowButtonError];
            if (!allowButtonError) {
                [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Allow")] performAction:grey_tap()];
               }

        return YES;
    }];

    [interactableCondition waitWithTimeout:seconds];
}

I've also tried using addUIInterruptionMonitorWithDescription as described here (but using EarlGrey code to do basically what I am doing above in the interruption monitors): Xcode 7 UI Testing: how to dismiss a series of system alerts in code

Neither approach works. Breakpoints don't fire for the non-error case in my GREYCondition, and the interruption monitor doesn't dismiss my alert either.

Does anybody know if EarlGrey supports dismissing system alerts?

Community
  • 1
  • 1
Jonathan Chen
  • 716
  • 8
  • 19

4 Answers4

5

As the docs for grey_systemAlertViewShown indicate, grey_systemAlertViewShown merely checks to see if system alert views are shown. A better usage of the API would be to assert that system alert is not shown (maybe because the test app has mocked out the code that causes system alerts).

Code that taps a button that requests causes system alert to be shown (for ex: requests user's geo location) comes here...
// Assert that in the test app system alert view is not shown because we have mocked out the part of code that requests user location.
[[EarlGrey selectElementWithMatcher:grey_anything()] assertWithMatcher:grey_not(grey_systemAlertViewShown())];

As of this writing system alert views cannot be dismissed by EarlGrey. Alertviews that are launched by the app can be dismissed. The FAQ has a question that indicates that EarlGrey tests will fail if modal dialogs are present.

Gautam
  • 286
  • 1
  • 3
  • Thanks for your reply, @Gautam. I read in the known issues section: "We plan to implement this in the EarlGrey APIs, but in the meantime we recommend that you use other means to dismiss system permission dialogs in your test code." Do you know what "other means" this is referring to? And as a partially related question, do you know if it's possible to integrate EarlGrey with XCode's XCUITest framework? It was possible for me to dismiss system alerts this way. – Jonathan Chen Feb 25 '16 at 17:00
  • 1
    You should probably ask that on their Google Group or create a new issue on the Github page. https://groups.google.com/forum/#!forum/earlgrey-discuss – gran_profaci Mar 19 '16 at 00:07
  • @Guatam - did you check how "Alertviews that are launched by the app can be dismissed"? I mean, other than using preset flag for EarlGrey testing and automatically dismissing alert (or not showing it at all)? – Wladek Surala Mar 23 '17 at 17:09
  • 1
    @WladekSurala please see [this test](https://github.com/google/EarlGrey/blob/master/Tests/FunctionalTests/Sources/FTRAlertViewTest.m#L29) in the EarlGrey test app tests where an in app alert [is shown](https://github.com/google/EarlGrey/blob/master/Tests/FunctionalTests/TestRig/Sources/FTRAlertViewController.m#L49) and then dismissed. – Gautam Mar 24 '17 at 17:42
2

The best way we found to get around this was to include a launch argument for testing, in which we wouldn't register the app for notifications.

Something like:

if [[[NSProcessInfo processInfo] arguments] containsObject:argument] { return; }

before you call

[[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications];

This way, the "Do you want to allow push notifications..." alert won't show.

ArielSD
  • 829
  • 10
  • 27
1

It is possible to grant all the required permissions using AppleSimulatorUtils util.

This approach eliminates the need to dismiss alerts and saves time.

Install an util by entering next commands in the Terminal app

brew tap wix/brew

brew install applesimutils

And grant permission(s) with

applesimutils --byId <simulator UDID> --bundle <bundle identifier> --setPermissions "notifications=YES"


For more info and examples please refer to

https://github.com/wix/AppleSimulatorUtils

Roman Zakharov
  • 2,185
  • 8
  • 19
0

EarlGreyImpl.invoked(fromFile: #file, lineNumber: #line).selectElement(with: grey_text("Click")).perform(grey_tap())

//use above code it might work for your problem