gpt4 book ai didi

ruby - capybara 与 has_no_css 同步?

转载 作者:数据小太阳 更新时间:2023-10-29 08:46:53 25 4
gpt4 key购买 nike

自升级到 Capybara 2.4 后,我一直遇到这个问题。以前,这个 block 工作正常:

page.document.synchronize do
page.should have_no_css('#ajax_indicator', :visible => true)
end

意思是强制等到ajax指示符消失了再进行下一步。

由于上面的代码返回了一个 RSpec::Expectations::ExpectationNotMetError,所以同步不会重新运行该 block ,而只是抛出错误。不确定为什么这在我之前使用的版本中有效(我相信 2.1)。

synchronize block 仅重新运行返回如下内容的 block :

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 可能无法捕捉到它。

根据您的脚本,您可能会找到更可靠的指标。

最佳答案

have_no_css 匹配器已经在等待元素消失。问题似乎是在 synchronize block 中使用它。 synchronize 方法仅针对某些异常重新运行,不包括 RSpec::Expectations::ExpectationNotMetError

删除 synchronize 似乎做了你想做的事——即强制等待直到元素消失。换句话说,只需执行以下操作:

page.should have_no_css('#ajax_indicator', :visible => true)

工作示例

这是一个页面,比如“wait.htm”,我认为它重现了您的问题。它有一个链接,单击该链接会等待 6 秒,然后隐藏指示器元素。

<html>
<head>
<title>wait test</title>
<script type="text/javascript" charset="utf-8">
function setTimeoutDisplay(id, display, timeout) {
setTimeout(function() {
document.getElementById(id).style.display = display;
}, timeout);
}
</script>
</head>

<body>
<div id="ajax_indicator" style="display:block;">indicator</div>
<a id="hide_foo" href="#" onclick="setTimeoutDisplay('ajax_indicator', 'none', 6000);">hide indicator</a>
</body>
</html>

以下规范表明,通过使用 page.should have_no_css 而无需手动调用 synchronize,Capybara 已经强制等待。当只等待 2 秒时,规范失败,因为元素没有消失。等待 10 秒时,规范通过,因为元素有时间消失。

require 'capybara/rspec'

Capybara.run_server = false
Capybara.current_driver = :selenium
Capybara.app_host = 'file:///C:/test/wait.htm'

RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = [:should, :expect]
end
end

RSpec.describe "#have_no_css", :js => true, :type => :feature do
it 'raise exception when element does not disappear in time' do
Capybara.default_wait_time = 2

visit('')
click_link('hide indicator')
page.should have_no_css('#ajax_indicator', :visible => true)
end

it 'passes when element disappears in time' do
Capybara.default_wait_time = 10

visit('')
click_link('hide indicator')
page.should have_no_css('#ajax_indicator', :visible => true)
end
end

关于ruby - capybara 与 has_no_css 同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25254584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com