打开 url 外部浏览器时是否可以测试 uitest (XCUI)?

Is it possible to testing uitest (XCUI) when open url external browser?

目前,我必须使用 XCUI 创建自动化 ui 测试,我有一些操作可以打开外部浏览器,默认情况下是 Safari。

我需要像这样创建一些ui测试行为。

  1. 单击我的按钮时转到外部浏览器。
  2. 检查是否正确 url 在浏览器中打开(或只打开浏览器)?
  3. 使用恢复状态返回我们的应用程序。

这不可能吗?

当然。 Safari 是一个 XCUIApplication,就像其他包标识符为 com.apple.mobilesafari.

的应用程序一样

要检查 URL,您将 tap() URL 字段(页面加载时它是一个按钮)并读取 URL 字段的值(此时它是一个 textField)。一旦你完成断言,activate() 你的应用程序,你就会回到它(注意:我的测试在断言后完成,所以我不必这样做,但这是已发布的方法 - 你总是可以输入调试并找到如何在屏幕的 top-left 中点击按钮 return 到您的应用程序(如果这不起作用)。

如果您向我展示您已经尝试过但无法正常工作,我很乐意提供准确的代码,但它是非常简单的 XCUI 自动化。

提供对我有用的确切代码

     enum SafariError: Error {
          case appLoadTimeout
     }
    
    let safari = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari")
    app.buttons["MyButtom"].tap() // MyButton launches Safari
    
    guard safari.wait(for: .runningForeground, timeout: 5) else {
        throw SafariError.appLoadTimeout
    }
    
    safari.otherElements["Address"].tap()
    XCTAssertEqual(safari.textFields["Address"].value  as! String, "https://check-url.com")

    app.activate() //Back to my app

前面的答案适用于外部浏览器。如果您的应用恰好启动内联浏览器,它们将无法工作,因为没有 URL 栏。您可以检测到内联浏览器并点击 Safari 按钮以在外部启动它,然后再检查 URL,但是您必须重新激活您的应用程序并关闭内联浏览器。更多步骤。

有一种更简单的方法适用于两种浏览器类型!

这些浏览器共享什么?一个分享按钮!我们怎样才能从那里得到 URL 呢? Copy 会将 URL 放入我们可以访问的粘贴板中。

 app.buttons["ShareButton"].tap()
 _ = copyButton.waitForExistence(timeout: Waits.short.rawValue) // a tiny wait is necessary here for the share page to open fully
 app.buttons["Copy"].tap()
 let URL = UIPasteboard.general.string!

这里有两个问题:

  1. 内联时,app 是您的应用。在外部时,它是 com.apple.mobilesafari。你必须有逻辑来处理它。
  2. 您想等待页面完成加载。如果不这样做,您将 运行 变得脆弱。当页面加载时,有一个ReloadButton。当它消失时,您应该会看到 StopButton。如果重新加载按钮没有消失,则页面没有完全加载,因此您可能需要点击停止按钮,但要以安全的方式进行,因为我看到页面加载完成的时间可能有 1% 以毫秒为单位在放弃它和执行该点击之间 - 我在点击之前快速 isHittable 检查。