rails 3.1,capybara-webkit,如何在链接中执行javascript?

时间:2012-01-22 20:44:34

标签: ruby-on-rails-3 capybara capybara-webkit

我可以在与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:数据库现在被锁定了?!

3 个答案:

答案 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)

它应该工作。使用水豚,你基本上是通过浏览器测试你的应用程序,它会表现相同。