XCTestCase与Auth0:如何解除安全警告“XXXX”希望使用“auth0.com”进行登录

8
最近,苹果推出了这个提示:“XXXX”希望使用“auth0.com”进行登录,其中“XXXX”是iOS应用程序的名称。

enter image description here

当用户点击“使用Google登录”或“使用Facebook登录”时,此警报/对话框会出现。这很好,但在运行IOS UI测试时,使用通常的方法关闭系统对话框时,此对话框不会消失。
func doUserLogin(_ app: XCUIApplication) {

    app.staticTexts["notLoggedInActivelabel"].tap()
    // this will bring up oauth0 login window in ios

    // setup a handler to dismiss the system alert
    let handler = self.addUIInterruptionMonitor (withDescription: "allow oauth") { (alert) -> Bool in
        // code should come here where the dialog is presented, 
        // but it never does ....   
        alert.buttons["Continue"].tap() // click Continue Button 
        return true
    }

    // click the login with GOOGLE button. This brings up dialog “XXXX” Wants to Use “auth0.com” to Login
    app.scrollViews.otherElements.buttons["LOG IN WITH GOOGLE"].tap()

    // this step is required when using addUIInterruptionMonitor
    app.tap()

    removeUIInterruptionMonitor(handler)
}

我觉得这有点合理:这是苹果引入的安全系统对话框,旨在提高安全性。如果在代码中轻易地将其解除,将会失去其意义。
但是,还有人知道是否可能在XCTestCase中解除此对话框吗?


1
你有任何关于这个的更新吗,Chris?我也遇到了同样的问题... - pavel
@pavel 很遗憾没有更新,我不得不放弃测试用例。 - chrisl08
1个回答

6

我认为苹果公司希望开发者利用其引入的addUIInterruptionMonitor

实际上,addUIInterruptionMonitor(withDescription:)不起作用,所以我选择访问Springboard并在系统警告中选择适当的权限。

1. 扩展XCTestCase以在必要时重复使用此功能

extension XCTestCase {

    // I hope this code is mostly reusable
    // I didn't test it for Location Permission While in Use vs. Always...
    func setPermission(for alert:XCUIElement, allow: Bool) -> Bool {
        if alert.elementType == .alert {

            // make sure to support any language
            // Might also be "allow" for some dialogs
            let buttonIdentifier = allow ? "Continue" : "Cancel"
            let identifierButton = alert.buttons[buttonIdentifier]
            if identifierButton.exists && identifierButton.isHittable {
                identifierButton.tap()
                return true
            }

            // Or, if you don't want to bother with the language/identifiers
            // Allow = Last button Index (probably 1), Cancel = 0
            let buttonIndex = allow ? alert.buttons.count - 1 : 0
            let indexButton = alert.buttons.element(boundBy: buttonIndex)
            if indexButton.exists && indexButton.isHittable {
                indexButton.tap()
                return true
            }
        }
        return false
    }
}

2. 在测试中调用此函数,例如:

// This holds a reference to your SignIn/Login XCUIElement
yourSignInButton.tap()

let systemAlerts = XCUIApplication(bundleIdentifier: "com.apple.springboard").alerts
if systemAlerts.count > 0 {
    _ = self.setPermission(for: systemAlerts.element(boundBy: 0), allow: true)
}

可选: Springboard类

我还创建了一个Springboard类,因为我也运行着系统设置测试等等...

class Springboard {
    static let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
}

这样,您可以通过以下方式调用您的XCUITestCase扩展:
let systemAlerts = Springboard.springboard.alerts
if systemAlerts.count > 0 {
    self.setPermission(for: systemAlerts.element(boundBy: 0), allow: true)
}

如果addUIInterruptionMonitor(withDescription:)实际上可以工作,那么它可能看起来像下面这样:

注意:目前仅适用于位置、麦克风等授权/权限警报。

let interruptionMonitor = addUIInterruptionMonitor(withDescription: "Allow the app and website to share information") { (alert) -> Bool in
    return self.setPermission(for: systemAlerts.element(boundBy: 0), allow: true)
}

// This holds a reference to your SignIn/Login XCUIElement
yourSignInButton.tap()

removeUIInterruptionMonitor(interruptionMonitor)

该解决方案通常可行,但似乎相当缓慢。首先我打开照片库,然后系统警报直接出现在我的应用程序中。但是之后一切似乎都会冻结约70秒钟。之后setPermission()函数被调用并按预期工作。你有类似的经历吗? - Morpheus78

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接