Bartosz Strutyński Bartosz Strutyński - 26 days ago 15
iOS Question

Xamarin.UITests - testing on real device - iOS - app permissions popups issue

I've iOS app that needs some privileges (GPS, Push notifications).
When app starts for a first time iOS asks user if they're ok with granting those permissions to application.
I've written some UITests and want to automate running them on locally connected iPhone.

The problem is that I cannot override permissions questions and my tests fails.
I found out that application deployed by IDE (Xamarin Studio) will ask for permissions, but application deployed via UITests will not.
So I tried with

.AppBundle(path_to_app)
but it says this is only valid for deploying to Simulator.


SetUp : System.Exception : This app bundle is not valid for running on
a simulator. To fix this issue please ensure that your target device
is a simulator. DTPlatformName is 'iphoneos', not 'iphonesimulator' in
the apps Info.plist.


Like it's trying to deploy iPhone app to Simulator. But Target in Xamarin Studio is set to real device.
I tried to add
.DeviceIdentifier
. When Used with
.InstalledApp
it was starting up (still asking for permissions).
But when I used
DeviceIdentifier
and
AppBundle
there was the same error as above.

My tests works fine on Test Cloud. They work fine on Simulator.
They work fine when I deploy to device manually, start app and approve permissions then run UI tests.

What I cannot achieve is to make UITests override permissions questions on real device.
Anyone made this work?

Last thing is that I found is in documentation for
AppBundle
method
"Will force a run on simulator"
https://developer.xamarin.com/api/member/Xamarin.UITest.Configuration.iOSAppConfigurator.AppBundle/p/System.String/

So I may be doomed with the task but maybe someone knows a workaround?

Answer

You can dismiss system dialogs with UITest by using InvokeUIA. The test below works by tapping the "OK" button of an iOS system alert:

[Test]
public void AppLaunches ()
{
    app.Screenshot ("First screen.");
    app.InvokeUia ("uia.query('[:view {:marked \"OK\"}]')"); 
    app.InvokeUia ("uia.tapMark(\"OK\")"); 
}

A working sample app & UITest is also here: https://github.com/King-of-Spades/InvokeUia-for-System-Dialogs

Warning about system dialogs in Test Cloud

The reason that you don't see this issue in Test Cloud is because Test Cloud automatically dismisses the system alerts; so usually you don't have to worry about it. However, if your alert launches too soon; so that it appears before the automation has fully started your app, then it will be unable to detect & dismiss the alert and cause your test to fail.

So you want to make sure that when running your app in Test Cloud that the request for permissions are delayed, or you can even deactivate them if they aren't explicitly needed for a particular test. More information is available in this Calabash guide: https://github.com/calabash/calabash-ios/wiki/Managing-Privacy-Alerts%3A--Location-Services%2C-APNS%2C-Contacts

(Even though it's Calabash, you can use the same strategy in UITest; albeit with a C# syntax.)

Update for Xcode 8 / iOS 10

Xcode 8 / iOS 10 removed UIAutomation, so the InvokeUIA workaround will only continue to be possible if you're using Xcode 7 and iOS 7-9. References:

Comments