关闭Capybara :: ElementNotFound /避免嵌套救援

时间:2018-07-18 12:26:32

标签: ruby-on-rails ruby selenium testing capybara

我遇到了在众多集成测试中共享的方法的问题。

问题是,我需要找到两个按钮之一,并且到目前为止,仅想出以下笨拙的语法来避免Capybara的ElementNotFound错误:

new_button = begin
      find(".button_one")
    rescue Capybara::ElementNotFound
      begin
        find('.button_two')
      rescue Capybara::ElementNotFound
        raise Capybara::ElementNotFound, "Missing Button"
      end
    end
new_button.click

这可以按预期工作:如果未找到第一个按钮,则单击第二个按钮。如果都不存在,则会引发错误。

尽管如此,我真的不喜欢嵌套的rescues,并希望整理一下。

感觉最简单的解决方案应该存在,尽管我没有在任何地方找到这个问题:有人知道在Capybara的nil中是否有返回find的选项方法,而不是引发异常?

例如,以下伪代码...

new_button = find('.button_one', allow_nil: true) || find('.button_two', allow_nil: true)
new_button ? new_button.click : raise(Capybara::ElementNotFound, "Missing Button")

...将是完美的。

否则,关于如何最好地挽救这两个错误并避免可怕的嵌套救援的任何建议?


脚注:该代码存在于一个庞大的现有结构中,该结构以前在不需要的地方可以正常工作。解决另一个问题已导致此问题,该问题已在整个套件中广泛使用。我很想调整电话并使用正确的元素(因此完全避免使用此方法),尽管今天晚些时候这将是一个大项目。

3 个答案:

答案 0 :(得分:3)

如果页面上只有一个按钮,最简单的解决方案是使用CSS逗号同时查找两个按钮

find(".button_one, .button_two").click

如果两个按钮都可能同时显示在页面上,那么您将获得歧义匹配错误,在这种情况下,您可以执行类似的操作

find(".button_one, .button_two", match: :first).click

all(".button_one, .button_two")[0].click

还可以使用Capybara提供的谓词has_css?/ has_xpath?/ etc来检查元素是否存在而不会引发异常。会给出类似

的代码
if page.has_css?(".button_one")
  find(".button_one")
else
  find(".button_two")
end.click

但是在这种情况下,使用CSS逗号肯定是更好的解决方案。

答案 1 :(得分:2)

尝试使用x路径// button [contains(@ class,'button_one')或contains(@class,'button_two'],如下所示,

new_button = begin
        find(:xpath, "//button[contains(@class,'button_one') or contains(@class, 'button_two']")
       rescue Capybara::ElementNotFound
        raise Capybara::ElementNotFound, "Missing Button"
      end

new_button.click

答案 2 :(得分:1)

我对Ruby不熟悉,因此我将保留指向Ruby docu和Capybara docu的链接。这个想法是使用find_elements代替find_element。为什么?如果找不到元素,find_elements将不会引发任何异常。伪代码是这样的:

new_button = find_elements('.button_one').size() > 0 ? find('.button_one') || find('.button_two')

而且您不再需要处理异常。