Appium: How to dismiss an iOS modal without a Close button - appium

I'm trying to automate an iOS app's UI for testing purposes. I'm having trouble closing/dismissing a modal that does not have a Close button.
I'm using Appium (Python) to automate actions and the Inspector tells me that all other elements "behind" the modal are visible: false ... so if I tap_settings to open the modal, tap_settings to close the modal doesn't work.
When I tap_settings to dismiss the modal, my code continues without failing but the following assertion fails because the modal persists.
I've also tried the 6 actions below:
#1
el = driver.find_element_by_name('Settings')
action = TouchAction(driver)
action.press(el)
#2
return TouchAction(driver).press(None, 10, 10).perform()
#3
return TouchAction(driver).tap(driver.find_element_by_name('Settings')).perform()
#4
return profile_settings().clear()
#5
return driver.execute_script("mobile: tap", {'x': 0, 'y': 0})
#6
return driver.swipe(0, 0, 10, 10)
Has anyone run into this or something similar? Or any ideas I haven't tried?

#rHenderson- Try adding below code, after performing actions on the modal
self.driver.press_keycode(10);
Other that above, pressing back key might also help closing the modal if it is supported by your app.

Related

refundRequestSheet done button is not working properly [SwiftUI 4, iOS16.1+]

I am having an issue with refundRequestSheet. So basically, my issue is that everything is presented just fine, I can get through the refund process, but at the end of the process where we are having done button, after I press the done button nothing is happening, result is not being called - it looks like the button is not actually calling any action.
The only way for me to close the screen is to actually swipe the sheet down, and then the result of onDismiss sometimes is failure and sometimes is a success.
I also investigated other type of sheets such manageSubscriptionsSheet, and this is having the same issue basically.
I also tried both simulator and the actual device, still nothing.
.refundRequestSheet(for: viewModel.transactionID ?? 0, isPresented: $viewModel.showRefundSheet, onDismiss: { _ in
viewModel.showRefundSheet = false
})

Jetpack Compose back button press in automation test

What is the recommended way to trigger a back button press in a jetpack compose test (running on a real device)?
I'm trying:
#get:Rule()
val composeTestRule = createAndroidComposeRule(MyActivity::class.java)
#Test
fun test() {
// Here would be some setup code, assertions and navigating into a second screen
// Navigate back to previous screen
composeTestRule.onRoot().performKeyPress(KeyEvent(NativeKeyEvent(0, KeyEvent.KEYCODE_BACK)))
// continue...
}
But I get the error:
java.lang.IllegalStateException: KeyEvent can't be processed because this key input node is not active.
I don't have any special logic for the key presses / navigation and only use out-of-the box functionality of the navigation compose library.
I ended up using the ActivityScenarioRule:
composeTestRule.activityRule.scenario.onActivity { activity ->
activity.onBackPressedDispatcher.onBackPressed()
}
Not sure if this is the right way to do it but it works.
EDIT: As pointed out correctly by LN-12 you should be using the onBackPressedDispatcher to support API 33's predictive back gestures.
We can use below code to test device back button from composable screen
Espresso.pressBack()

Modal dialogs breaking responder chain in mac catalyst scene based app

I have a multi-window scene-based (not SwiftUI) iPad app that I am adapting for Mac using mac catalyst. I am having trouble with the main menu behavior. The menu is built in AppDelegate.swift using func buildMenu(). I have, for example, an Open Image... menu item that uses a selector in my main view controller. Here is the code in buildMenu():
let openFileCommand = UIKeyCommand(
title: "Open Image...",
action: #selector(DiagramViewController.openImageFile(_:)),
input: "o",
modifierFlags: [.command]
)
let openFileMenu = UIMenu(
title: "",
image: nil,
identifier: UIMenu.Identifier("openImage"),
options: .displayInline,
children: [openFileCommand]
)
builder.insertSibling(openFileMenu, afterMenu: .newScene)
It is enabled and works fine when first opening the view controller. See:
I then open any modal dialog, for example, the About dialog, and after closing it, the Open Image... menu item is deactivated, as if the selector is no longer in the responder chain, though everything works on the view controller.
I don't understand what is going on here. This kind of functionality works fine on a non-multi-window catalyst app.
UPDATE: Well the problem has nothing to do with the app being scene-based. It is a UIDocument based app, and the UIDocumentBrowserViewController presents the main view controller modally. The main view controller is then the first responder and everything is fine, but as soon as you open another modal window on top of it, like the system generated About dialog, the original document browser view controller becomes the first responder and the main view controller is no longer in the window hierarchy (even though the document browser view controller is invisible, and the main view controller is still shown and works normally). If anyone has experience with dealing with this issue, I'd appreciate their advice.
With further experimentation, and given that this is a UIDocument based app, it looks like the document browser view controller becomes the first responder after the dialog closes. So I think I can work around that and forward actions form the document browser to the main view controller.

Is there a way to catch and cancel the back button event in a NativeScript app on the iOS platform?

I'm working on a NativeScript-Angular app for both Android and iOS but have hit a problem with standard back button navigation. I have resolved the issue for Android, but cannot find a solution for iOS.
The event is causing a problem when going back to a particular page where routing data is expected, resulting in the exception:
"Error: Currently in page back navigation - component should be reattached instead of activated".
My Android solution catches the back button event and cancels it, then calls the router to do the navigation.
ngOnInit() {
if (app.android) {
app.android.on(app.AndroidApplication.activityBackPressedEvent,
(args: any) => this.backEvent(args));
}
}
backEvent(args) {
args.cancel = true;
this.backToRegister(false);
}
backToRegister(accepted: boolean){
this.router.navigate(['/register',
this.registerParametersEntered.password,
this.registerParametersEntered.confirmPassword,
this.registerParametersEntered.code,
this.registerParametersEntered.email,
accepted]);
}
I want to do something similar with iOS, such as: -
if (app.ios) {
this.page.on('navigatingFrom', (data) => {
// TODO cancel the back button event
this.backToRegister(false);
})
}
I can't find a way of doing this for iOS - my research is leading me to the conclusion it is not possible to cancel the iOS back button - for example, see here.
Any ideas or alternative suggestions greatly appreciated!
You can't override the back button for iOS. See this SO question. You basically need to create a custom button, you can mimic the appearance of the back button on iOS and add your own event handler. That's how you'd do it in a native iOS app, and how you do it in NativeScript since the native controls are used via NativeScript.
The actionbar in nativescript can have a custom layout inside or you can just use an action-item and position it on the left for iOS, while also hiding the button on Android if you desire.
Another solution would be, instead of catching the back button event just to throw it away/disable it - to just clear the history after you are switching a page where there no "back" to go to.
this.router.navigate(['level1'], {
clearHistory: true
}

UISearchController disappears when pushing a new UIViewController

I'm currently working with an example from Raywenderlich: UISearchController-Tutorial (The finished project is at the end of their article or here) and I noticed that when I execute a search and click on one of the results, during the push transition, the UISearchController disappears. It's visible on this video: here
Before selecting a result
During the transition to the new VC
I run this example with Xcode 10, iOS 12 (sim: iPhone 8)
Any idea / pointer would be deeply appreciated
Cheers.
Its default in iOS12. Just look at the Apple-Mail App. There it is the same. Actually you dont need the searchbar, when you are showing another VC

Resources