如何在等待元素可见性时避免冗余调用

时间:2017-11-17 23:01:21

标签: selenium selenium-webdriver webdriver-io

我目前有一个使用WebdriverIO的测试脚本,点击按钮并等待弹出窗口显示。测试的目的是确保单击后显示元素,但由于它是异步的,我必须等到它显示出来。

但是,如果我等到元素显示,我的断言将始终通过waitForVisible成功。如果它不成功,它将始终在waitForVisible命令上抛出异常,并且断言永远不会执行。

以下是代码示例:

browser.click(btnElement)
browser.waitForVisible(popupElement)
expect(browser.isVisible(popupElement)).to.be.true

有没有不同的方法告诉expect语句重试/等待,直到元素可见,所以断言没有用处?

2 个答案:

答案 0 :(得分:2)

您似乎混淆了 assertions 的目的,或者滥用它们,特别是在您的示例中。当你有确定性 thing (元素的WebElementtextattribute等时,你应该只使用断言。)您要验证包含预期的类型的值(您将其返回到assert,或expect语句以进行最终验证=> 输出是理想的)。

断言验证静态值,他们不会轮询DOM。这就是为什么你有.waitForVisible()waitForText()或更重要的.waitUntil()等工具(提供更多灵活性)的原因。

当然, ChaiJS 提供的expect断言风格可能会有一个令人困惑的词典(expect可能会脱离上下文:它是期待的WebElement可见。只需使用它们来验证不同命令的输出,而不是WebElements的状态,或其他动态/变化元素。

话虽如此,作为最佳实践,您应始终将命令(例如:.click())包装到.waitUntil()块中并确保WebElement已为您即将执行的操作做好准备:

  • 前端逻辑在DOM中呈现吗? (使用.isExisting()
  • 在DOM中可见? (您 *不能点击viewport中无法看到的元素
  • 可点击? (或者你想对其进行的其他行动......)

最后,惯用法(在我们的案例中为.click())应如下所示:

browser.waitUntil(() => {
    browser.isExisting(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') does not exist");
browser.waitUntil(() => {
    browser.isVisible(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') is not visible");
browser.waitUntil(() => {
    browser.click(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') could not be clicked");

您可以将整个内容包装到 custom-command 中,然后根据需要使用它。告别片状测试! :)

* Selenium是以用户为中心的网络自动化工具,因此所有操作都像用户一样执行(用户无法点击不可见的元素< / em>,用户无法同时点击多个元素,或者通过输入整个单词或整个段落来填写input字段。)

答案 1 :(得分:0)

我不了解WebdriverIO,但我认为它有类似于try-catch的东西。在try-catch中等待您的等待。如果成功,Assert.pass()或等效。如果超时,则会在您的catch中抛出异常,因为超时会设置Assert.fail()或等效内容。

我从未使用过ChaiJS,但我确实看过the documentation,发现了一些你应该可以使用的东西。

assert.isOk(false, 'this will fail');

这是来自文档,应该与我熟悉的Assert.Fail()相同。人们可以假设稍微调整以下将相当于Assert.Pass()

assert.isOk(true, 'this will pass?');

如果因某些原因无效,可以使用文档中的以下内容。

assert.isNotOk(false, 'this will pass');