[入职期间,我有一个带有表格视图的视图,供用户打开/关闭他想要的推送通知。在此推送通知列表的下面,我有一个“下一步”按钮,该按钮转到应用程序的主视图。
虽然我正在模拟器上测试用户界面,但是当我点击“下一步按钮”时,除非所有推送通知均已关闭,否则我会收到带有“允许”按钮的系统警报“应用程序名称希望向您发送通知”。
要处理此系统警报,我正在使用以下方法:
func handleWouldLikeToSendNotificationsAlert() {
sleep(1)
addUIInterruptionMonitor(withDescription: "Would like to send you notifications alert") { (alert) -> Bool in
let alertButton = alert.buttons["Allow"]
if alertButton.exists {
alertButton.tap()
return true
}
return false
}
XCUIApplication().tap()
}
实际上,我的应用程序还会显示一个自定义警报,以防用户打开了某些推送通知但由于某种原因而无法发送它们。因此,当我在模拟器上进行测试时,我总是会收到此警报。我编写了另一种方法来利用此警报,因此即使使用UI测试,即使打开了某些通知,我也可以进入应用程序的主视图。
问题是:第一个handleWouldLikeToSendNotificationsAlert()
有时也会同时点击我的自定义警报。因此,这是不可靠的。
而且系统警报仅显示一次。如果已经允许一次,则不会在其他测试中再次显示。在Bitrise上,我有时会通过此测试,有时会失败。
是否有办法确保我总是收到此系统警报?还是永远不会得到它?
而且为什么XCUIApplication.tap()
会点击我的自定义警报?我以为它将根据此代码处理系统警报上的“允许”按钮。
谢谢。
可以使用AppleSimulatorUtils util授予所有必需的权限(在Simulator上进行测试时)。这种方法消除了消除警报的需要,并节省了时间。通过在终端应用程序中输入以下命令来安装util
brew tap wix/brew
brew install applesimutils
并授予权限
applesimutils --byId <simulator UDID> --bundle <bundle identifier> --setPermissions "notifications=YES"
有关更多信息和示例,请参阅
https://github.com/wix/AppleSimulatorUtils
您也可以使用新的XCTest API撤消权限,但不能撤消通知
app.resetAuthorizationStatus(for: .bluetooth)
阅读更多:https://developer.apple.com/documentation/xctest/xcuiapplication/3526066-resetauthorizationstatus
如先前的Stackoverflow question中所述,从中断监视器的处理程序返回false
表示尚未处理警报。
因此,它两次进入处理程序并已经处理了第二个警报,我才能证明其存在并点击其按钮。
在通过一种这样的方法为两个警报添加中断监视器之后,它可以工作。
func handleAlerts() {
sleep(1)
addUIInterruptionMonitor(withDescription: "Would like to send you notifications alert") { (alert) -> Bool in
let allowButton = alert.buttons["Allow"]
if allowButton.exists {
allowButton.tap()
return true
}
return false
}
addUIInterruptionMonitor(withDescription: "Failed to turn notifications on alert") { (alert) -> Bool in
let GoWithoutNotificationsButton = alert.buttons["Go without notifications"]
if GoWithoutNotificationsButton.exists {
GoWithoutNotificationsButton.tap()
return true
}
return false
}
XCUIApplication().tap()
}
此外,也可以使用如下导航栏:XCUIApplication().tap()
来避免不必要的操作。