我可以在与capybara click_link('next_page')
的链接中执行javascript吗?
链接如下所示:
<a onclick="$('#submit_direction').attr('value', '1');$('#quizForm').submit()" id="next_page" href="#">Next Question</a>
我在github阅读capybara,我可以点击提交按钮提交表格,如下所示:
click_on('Submit Answer')
但是,在我的情况下,我需要在链接中使用javascript提交表单,那么,如何测试里面有javascript的链接?是不是click_link('next_page')
足够了?
修改
设置:js=> true
后我的测试如下:
it "should pass when answering all correct", :js=>true do
login_as(student, :scope => :student)
visit ("/student_courses")
#page.execute_script("$('#submit_direction').attr('value', '1');$('#quizForm').submit()")
trace "HTML:------------", page.html
end
之前:js =&gt;是的,我可以正常访问该页面,但是,我注意到在以下页面之后无法访问该页面:js =&gt;是的,这是我访问该页面后得到的错误:
在2012-01-23 06:29:26开始获取127.0.0.1的“/ student_courses” +0200(5010.7ms)UPDATE“students”SET“last_sign_in_at”='2012-01-23 04:29:26.274285',“current_sign_in_at”='2012-01-23 04:29:26.274285',“last_sign_in_ip”='127.0.0.1', “current_sign_in_ip”='127.0.0.1',“sign_in_count”= 1,“updated_at” ='2012-01-23 04:29:26.276279'WHERE“学生”。“id”= 1 SQLite3 :: BusyException:数据库被锁定:UPDATE“students”SET “last_sign_in_at”='2012-01-23 04:29:26.274285',“current_sign_in_at” ='2012-01-23 04:29:26.274285',“last_sign_in_ip”='127.0.0.1',“current_sign_in_ip”='127.0.0.1',“sign_in_count”= 1,“updated_at” ='2012-01-23 04:29:26.276279'在哪里'学生“。”id“= 1 HTML:------------ _ _ 内部 服务器错误
内部服务器错误
无法回滚事务 - 正在进行的SQL语句
WEBrick / 1.3.1(Ruby / 1.9.3 / 2011-10-30)at 127.0.0.1:34718
那么,为什么SQLite3 :: BusyException:数据库现在被锁定了?!
答案 0 :(得分:8)
我花了8个小时来解决类似的问题,然后我找到了解决方案。修复很简单,我可以哭。
首先,诊断
你得到“SQLite3::BusyException: database is locked
”的原因是你正在启动一个异步线程,即表单提交,最终会失去对你的测试主线程的“数据库写”竞争。实际上,当您的测试已经完成并且正在运行“每个”之后的数据库清理例程(在spec_helper中定义)时,表单操作才刚刚开始尝试运行业务逻辑(它依赖于您的测试之后的数据) :每个钩子都在忙着毁灭)。
如果测试单击AJAX POST按钮然后终止而不断言有关视图更改的内容,则更有可能发生此问题。
其次,修复
事实证明,Capybara旨在“同步”您的所有请求。但只有你暗中让它。请注意,在您提交表单后,您没有让Capybara查看您的页面。因此,它认为您已完成并将您的数据从范围中删除(而您的表单提交线程在后台挂起。)
只需在测试结束时添加以下代码行,它就会突然发挥作用:
page.should_not have_content "dude, you forgot to assert anything about the view"
第三,让它漂亮
不要使用execute_script。这就是Capybara的用途。但也不要依赖“click_on”,因为它不是一个很好的抽象。你需要对它的内部结构了解太多。相反,使用CSS选择器,如:
page.find("#submit_button").click
还有一件事 - 你的测试不应该试图操纵DOM。一个好的Selenium测试假设必须遵循普通用户遵循的相同步骤。
总结
it "should pass when answering all correct", :js => true do
login_as(student, :scope => :student)
visit ("/student_courses")
page.find(".my-js-enabled-button").click
page.find("#submit_button").click
# Synchronizes your view to your database state before exiting test,
# Therefore makes sure no threads remain unfinished before your teardown.
page.should_not have_content "dude, you forgot to expect / assert anything."
end
答案 1 :(得分:1)
要扩展Alex的评论,除非为给定的测试明确启用,否则Capybara不会执行JS。
要执行此操作,请使用:js =&gt;对于描述块或单个测试都是如此。
describe "in such and such a context", :js => true do
# some stuff
end
答案 2 :(得分:-1)
它应该工作。使用水豚,你基本上是通过浏览器测试你的应用程序,它会表现相同。