【问题标题】:How to locate element on system action sheet in iOS UI Test如何在 iOS UI 测试中定位系统操作表上的元素
【发布时间】:2022-08-05 16:04:56
【问题描述】:

我们的应用程序将在 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))

  • 对我来说,跳板有时会发挥作用,但可能会延迟 30-60 秒 :\'(,有时它在运行比 iOS15 更旧版本的 iOS 的设备上也不起作用。
  • 谢谢你的回复。我正在使用版本 15.3.1 的 iPhone 13 Pro 运行此测试。好一点,我会试着等一下跳板,看看它是否可以触发。
  • @stachich,你是对的。添加30秒等待后,可以找到Springboard中的标签和按钮!谢谢伙计,这个问题困扰了我大约 2 天:)
  • 没问题的伙伴,很高兴你解决了它:D。这只是迄今为止我遇到的与 xcuitests 相关的许多奇怪事情之一。

标签: ios swift uikit xctest uiactionsheet


【解决方案1】:

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

值得一提的是,对于我们的应用来说,它实际上不是 Action sheet,而是与 UITextView 关联的文本,当用户单击 URL 时会触发 UITextViewDelegate 方法 textView(_ textView: UITextView, shouldInteractWith URL:...

UI测试,通话按钮其实是一个staticText/Label。取消按钮是按钮。所以一定要给他们正确的类型。

    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()

    }

最小测试应用

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: sample@gmail.com"
        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
    }
}

【讨论】:

    【解决方案2】:

    加载跳板元素关卡可能很耗时。如果您的设备上安装的软件很少,很容易找到相应的元素。这是我遇到的情况。

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多