iOS - Logout from Apple Store / Restore Device Programmatically - ios

I'm automating test cases to run in several devices in parallel. I'm using Appium for this and this works fine. My issue is that I have some test cases that need the device to be logged into specific Apple Store accounts. Also, it is possible that the device might already be logged into another account and I don't have the option to logout manually. My test cases to log into an account if the device has no account attached to it already run well (inside my app I try to do an action that requires an Apple ID, the alert requiring login appears and I already automated the login process). The issue is when the device is already logged into another account.
My two options are:
Force the device to log out from Apple Store
Create a device backup without being logged and restore this backup before my test
I wasn't able to find a way to handle the first option. The second one works using idevicebackup2 (a lib from libimobiledevice). The issue here is that after restoring the device data, the setup wizard appear and there is no way to get rid of it automatically. I tried using cfgutils to remove the wizard steps, but even after removing all steps, the wizard appears just waiting for a confirmation after restoring.
I would like to know if there is a way to go for the first option, or a way to skip the setup wizard in the second option, or maybe a way to restore the backup partially (just clearing the Apple ID data) in order to avoid rebooting the device and getting stuck with the wizard again. Thanks in advance.

One option available now with Xcode 9 is the new multi-app testing. You can now call any app on the system based on it's bundle identifier XCUIApplication(bundleIdentifier: "com.MEGACORP.xyz") during a XCUI test. They cover the new API and examples in WWDC session 409 - What's New in Testing - it's worth watching the whole thing.
I've written some tests using the new API to switch out of the app under test and open System Settings to reset the app state during the test teardown. There's a list of all the system bundle ids in this question.
Your test would start with something like:
let store = XCUIApplication(bundleIdentifier: "com.apple.AppStore")
store.launch()

Related

iOS | Always logged in at the start of every new test

Not sure was this already asked here, but I could use help with an issue. I will provide any additional info if needed.
As said in the title, I would like to not be logged in after every test has been run, since I need to go through login test first. My colleague on Android just goes through her test, and does Driver.Quit/Dispose(); at the end, and she’s logged out for every other/next test after that.
On the other hand, for me (iOS), after I dispose of my driver - when the next test starts, I’m frequently (if not all the time) already logged in, and then I need to handle that case as well - and I’m trying to avoid it. I know that some login data is kept in the iOS keychain - and I can reproduce this issue manually with our app - if I uninstall the app, while being logged in - after I reinstall the app and start it - I’m already logged in.
Is there a way to handle this in a proper way? I’ve tried a lot of things, like actually logging out through the app, but that adds additional code, and makes it more complicated. Tried few additional capabilities - but nothing worked.
Note: It sounds like your app is keeping you logged in even with terminating/reinstalling the app. I would take a look closer and see if there's an issue attempting to log the user out when the app terminates or if there's a reason it's not coming to the login page after reinstalling.
I have code inside my iOS app that closes out the app if the app is terminated. And the below code works for me with appium as it terminates the app which also means it logs me out.
Try this to terminate your app:
const bundleId = "com.yourappsbundleid"
driver.terminateApp(bundleId)
Also note that appium's website provides more information and also ways to do this in other languages. See: https://appium.io/docs/en/commands/device/app/terminate-app/

How to reset an iOS app, using UIAutomation instrument, if the app does not have sign out option

I want to test the sign in screen and once I complete one test, my app is signed in but for the next test I want to sign out and go to the first screen again. (PS: App does not have a sign out).
Is there any way out that I can clear application data without uninstalling the app so that I can resume my tests from the first screen without any break.
Or please suggest if there is any other option.
You could try cmd-shift-hh? then swipe the app up, then you can test the app again
This kind of feature is important, because in the case where the app fails a test (and is therefore in an unknown state), you want a reliable way to return to a known state -- like the first screen.
The bad news is that Apple doesn't give you this within instruments.
One way to do to it is to take advantage of the shake gesture -- assuming that you don't need it for other things in your app -- so that in a UIAutomation build, calling target.shake() will return you to your first screen.
Another way to do it would be to instrument your code so that you can send a reset signal from the shell as part of your test. In our framework (called Illuminator), we provide an automation bridge to accomplish this.
driver.resetApp(); It may work. try this.

Removing iOS permission alert for local notifications when running app in simulator

I'm trying to write an acceptance test in KIF on an app that asks for local notification permissions pretty early on. Unfortunately due to iOS simulator security reasons it isn't possible to automate accepting iOS permission alerts using KIF. Per https://stackoverflow.com/a/28443743/62 it looks like there are ways to disable the permission alerts for location, address book, calendar, and photos, but I couldn't find a way to disable the local notification permission. I tried the entitlement approach from the linked question but none of the following keys worked:
kTCCServiceNotifications
kTCCServiceNotification
kTCCServiceLocalNotification
kTCCServiceLocalNotifications
Any other ideas? For now I'm working around this by changing my production code to conditionally disable local notifications when acceptance tests are running, but ideally I wouldn't have to.
Unfortunately, I don't think in an automation test there is a good way to do this. I know that even resetting the simulator isn't sometimes enough to reset permissions. I would design your tests to not test a system call, but your own application code.
One way to test different functionality based on whether the user allows notifications is to extract the call to check for permissions and then stub this method out in the testing. This method would be the best practice since the goal is not to test if iOS works but if your application code is correct.
Notification permission can be suppressed by granting permission in applicationState.plist:
Run your app on a simulator and tap on "ok" for any permission popups
navigate to "~/Library/Developer/CoreSimulator/Devices/{$deviceId}/data/Library/BackBoard/applicationState.plist"
Replace the applicationState.plist of the UI test simulator with the above one before bootstrapping it

Modal Application

I'm using Xamarin.Android and I would like to build an application that start in modal way and don't close if you push the home button.
So this application need to be the only one application than a user can use on device.
Somebody can suggest how it can be done?
You best way to do is to make a "Launcher"/"Home" application. The Android SDK comes with a sample on how to do this.
You basically do this by adding your main Activity to the android.intent.category.HOME and android.intent.category.DEFAULT category and you set the launchMode to singleInstance.
This will register it as a Home application, then when you press your home button it should ask you to choose which launcher you want to use. You will have to set it once and it can be changed by the user.
You can find the sample in: android-sdk\samples\android-17\Home\src\com\example\android\home (should also be available in the other API samples).
You cant stop people from installing applications on android devices. You would have to build your own hardware for that however, you can override OnKeyTouch and check for the key being home.
You could build a service that checks the package of each running application and log which applications are run on the device to prevent users from using company property on other things. However, if android ever decides to kill your application the service should stop and this wont work.
Long story short what you are trying to do is flawed in its inception given the platform you are trying to do it on.

Create equivalent of Androids sync adapter on iOS

I got data on a webserver which I want to download to an iOS contact list. Is it possible to programatically create an account on iOS that works like the android "sync adapter" and is not one of the default account or an LDAP/CardDAV account?
Or can I have my application to periodically chech for updates on my webserver without the user having to manually start it. (i.e. running in the background and starting up automatically when the phone is restarted)
No, to both. The best you can do is create a configuration profile that the user can download to add an LDAP/CardDAV account—but you will need to run an actual LDAP or CardDAV server to have any kind of automatic contact syncing happen without the user opening your app. The Address Book framework on iOS only allows you to add and modify contacts within the existing accounts on the device, and the multitasking rules only allow your app to start in the background if it provides a VoIP service.
Use silverstripe-sync !
Source: SO

Resources