Xcode UI测试如何处理UNUserNotificationCenter生成的通知权限

Posted

技术标签:

【中文标题】Xcode UI测试如何处理UNUserNotificationCenter生成的通知权限【英文标题】:Xcode UI Test How to handle notification permissions generated by UNUserNotificationCenter 【发布时间】:2018-09-04 07:31:21 【问题描述】:

在我的应用程序中,我要求这样的通知权限:

  UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound])  (granted, error) in

        if granted 
            DispatchQueue.main.async 
                UIApplication.shared.registerForRemoteNotifications()
            
        
    

现在在测试时,我需要处理这个权限弹出但它不起作用,我尝试了这些代码:

XCUIApplication().alerts["“AppName” Would Like to Send You Notifications"].buttons["Allow"].tap() //didn't work.

addUIInterruptionMonitorWithDescription("Notification Dialog")  (alert) -> Bool in  
    alert.buttons["Allow"].tap()
    return true



addUIInterruptionMonitorWithDescription("“AppName” Would Like to Send You Notifications")  (alert) -> Bool in  
    alert.buttons["Allow"].tap()
    return true



addUIInterruptionMonitorWithDescription("Notifications may include alerts, sounds, and icon badges. These can be configured in Settings.")  (alert) -> Bool in  
    alert.buttons["Allow"].tap()
    return true

但是没有任何效果。

【问题讨论】:

【参考方案1】:

试试这个

    let app2 = XCUIApplication(bundleIdentifier: "com.apple.springboard")
    let button = app2.alerts.firstMatch.buttons["Allow"]
    button.waitForExistence(timeout: 10)
    button.tap()

【讨论】:

非常有帮助。谢谢。出于某种原因,系统对话不再是应用程序的一部分? ios 14.4、Xcode 12.4 UIInterruptionHandler 也可以。您必须在中断处理程序块之后添加 app.tap() 才能使其工作。但正如 Apple 建议的那样,它应该只用于您不知道它们何时会发生的警报。 当我使用这种方法时,我在tap() 呼叫:[__NSArrayM insertObject:atIndex:]: object cannot be nil (NSInvalidArgumentException) 上收到此错误【参考方案2】:

1/ 尝试使用 XCode 测试记录器记录路径以提醒按钮,并确保您拥有正确的按钮。

XCUIApplication().alerts["“AppName” Would Like to Send You Notifications"].buttons["Allow"].tap() //didn't work.

可能不正确。

(注意:使用测试记录器来做一些事情,比如找到元素的路径是可以的,而且对新手非常友好。)

2/ 您不必使用addUIInterruptionMonitorWithDescription 以防万一,您有一个每次都会发生的系统警报,或者您知道它会发生。 只需使用waitForExistance 并点击它(如果存在)。

(注意:我发现等待和点击系统通知比addUIInterruptionMonitorWithDescription更好,这有时不稳定/复杂)

3/ alert.buttons["Allow"].tap() 对我来说似乎不正确,不应该是 XCUIApplication().alerts.buttons["Allow"] 吗?或者,您可以使用XCUIApplication().alerts.buttons.element(boundBy: 0 点击第一个按钮。

【讨论】:

【参考方案3】:
import XCTest

// For multiple permission requests
var isPhotoPermissionAvailable: Bool?
var isLocationPermissionAvailable: Bool?
var isNotificationsPermissionAvailable: Bool?

extension XCTestCase 

    func allowPhotos(_ enabled: Bool = true) 
        addUIInterruptionMonitor(withDescription: "Photo Permissions")  (alert) -> Bool in
            isPhotoPermissionAvailable = enabled
            var alertButton = alert.buttons["Don't Allow"]
            if enabled == true 
                alertButton = alert.buttons["OK"]
            
            if alertButton.exists 
                alertButton.tap()
                return true
            
            XCUIApplication().tap()
            return false
        
        if isPhotoPermissionAvailable == nil 
            XCUIApplication().swipeUp() //with this code, alert.buttons["OK"] exsists
        
    

    func allowLocation(_ enabled: Bool = true) 
        addUIInterruptionMonitor(withDescription: "Location Dialog")  (alert) -> Bool in
            isLocationPermissionAvailable = enabled
            var alertButton = alert.buttons["Don't Allow"]
            if enabled == true 
                alertButton = alert.buttons["Always Allow"]
            
            if alertButton.exists 
                alertButton.tap()
                return true
            
                XCUIApplication().tap()
            return false
        
        if isLocationPermissionAvailable == nil 
            XCUIApplication().swipeUp()
        
    

    func allowNotifications(_ enabled: Bool = true) 
        addUIInterruptionMonitor(withDescription: "Notification Dialog")  (alert) -> Bool in
            isNotificationsPermissionAvailable = enabled
            var alertButton = alert.buttons["Don't Allow"]
            if enabled == true 
                alertButton = alert.buttons["Allow"]
            
            if alertButton.exists 
                alertButton.tap()
                return true
            
            XCUIApplication().tap()
            return false
        
        if isNotificationsPermissionAvailable == nil 
            XCUIApplication().swipeUp()
        
    

【讨论】:

以上是关于Xcode UI测试如何处理UNUserNotificationCenter生成的通知权限的主要内容,如果未能解决你的问题,请参考以下文章

XCode 如何处理带有多个目标的#import 标头语句?

如何处理 Xcode 故事板中的错位视图警告?

开始Skype通话时如何处理UI?

如何处理 UIActionSheet 的转换

如何处理下拉angular-ui中的大项目列表?

如何处理Xcode上传IPA文件后无法在后台架构版本中显示的问题?