Capybara无法识别动态添加的DOM元素?

17

在使用Capybara和Selenium时,我似乎无法测试使用jQuery实现的slick JavaScript功能。期望的行为是,当用户单击“添加资源”链接时动态生成表单。Capybara可以单击该链接,但无法识别新的表单元素(例如"resource[name]")。

是否有一种方法可以重新加载Capybara的DOM,或者这个gem中有一些我还没有学到的元素?

提前感谢!

==编辑==

目前正在尝试Selenium的:

wait_for_element 

方法。

==编辑==

我尝试执行以下操作时,不断收到“空类的'wait_for_element`方法未定义”的错误:

@selenium.wait_for_element

看起来使用特定的方法,或者也许是使用访问我期望的 DOM 元素的巨大选择器的 wait_for 方法是正确的操作方式,但现在尝试获取 selenium 会话开始变成一件很棘手的事情。

3个回答

17

我在RSpec中使用基于Webdriver的Capybara驱动程序,我按如下方法进行配置和使用,它一定可以处理JS,并且不需要重新加载DOM。关键是使用wait_until和一个条件,当你的AJAX响应完成时,该条件将为真。

before(:each) do
  select_driver(example)  
  logout
  login('databanks') 
end

 def select_driver(example)
   if example.metadata[:js]
    Capybara.current_driver = :selenium
  else
    Capybara.use_default_driver
  end
end

it "should let me delete a scenario", :js=>true do
    select("Mysite Search", :from=>'scenario_id')  
    wait_until{ page.has_content?('mysite_searchterms')}    
    click_on "delete"     
    wait_until{ !page.has_content?('mysite_searchterms')}   
    visit '/databanks'
    page.should_not have_content('Mysite Search')
  end

昨晚我还想出了一个方法来减缓webdriver的速度,就像这样,如果你想以慢动作观看:

   #set a command delay
   require 'selenium-webdriver'

   module ::Selenium::WebDriver::Remote
     class Bridge
       def execute(*args)
         res = raw_execute(*args)['value']
         sleep 0.5
         res
       end
     end
   end  

正如其他人提到的,如果你在等待元素时出现超时,你可以考虑增加这个时间:

Capybara.default_wait_time = 10

感谢 @ebeland。现在,在我们工作的测试中使用类似方法已经有很多个月了,wait_until 方法无疑是正确的选择 :) - kelly.dunn
4
wait_until 已被移除出 Capybara 2.0.0。请参考这篇博客文章 - David Tuite

7

来自Capybara文档:

在使用异步JavaScript时,您可能会遇到尝试与尚未出现在页面上的元素进行交互的情况。Capybara通过等待元素出现在页面上自动处理此问题。

您可以尝试增加等待时间来提高成功率:

Capybara.default_wait_time = 10

如果这并没有帮助到您,我建议您联系GitHub项目中的某些人员,写信给邮件列表或提交问题报告。

3
+1。Capybara在诸如'has_selector?','has_css?'等方法调用中使用此默认等待时间。因此,您可以使用这些方法等待元素出现,例如:has_css?("a#myinput", :visible => true),它会等待元素出现在屏幕上然后再继续执行。 - bergyman
我应该把 Capybara.default_wait_time = 10 放在哪里? - Incerteza
1
如果你有 spec/rails_helper.rb 文件,就在其中加入 @AlexanderSupertramp,否则加入到 spec/spec_helper.rb 文件中。 - thomasfedb
Cucumber和RSpec的目录/spec有什么关系? - Incerteza
@AlexanderSupertramp 没什么!这个问题是关于如何在 RSpec 中使用 Capybara,与 Cucumber 无关。 - thomasfedb

0

即使 wait_until 已从 Capybara 2.0 中删除,但仍然很有用,并可从下面的代码中获取:

 def wait_until(delay = 1)   
 seconds_waited = 0   
 while ! yield && seconds_waited < Capybara.default_wait_time     
    sleep delay     
    seconds_waited += 1   
  end   
  raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield 
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接