如何在 iOS UI 测试中定位系统操作表上的元素

发布于 2025-01-09 13:34:46 字数 1309 浏览 0 评论 0原文

我们的应用程序将在 iPhone 屏幕底部弹出一个系统操作表,如下图所示。我想在 UI 测试中找到并点击该操作表上的“呼叫...”和“取消”按钮。

首先,我尝试添加一个 UI 中断处理程序,并将断点放入处理程序闭包中,但在操作表显示时不会触发它。

        // Add an UI interruption handler to handle system alert.
        addUIInterruptionMonitor(withDescription: "Notification permisson request") { alert in
            let notifyAllowBtn = alert.buttons["Allow"]
            let callBtn = alert.buttons["Call 8663xxxxx"]
            
            if notifyAllowBtn.exists {
                notifyAllowBtn.tap()
                return true
            }
            
            if callBtn.exists {
                callBtn.tap()
                return true
            }
            
            // A placeholder for other alerts
            return true
        }
        // need to interact with the app again for the handler to fire
        app.swipeUp()

我还尝试了 SpringBoard,但仍然没有运气。这里需要帮助,我如何在系统操作表上找到该元素?

        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        let alertCallButton = springboard.buttons["Call 8663xxxxx"]
        XCTAssert(alertCallButton.waitForExistence(timeout: 5))

输入图片此处描述

Our app will pop up a system action sheet on the bottom of iPhone screen as below screenshots illustrated. I want to locate and tap the "Call..." and "Cancel" button on that action sheet in UI Test.

First, I tried to add an UI interruption handler, and put a break point into the handler closure but it is not triggered when action sheet showed.

        // Add an UI interruption handler to handle system alert.
        addUIInterruptionMonitor(withDescription: "Notification permisson request") { alert in
            let notifyAllowBtn = alert.buttons["Allow"]
            let callBtn = alert.buttons["Call 8663xxxxx"]
            
            if notifyAllowBtn.exists {
                notifyAllowBtn.tap()
                return true
            }
            
            if callBtn.exists {
                callBtn.tap()
                return true
            }
            
            // A placeholder for other alerts
            return true
        }
        // need to interact with the app again for the handler to fire
        app.swipeUp()

Also I have another try with SpringBoard, still without luck. Need help here, how could I locate the element on system action sheet?

        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        let alertCallButton = springboard.buttons["Call 8663xxxxx"]
        XCTAssert(alertCallButton.waitForExistence(timeout: 5))

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初心 2025-01-16 13:34:46

正如 @stackich 所说,我添加了 30 秒的延迟来在 Springboard 上查找元素。它有效。我将我的测试放在下面,以防将来有人遇到同样的问题。

值得一提的是,对于我们的应用程序来说,它实际上不是操作表,而是与 UITextView 和 UITextViewDelegate 方法关联的文本 textView(_ textView: UITextView, shouldInteractWith URL:...< /code> 当用户单击 URL 时触发

,调用按钮实际上是一个静态文本/标签,因此请务必为他们提供正确的类型

    func testPhoneCall() {
app = XCUIApplication()
springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
app.launch()

app.links["888-111-2222"].tap()
sleep(1)

let callLabel = springboard.staticTexts["Call (888) 111 2222"]

print("

As @stackich said, I add a 30 seconds delay to find elements on Springboard. And it works. I put my test in below in case anyone meet the same problem in the future.

Worth to mention that, for our app it is not Action sheet actually, instead it is text associated with UITextView, and UITextViewDelegate method textView(_ textView: UITextView, shouldInteractWith URL:... is fired when a user click a URL.

UI Test, the call button is actually a staticText/Label. The cancel button is button. So be sure to give them the correct type.

    func testPhoneCall() {
        app = XCUIApplication()
        springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        app.launch()
        
        app.links["888-111-2222"].tap()
        sleep(1)
        
        let callLabel = springboard.staticTexts["Call (888) 111 2222"]
        
        print(" ???? \(springboard.debugDescription)")
        
        // Add a 30 seconds waiting for springboard available
        XCTAssert(callLabel.waitForExistence(timeout: 30))
//        callLabel.tap()

    }

Minimum test app

import UIKit

class ViewController: UIViewController, UITextViewDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "Main View"
        
        addUITextViews()
    }
    
    func addUITextViews(){
        
        // lauout for the View
        let myTextView3 = UITextView()
        myTextView3.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(myTextView3)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            myTextView3.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40),
            myTextView3.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 40),
            myTextView3.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            myTextView3.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            myTextView3.widthAnchor.constraint(equalToConstant: 400),
            myTextView3.heightAnchor.constraint(equalToConstant: 400),
        ])
        
        // set Phone# and Email Address for the UITextView
        myTextView3.font = UIFont.systemFont(ofSize: 24)
        myTextView3.isEditable = false
        myTextView3.isSelectable = true
        myTextView3.text = "Phone: 888-111-2222 \nEmail: [email protected]"
        myTextView3.dataDetectorTypes = .all
        myTextView3.delegate = self
    }
    
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

        guard let currentScheme = URL.scheme else { return false }

        switch currentScheme {
        case "sms", "tel":
            print("It is a call!")
        case "mailto":
            print("send email")
        default: break
        }
        return true
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文