My application opens a view controller which requires the user to enter their passcode to continue. I am writing UI automation and have used the record option to attempt to discover the element name that I need to interact with. The recorder tells me to use the following:
app.secureTextFields["Passcode field"].tap()
However when I run the test the secureTextField is not found. When I print out the elements in app there is no evidence of the view controller that is currently in the foreground and only the elements of my own application (which is in the background currently) are listed. I have also attempted to use addUIInterruptionMonitor (suggestions found here). The test fails on app.tap() stating that the application for target application is not in the foreground.
Is anyone aware of how to access elements of a system dialog currently in the foreground using XCTTest?
Related
I know how to put app into Single app mode programmatically, provided that Autonomous single app mode persimmon is granted by MDM server to App.
This link have detail description about how to lock app in single app mode too.
Code to Apply single app mode as below -
UIAccessibilityRequestGuidedAccessSession(true){
success in
completionBlock(success)
}
My Question/Requirement is, detect if app is running in Autonomous single single app mode or UIAccessibilityRequestGuidedAccessSession is enabled, if it's enabled then only show alert to user and ask if he wish to disable Single App mode.
I Tried to detect using UIAccessibilityIsGuidedAccessEnabled() but it's of no use, as return value is always false.
You can use BOOL UIAccessibilityIsGuidedAccessEnabled(void); to get that information.
Source#AppleDocs
You could also try to add UIGuidedAccessRestrictionDelegate and then react to
func UIGuidedAccessRestrictionStateForIdentifier(_ restrictionIdentifier: String) -> UIGuidedAccessRestrictionState
Remember though, guided access needs to be enabled by the user (triple tap home button). Not from the settings!
So #Akaino answer is right, but UIAccessibilityIsGuidedAccessEnabled method wasn't working as expected due to i used to apply code below on didFinishLaunchingWithOptions hence it wasn't working properly
UIAccessibilityRequestGuidedAccessSession(true){
success in
completionBlock(success)
}
When i applied same code above on viewDidLoad() method, UIAccessibilityIsGuidedAccessEnabled is working as expected.
Some background
I am currently writing a UI Test for a settings pane, and click on buttons to enable certain permissions such as push notifications and location services.
However, if the alert for the permission has been displayed before (regardless of the user allowing or denying access to the permission), the alert will not display again, and will just take the user to the settings app. Unfortunately, these settings do not reset, meaning the first time I run the UI tests, alerts will show; and on all subsequent UI test runs, the buttons will take me to the settings app unless I reset the device before the tests begin.
My issue
Thus, my test needs to know if the app went into the background, and attempt to foreground it to continue the testing:
if app.state == background {
foregroundApp()
}
// continue with other tests
Is there any way to determine if the app is in the background?
What I tried
I researched methods to determine the state of the application (running/background/etc) from a UI test, and was not able to find much. I tried to check whether certain elements exist:
if (app.navigationBars.element.exists) ...
but this gives me runtime errors[1] if the user is taken to the settings page because the app under test is in the background, and the test cannot lookup the navigationBars (or other elements).
I tried using some of the methods from Facebook's private headers for XCUIApplication() and XCUIElement().
XCUIApplication().state always returns 3 no matter what state the app is currently in, and any attempts to call XCUIApplication().resolve() to foreground the app give me the same errors as before[1]
I tried to rewrite the logic to foreground the app before resuming the tests, but methods such as XCUIApplication().launch() kill the app before restarting, which I cannot do. Only siri service seems to work for me, but I cannot access the siri service through the corporate proxy, and modifying proxy permissions is not possible.
Is there any other way to check the app state?
Errors
[1] This error is printed every time I try to do something involving state. I do not call snapshotView anywhere, and thus the suggestion to use afterScreenUpdates is useless.
Failure to get snapshot within 15.0s
Cannot snapshot view (<UIKeyboardImpl: 0x7febcc75d000; frame = (0 0;
414 226); layer = <CALayer: 0x608000625720>>) with
afterScreenUpdates:NO, because the view is not in a window. Use
afterScreenUpdates:YES.`
tl;dr
I need to check whether the app I am UI testing has entered the background (i.e. user pressed the home button). Checking for existence of particular elements such as navigation bars doesn't work, neither do most methods from Facebook's private headers for XCUIApplication/XCUIElement. Foregrounding the app also causes issues, and relaunching the app is not an option; neither is siri service.
You can do this in Swift 4, using XCUIApplication.state, which will give you information about the state of the app - whether it's in the foreground or background etc. however, it's not possible to find this information in Swift 3 and below. Essentially, UI testing in Swift 3 doesn't support leaving the app.
I'd like to write a test for my iOS app that verifies the correct screen content is shown when the app is launched from a custom registered URL scheme.
For example, a user receives an email with a link to myapp://action1/1234. When they tap on this link, my app is launched and the screen displays "1234".
In didFinishLaunchingWithOptions my AppDelegate checks to see if launchOptions?[UIApplicationLaunchOptionsURLKey] exists and takes appropriate action.
How do I write a UI test so that the app launchOptions dictionary contains the expected URL when the app is launched?
You can make this work by leveraging launchEnvironment on XCUIApplication in combination with a few lines of custom code in your target app. Basically you would set a custom launch environment variable for this test, and in your app you would check for that variable and handle it the same way you would handle the existence of the particular UIApplicationLaunchOptionsURLKey you're expecting.
In your app you can check that value via NSProcessInfo.processInfo.environment which returns a dictionary of the environment variables.
(Take note that the default XCTestCase template in Xcode 7 includes a call to XCUIApplication -launch in setup which will terminate any previously running instance, and launch a new instance by default.)
Edit: wanted to add, I've written a little bit more about this in an article on Xcode 7 UI Testing Tips, in case it's helpful.
I am working on an app using Monaca where I need to be able to push notifications to users of the app. I tried getting the monaca push back-end working, and that wouldn't work, the app didn't register. I then moved to using the standard cordova plugin, so I can push directly from my servers, without using monaca's back-end. when I call the init function, normally a register event will fire, this works fine when I build the app. However I very much want to get the custom debugger working, I am able to build the custom debugger, and I see the plugin properly installed. Also the init function gets called, as soon as it is called I get the standard IOS security alert to grant the app permission, however the register event is not fired, therefore I am unable to get the device ID to push to the custom debugger app. Has anyone been able to use push notifications with the custom debugger application?
Best,
Peter
(https://github.com/phonegap/phonegap-plugin-push)
P.S, i calls to set the badge count setApplicationIconBadgeNumber works fine in the debugger. I think this is something simple, maybe with the certs? I dont get any errors fired, no notifications no clues using the standard debugger, how can I hunt down what the issue is?
I can get it work using ngCordova, which is AngularJS integration.
http://ngcordova.com/docs/plugins/pushNotifications/
Then, inject it like
var app = ons.bootstrap('myApp', ['onsen', 'ngCordova']);
Get back to me if you need further clarification.
I am using Display.screenshot() to get a screen shot for the current displayed screen.
My application has all available persmissions set to allow,
it works well in all device application, but it doesn't work on Facebook and Twitter app -
on those apps i got an exception:
Error: net.rim.device.api.system.ControlledAccessException: Unauthorized attempt to attach to this application
what should I do to overcome this?
You seem to be calling Application.getApplication() somewhere in the code.
Your ApplicationMenuItem code generally runs within the UI application whose menu it is launched from. So when you click your ApplicationMenuItem within facebook app, it executes within the event dispatcher thread of facebook app.
However, since your code is not a part of the facebook app, it can't access its Application Object using the Application.getApplication() method.
If you are not calling this method yourself, maybe Display.screenshot() calls it internally. To solve this, you need to run the code in your app's event dispatcher thread. This can be done by using the special method addMenuItem(long, ApplicationMenuItem, ApplicationDescriptor) while registering the menu item and passing it your app descriptor.