使用 UIAutomation 处理警报

Posted

技术标签:

【中文标题】使用 UIAutomation 处理警报【英文标题】:Handling Alert with UIAutomation 【发布时间】:2010-09-06 12:10:49 【问题描述】:

我正在尝试使用 UIAutomation 测试 UIAlertView 的存在,但我的处理程序从未被调用。

在我的 javascript 开头我写:

UIATarget.onAlert = function onAlert(alert) 
    UIALogger.logMessage("alertShown");
    return false;

据我了解,一旦我指定了 onAlert 函数,它就会在我的测试期间出现 alertView 时被调用。 所以我运行了一个显示警报视图的测试,这是显示警报的代码:

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:message message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
alertView.accessibilityLabel = @"alerte d'avertissement";
[alertView show];

我在仪器中运行我的测试,警报出现但我的处理程序从未被调用。有没有人能够将事件处理程序与 UIAutomation 一起使用?

谢谢, 文森特。

【问题讨论】:

【参考方案1】:

文档似乎有误。事实证明,警报是在您的脚本尝试运行的同一线程上处理的。因此,如果您希望调用警报处理程序,则需要休眠,例如,

UIATarget.onAlert =  ... 
window.buttons().triggerAlertButton.tap();
UIATarget.localTarget().delay(4);

此外,警报的名称和值似乎始终设置为空。但是,我能够访问包含警报标题的第一个静态文本。

【讨论】:

在许多情况下,当元素没有指定名称但内部有静态文本时,此文本可以像 name 属性一样使用...对我来说适用于按钮、视图、表格...。跨度> 嗨,我也有同样的问题。你能告诉我如何从 alertview 获取静态 txt 吗?提前致谢 @cancerian 在onAlert 回调函数中,试试alert.logElementTree()。从那里,我看到alert.name() 是它的titlealert.elements()[2].name() 是它的message 而不是delay(4)frontMostApp().alert() 更快:***.com/a/12726891/242933 Drew,您的意思是警报是在与主自动化脚本不同的线程上处理的,对吗? (因为在处理警报时主脚本会继续运行。)@MattDiPasquale,我没有在主线程中找到app.alert() 特别工作; target.delay(4) 的结果要好得多。【参考方案2】:

确保当UIAlertView 显示时 UI 自动化脚本仍在运行。

例如,将以下行添加到脚本的末尾将使其一直运行,直到可以访问警报或对象解析的宽限期到期。

// Wait for UIAlert to appear so that UIATarget.onAlert gets called.
target.frontMostApp().alert();

我通过彻底阅读和理解 Instruments User Guide: Automating UI Testing 发现了这一点,我强烈建议将其作为 UI 自动化的介绍。

查看UIATarget Class Reference,特别是方法popTimeoutpushTimeoutsetTimeouttimeoutdelay 也可能会有所帮助。

【讨论】:

这解决了我的问题。调用 .alert() 将等待最多 5 秒(默认情况下,可使用 target.setTimeout 配置)以显示。【参考方案3】:

下面的代码对我有用。该函数正在处理警报,并在日志上打印“警报显示”。

var target = UIATarget.localTarget();
var application = target.frontMostApp();
var window = application.mainWindow();

UIATarget.onAlert = function onAlert(alert)
    UIALogger.logMessage("alert Shown");    


target.frontMostApp().mainWindow().tableViews()[0]
    .cells()["Fhgui"].buttons()["Images"].tap();
// Alert detected. Expressions for handling alerts 
// should be moved into the UIATarget.onAlert function definition.
target.frontMostApp().alert().defaultButton().tap();

【讨论】:

【参考方案4】:

@vdaubry 解决方案很简单。

根据 Apple 文档,如果您想手动处理警报,那么您应该在 onAlert(alert) 中返回 true 而不是 false

 UIATarget.onAlert = function onAlert(alert) 
    UIALogger.logMessage("alertShown");
    return true;

@Drew Crawford 延迟将不起作用,因为默认情况下 UI 自动化会单击按钮。文档没有错,但解释不清晰。

【讨论】:

【参考方案5】:

我也遇到了“从未调用过警报处理程序”的问题。 只需重新启动苹果的仪器就为我解决了:-)。

【讨论】:

【参考方案6】:

例如- 不调用 onAlert

var target = UIATarget.localTarget(); 
target.buttons()["ShowAlert"].tap()
UIAtarget.onAlert = function onAlert(alert)
...

-

例如- onAlert 被调用

var target = UIATarget.localTarget(); 
UIAtarget.onAlert = function onAlert(alert)
......
target.buttons()["ShowAlert"].tap()

#import "onAlert.js"
var target = UIATarget.localTarget(); 
target.buttons()["ShowAlert"].tap()

试试看。

【讨论】:

【参考方案7】:

在 XCode 6.3.1 & Instruments(6.3.1 (6D1002)) 上使用 sn-p 对我有用:

    var target = UIATarget.localTarget();

    // Following line shows an internal alert with 'Cancel' & 'Continue' buttons
    target.frontMostApp().mainWindow().buttons()["ShowAlert"].tap();

    // Handle an internal alert
    UIATarget.onAlert = function onAlert(alert) 
            return true;
     

    // Perform Tap on alert.
    target.frontMostApp().alert().buttons()["Continue"].tap();

【讨论】:

以上是关于使用 UIAutomation 处理警报的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS uiautomation 中使用两个按钮处理警报

如何使用带有 tuneup.js 的 UIAutomation 验证警报内容

如何处理 UIAutomation 中的文本通知?

使用 UIAutomation 的仪器出现意外错误

在 UIAutomation 中使用accessibilityIdentifier 获取UIElement

pythonGUI自动化:uiautomation的常见使用