【发布时间】:2019-10-17 08:33:10
【问题描述】:
自从升级到 Capybara 2.4 后,我一直遇到这个问题。以前,这个块工作正常:
page.document.synchronize do
page.should have_no_css('#ajax_indicator', :visible => true)
end
意思是强制等到ajax指示符消失后再继续下一步。
由于上面返回RSpec::Expectations::ExpectationNotMetError,同步不会重新运行块,而是抛出错误。不知道为什么这在我之前使用的版本中有效(我相信是 2.1)。
synchronize 块仅重新运行返回以下内容的块:
Capybara::ElementNotFound
Capybara::ExpectationNotMet
以及某个驱动程序添加到该列表中的任何内容。
查看 Justin 的回复以获得更全面的解释和不使用 synchronize 的示例,或者查看我的回复以获得直接解决方案。
跟进:我已经重新审视了这个问题,所以这里有一些提示:
1) document.synchronize 通常没有什么用处,正如其他人所提到的,大多数查找器都有内置的等待。您可以在有意义的情况下使用wait: 0 手动强制它不要等待。
请注意,因此,以下内容不等效:
!assert_css('#ajax_indicator')
assert_no_css('#ajax_indicator')
前者会等到元素存在,而后者会等到元素不存在,即使它们在逻辑上是等价的。
2) 导致我们最初插入同步的问题是由于各种鸡和蛋的问题。
#ajax_indicator 在这种情况下会在有活动加载时出现,然后消失。我们无法区分指标还没有出现,出现了然后消失了。
虽然我还没有 100% 解决这个问题,但提高我们测试可靠性的方法是寻找指标来确保页面加载达到某个点,例如
do_thing_that_triggers_ajax
find('#thing-that-should-exist')
assert_no_selector('#ajax_indicator', visible: true)
这与断言 #ajax_indicator 存在然后断言它不存在不同,因为在这种情况下,如果 ajax 发生得太快,capybara 可能无法捕捉到它的作用。
根据您的脚本,您可能会找到更可靠的指标。
【问题讨论】:
-
其实Capybara的用户不应该直接使用
synchronize。 -
我不明白为什么不这样做,它是公开记录在案的。不过,我完全有可能使用不正确(如elabs.se/blog/53-why-wait_until-was-removed-from-capybara 所述)。
-
如您所见,它适用于必须使用
native的情况。此类案件数量非常少见。是的,你用错了。