Capybara RSpec 匹配器在等待元素?

Capybara RSpec matchers waiting for elements?

在使用 Capybara + RSpec 编写测试 framework/tests 时,我遇到了这个测试元素不存在的建议:

expect(page).to have_no_button('Save')   # OK
expect(page).not_to have_button('Save')  # Bad

我很困惑为什么,直到我看到这样说:

Use should have_no_* versions with RSpec matchers because should_not have_* doesn’t wait for a timeout from the driver.

这是真的吗?如果不是...从页面对象模型 perspec 是否有一种方法来检查和 return 是否存在 <element> 是否更有意义(我通常使用 .visible?) 这样你就可以使用 rspec 匹配器来做 expect(page_object).to be_method_visibleexpect(page_object).not_to be_method_visible ?

而不是必须在页面对象中编写 2 个单独的方法(除非 not_to 确实不会等待)

有关我在页面对象模型中的断言方法的示例,这是我检查 "logout link"

时所做的
def logged_in?
    logout_text.visible?
end

private
def logout_text
    find 'a', text: 'Log Out'
end

然后在规范中我会说: expect(page_object).to be_logged_in

所以我会对其他元素使用类似的东西。

我不知道你是从哪里看到这个建议的(也许它真的很老)但是对于任何 "recent" 版本的水豚(至少过去 4 年),当使用水豚提供的匹配器时,它是不正确。

假设 have_buttonhave_no_button 是 Capybara 提供的匹配器(不是 RSpecs 内置 have_xxx => has_xxx? 匹配器调用您在页面对象上定义的 has_button? 方法) 你给出的两个例子

expect(page).to have_no_button('Save')
expect(page).not_to have_button('Save')

将表现相同。他们将检查按钮是否存在,如果 return 不存在,或者如果 Capybara.default_max_wait_time 秒已经过去并且按钮在页面上仍然可见,则引发异常。