leancodepl / patrol

Flutter-first UI testing framework. Ready for action!
https://patrol.leancode.co
Apache License 2.0
917 stars 142 forks source link

ASWebAuthenticationSession permission dialog #485

Closed wferem1 closed 1 year ago

wferem1 commented 2 years ago

I have a flutter app which redirect the user to an SSO page to login. on iOS this starts an ASWebAuthenticationSession or SFAuthenticationSession (depending on the iOS version) which shows a dialog as follows: image

I tried tapping the Continue button, or call $.native.grantPermissionWhenInUse to allow the permissions, but it seems that this is not a permission dialog (none is found) and tapping with Selector(text: 'Continue') returns with code NOT_FOUND.

Is there any way to have the PatrolTester approve/cancel this request?

bartekpacia commented 2 years ago

Hi @wferem1! Thanks for creating the issue :)

You were thinking good to use $.native.tap(Selector(text: 'Continue')). Just one more thing: on iOS, you need to specify the appId of the app you're interacting with. All system dialogs on iOS are owned by the Springboard app (its bundleID is com.apple.springboard).

So try doing this:

await $.native.tap(
  Selector(text: 'Continue'),
  appId: 'com.apple.springboard',
);

Let me know if this helped!

I should probably add info to docs about this.

wferem1 commented 2 years ago

Hi @bartekpacia! That indeed did the trick, thanks for explaining!

wferem1 commented 2 years ago

I have another question, i can't seem to enter text in the textfields on the webview shown after i tap continue.

bitmap

on Android this worked by calling $.native.enterText(Selector(text: 'Email address'), 'some-text') but on iOS this does not seem to work. I tried it with my bundle id, the springboard id and safari's id (com.apple.mobilesafari) but none of them seem to work (nothing is found)

bartekpacia commented 2 years ago

I don't know the solution to your problem – I haven't encountered this case myself yet πŸ˜…

Please try listing all bundle identifiers present on the Simulator:

$ xcrun simctl listapps booted

and see if anything looks interesting and try. Unfortunately, there's no better way to find out.

Good luck and let me know if this helped. If not, we'll think of a different solution :)

bartekpacia commented 2 years ago

Maybe com.apple.webapp?

bartekpacia commented 2 years ago

Also, try using enterTextByIndex() instead of enterText() – it's a bit more reliable.

So:

await $.native.enterTextByIndex('wferem1@gmail.com', index: 0, appId: `IDK`);
await $.native.enterTextByIndex('NyanCar', index: 1, appId: `IDK`);

Replace IDK with your appId (the default if you're passing PatrolTestConfig to patrolTest()), MobileSafari, and Springboard (though I doubt it's gonna be Springboard).

Curosevic commented 2 years ago

Also facing this issue. I've tried index but I keep getting NOT_FOUND text field at index doesn't exist. And when I try enterText it never seems to find the field.

bartekpacia commented 2 years ago

Hi @Curosevic, sorry to hear that.

Unfortunately, I don't have a reproducible example on which I could find the right appID. It doesn't have to be code – it can be any app (even on the App Store) which is using ASWebAuthenticationSession that I could download and play with. I'll be grateful for any suggestions of such apps!

Curosevic commented 2 years ago

Looks like I was able to get it using enterText and my apps appId :)

bartekpacia commented 2 years ago

@wferem1 Let me know if your problem persists.

wferem1 commented 2 years ago

I can't seem to get it working, this is the part of my code starting from the permission dialog


  if (Platform.isIOS) {
    // extra popup before opening webview
    await tester.native.tap(Selector(text: 'Continue'), appId: 'com.apple.springboard',);

    await tester.native.enterTextByIndex(
      'email@test.com',
      index: 0,
      appId: 'com.apple.webapp', // I tried with and without an appId (safari, webapp, springboard, my own)
    );

    await tester.native.enterTextByIndex(
      'password!',
      index: 1,
      appId: 'com.apple.webapp',
    );

    await tester.native.tap(
      Selector(text: 'Continue'),
    );
  }
Curosevic commented 2 years ago

You could try enterText instead of enterByIndex. EnterByIndex didn't work for me but enterText did.

bartekpacia commented 2 years ago

I have a hypothesis why enterTextByIndex() doesn't work in your case but enterText() does.

This could be because enterTextByIndex(), when called, looks at all the text fields present in the app and attempts to find the text field with the given index, failing if it doesn't exist.

enterText(), on the other hand, has a timeout (10s by default), so if a text field is not found immediately (because the website is, for example, loading), it will wait for it and fail only after the timeout has passed.

If you're interested in how it works under the hood, here's Swift code for enterText(), and here for enterTextByIndex()

Yokoi-K commented 2 years ago

@bartekpacia

My app has Google authentication. https://pub.dev/packages/google_sign_in

I would like to say in advance that my language is Japanese. So it is not in English.

Tapping the iOS dialog during Google Authentication was successful.

However, the email address input in the following Google modal fails.

iOS native dialog for google_sign_in (Success)

await tester.pumpAndSettle();

// This is success.
await native.tap(
  // 'ηΆšγ‘γ‚‹' is 'Continue' Japanese.
  Selector(text: 'ηΆšγ‘γ‚‹'),
  appId: 'com.apple.springboard',
);

email address input for google_sign_in (Failure)

enterText does not work.

await tester.pumpAndSettle();

// This is failure
await native.enterTextByIndex(
  'test@gmail.com',
  index: 0,
  appId: 'com.apple.webapp',
);

// or This (also failure)
await native.enterText(
//  'γƒ‘γƒΌγƒ«γ‚’γƒ‰γƒ¬γ‚ΉγΎγŸγ―ι›»θ©±η•ͺ号' is 'Email address or phone number' Japanese.
Selector(text: 'γƒ‘γƒΌγƒ«γ‚’γƒ‰γƒ¬γ‚ΉγΎγŸγ―ι›»θ©±η•ͺ号'),
   appId: 'com.apple.webapp',
   text: 'test@gmail.com',
);

thanks.

Yokoi-K commented 2 years ago

I was mistaken.

I solved the problem by setting the bundleId of my app properly.

bartekpacia commented 1 year ago

Closing because it looks like it was resolved :) Feel free to comment and I'll be happy to continue the discussion :)

github-actions[bot] commented 1 year ago

This issue has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar problem, please file a new issue. Make sure to follow the template and provide all the information necessary to reproduce the issue.