Call button on UI Testing? - ios

I was wondering if it's possible to tap call button from tel's scheme (e.g tel//555555555). Because if I touch call button I'll have an alert that I need to confirm my call or cancel it. Is it possible?
I have this on my code:
addUIInterruptionMonitor(withDescription: "Phone Dialog") { (alert) -> Bool in
let button = alert.buttons["Llamar"]
if button.exists {
button.tap()
return true
}
return false
}
app.tap()
XCTAssert(app.buttons["call_button"].exists, "No se encuentra el boton de llamar")
app.buttons["call_button"].tap()
sleep(2)
Any Idea?
Regards

The UIInteractionMonitor does not work in the case of the phone call system dialog. The phone call dialog is handled by the Springboard and not your app.
Xcode 9 allows you access to the Springboard so you can tap on the "Call" button by doing this:
func testPhoneCall() {
let app = XCUIApplication()
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
app.launch()
app.buttons["call_button"].tap()
// tap on the call button
springboard.buttons["Llamar"].tap()
}

Related

Why the screen is getting refreshed when tapping cancel from phone call dialer in swift?

I am just using phone dialer in my swift code it is working fine but I don't know why the screen is getting refreshed when I am tapping on cancel button.
if let phoneCallURL = URL(string: "telprompt://1234") {
let application:UIApplication = UIApplication.shared
if (application.canOpenURL(phoneCallURL)) {
if #available(iOS 10.0, *) {
application.open(phoneCallURL, options: [:], completionHandler: nil)
} else {
// Fallback on earlier versions
application.openURL(phoneCallURL as URL)
}
}
}
When the phone call action sheet appears, the OS is hanling the interaction, so your app will become inactive, and the applicationWillResignActive delegate function will be called.
Once cancel button is taped, your app become active, and you may find some loading code in your applicationDidBecomeActive delegate function. You can handle the details in this function.
check offical document to find more details of app life cycle.

iOS Swift UI Test tap alert button

A really small UI test fails when trying to tap an alert button, what step am I missing?
I'm trying to tap the "Continue" button in the alert displayed below with the following code (that I get from recording my steps).
let app = XCUIApplication()
let salesforceloginbuttonButton = app.buttons["salesforceLoginButton"]
salesforceloginbuttonButton.tap()
let posWantsToUseSalesforceComToSignInAlert = app.alerts["“POS” Wants to Use “salesforce.com” to Sign In"]
let continueButton = posWantsToUseSalesforceComToSignInAlert.buttons["Continue"]
continueButton.tap()
When I run the test it fails at the last line (i.e: continueButton.tap()) with the error No matches found for Find: Descendants matching type Alert from input.
Notes:
I already tried waiting a few seconds before tapping the continue button with the same result.
When the test is ran, the app launches and the alert gets displayed after tapping the salesforceloginbuttonButton
I think your alert is not recognized, maybe because of the double quotation marks
You can try and explicitly set the identifier of your alert like this:
let alert = UIAlertController(title: "Alert", message: "msg", preferredStyle: .alert)
alert.view.accessibilityIdentifier = "myAlert"
Then in your tests:
let alert = app.alerts["myAlert"]
let button = alert.buttons["Continue"]
button.tap()
Had a similar issue but I could solve it by using addUIInterruptionMonitor. In your XCTestCase add an override setUp like this. One caveat is that it's a little flakey... Will update the answer if I find a better solution.
class ExamplelUITests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
app = XCUIApplication()
continueAfterFailure = false
addUIInterruptionMonitor(withDescription: "Login Dialog") {
(alert) -> Bool in
let okButton = alert.buttons["Continue"]
okButton.tap()
return true
}
app.launch()
}
func testExample() throws {
app.buttons["Login"].tap()
app.tap() // This one is needed in order for the InteruptionMonitor to work
}
}

Trying to automate allowing push notifications in UI test and UI interruption monitor does not trigger

I am trying to write a UI test for my iOS Swift app in order to automate screenshots with Fastlane. My app requests push notification permissions in its AppDelegate's didFinishLaunchingWithOptions, so when the application is first launched on a new device (which is going to be the case since I will erase the simulator between each running of my UI test), I want the permissions to be allowed before I can interact with the rest of the app. So I followed this article and here is my UI test's code:
import XCTest
class Fastlane_Snapshots: XCTestCase {
let app = XCUIApplication()
override func setUp() {
continueAfterFailure = false
setupSnapshot(app)
app.launch()
addUIInterruptionMonitor(withDescription: "System Dialog") {
(alert) -> Bool in
print("Interruption running")
let button = alert.buttons.element(boundBy: 1)
if button.exists {
button.tap()
}
return true
}
app.tap()
}
override func tearDown() {
}
func testSnapshots() {
}
}
But the UI monitor code is never triggered. When I start recording for the testSnapshot method, I see the alert appear in the simulator but it's not dismissed, and when I set a breakpoint on the first line of the UI interruption monitor callback, it doesn't get there.
Any idea what I might have forgotten?

In AppDelegate how to detect if user is typing inside UITextView?

I'm showing notification alert when app is active. In AppDelegate I'm handling push notification alert and action. I want to detect if user is typing in UITextView in a VC.
How to check it?
Following is the code snippet in AppDelegate.swift
switch application.applicationState {
case .active:
if let topVC = currentNavInTab.visibleViewController as? ChatViewController {
if topVC.user_is_typing { // How to detect if user is typing?
return
}
}

DispatchGroup notify() doesn't get called

I have to wait for the completion until the user touches the Try Again button to call the same function again. All works fine the first time but when I press it again, the notfy() method doesn't get called. Here is the playground class to simulate that scenario:
import Foundation
class TokenManager{
private var alertAlreadyShown = false
static let shared = TokenManager()
var alreadyEnterGroup = false
let handlerTryAgainGroup = DispatchGroup()
func showRefreshAlert(onTryAgainPressed : #escaping()->Void){
//PREVENTS TO ENTER ON GROUP MUTIPLE TIMES (ASYNC CALLS)
if(!alreadyEnterGroup){
alreadyEnterGroup = true
self.handlerTryAgainGroup.enter()
}
//PREVENTS TO SHOW ALERT MUTIPLE TIMES (ASYNC CALLS)
if(!alertAlreadyShown){
alertAlreadyShown = true
//NOTIFY THE COMPLETION THAT USER TOUCH TRY AGAIN BUTTON
handlerTryAgainGroup.notify(queue: DispatchQueue.main) {
onTryAgainPressed()
}
}else{
//THIS IS JUST A TEST TO SIMULATE THE USER TAPS MUTIPLE TIMES ON BUTTON
TokenManager.shared.tryAgainPressed()
}
}
func tryAgainPressed() {
alreadyEnterGroup = false
handlerTryAgainGroup.leave()
}
}
func showAlert(){
TokenManager.shared.showRefreshAlert {
//CALLS THE SAME FUNCTION IF THE USER TAPS TRY AGAIN
showAlert()
}
}
//SHOW THE ALERT AND PRESS TRY AGAIN FOR THE FIRST TIME
showAlert()
TokenManager.shared.tryAgainPressed()
What is wrong at this case?

Resources