嘿所有,我正在尝试修复我的众多场景,通过JQuery测试高级AJAX和客户端屏幕构建的页面,并且遇到大量问题。
主要是,我很难知道某些AJAX请求何时完成。我试过把睡眠延迟,但这是一个长期的坏主意。我还尝试了一些我在网上找到的方法来检查AJAX调用是否全部完成,但这些方法似乎不够稳定。
我开始更多地探索Selenium并找到了waitForXXX函数。兴奋我把它们扔进我的黄瓜步骤但没有运气。我目前的测试用例是一个动态加载的网格,通过AJAX获取数据。 (Jquery Datagrid插件)。我正在寻找第一个非标题行的数据,然后点击它。单击元素的代码是:
page.all(:css, "#{arg1} tr")[1].click();
有时这种方法有效,通常不会因为尚未加载行。所以我在努力:
waitForElementPresent("css=#{arg1} tr:nth-child(1)")
在单击该行之前,但无论何时到达该行代码,我都会从ruby中得到一个很好的错误:
stack level too deep (SystemStackError)
我做错了什么,是否有更好的方法来编写这些步骤以确保它们真的等待AJAX调用完成?
请注意,应用程序本身运行正常 - 这只是为了让我的测试代码可靠地变为绿色。
答案 0 :(得分:1)
我在下面的步骤(我们从其他人那里取得)中获得了很好的运气。它是originally geared对于culerity / celerity(我们曾经使用过一段时间),但它对纯黄瓜/水豚来说非常好:
When /^I wait for the AJAX call to finish$/ do
keep_looping = true
while keep_looping do
sleep 0.10
begin
count = page.evaluate_script('window.running_ajax_calls')
keep_looping = false if count.respond_to?(:to_i) && count.to_i == 0
rescue => e
raise e
end
end
sleep 0.20
end
您可能需要调整循环睡眠和睡眠后。这些值适用于同时运行12个核心测试的Mac Pro。在极少数情况下,我们又增加了1秒等待。
答案 1 :(得分:1)
在尝试与元素交互之前,我倾向于调用has_css?
方法,例如
page.should have_css("#{arg1} tr")
Capybara将重试,直到(可配置的)默认等待时间到期。一旦完成此步骤,您就应该能够按预期单击元素 - 如果元素在等待时间到期之前没有出现,则步骤将失败。
答案 2 :(得分:0)
感谢Alistar关于page.should have_css的提示,我编写了一个通用示例。如果有多个AJAX同时进行,这可能不会起作用,但它对我来说非常轻量级。
在我的application.html.erb中,我添加了一个简单的空白div:
<div id="ready"/>
然后在我的应用程序启动时加载的javascript文件中,我添加了这一行,以便在进行AJAX调用时隐藏div。
$('#ready').ajaxStart(function(){$(this).hide();}).ajaxStop(function(){$(this).show();});
然后在我对Cucumber的常见步骤中,我有一个非常简单的“等待AJAX”步骤定义:
When /^I wait for AJAX$/ do
page.should have_css("#ready")
端
首次测试时,这似乎有效。它是另一种皮肤猫的方式,所以它可能不会一直起作用,但在我的情况下它对我来说很好而且轻巧。