Ruby,Rails和TDD的新手。我正在使用RSpec与Capybara和Capybara webkit。
尝试测试页面上是否存在div元素。
测试代码:
require 'spec_helper'
describe "Login module" do
before do
visit root_path
end
it "should have a module container with id mLogin" do
page.should have_css('div#mLogin')
end
it "should have a module container with id mLogin", :js => true do
page.evaluate_script('$("div#mLogin").attr("id")').should eq "mLogin"
end
end
第一次测试通过但第二次测试失败了:
Login module should have a module container with id mLogin
Failure/Error: page.evaluate_script('$("div#mLogin").attr("id")').should eq "mLogin"
expected: "mLogin"
got: nil
在浏览器开发工具中使用JS并获取“mLogin”而不是nil。
有什么想法吗?感谢。
答案 0 :(得分:0)
find('div#mLogin')[:id].should eq 'mLogin'
请参阅doc:
#evaluate_script
Evaluate the given JavaScript and return the result. Be careful when using this with scripts that return complex objects, such as jQuery statements. execute_script might be a better alternative.
到目前为止,evaluate_script总是返回nil。
无论如何,你的第二次测试似乎是在测试水豚是否有效,因为你的第一次测试就足够了。
答案 1 :(得分:0)
一个可能的问题是have_css
匹配器支持Capybara的同步功能。如果没有立即找到选择器,它将等待并重试,直到找到它或超时为止。
在http://rubydoc.info/github/jnicklas/capybara#Asynchronous_JavaScript__Ajax_and_friends_
上有关于此的更多文档另一方面,evaluate_script
立即运行。由于这是您在访问页面后首先执行的操作,因此存在竞争条件:在页面加载完成之前,它可能会执行此脚本。
您可以尝试在页面上找到一个元素,直到
或者,您可以在调用synchronize
时将呼叫包裹起来以显式重试,但通常不建议这样做。对于这样的情况,使用Capybara的内置匹配器会更好。只有当没有内置的方法来完成你需要做的事情时,evaluate_script
方法才应该作为最后的手段使用,你需要非常小心以避免竞争条件。