2

我可以在与 capybara 的链接中执行 javascriptclick_link('next_page')吗?

链接如下所示:

<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=> true之前,我可以正常访问页面,但是,我注意到在:js=> true之后页面无法访问,这是我访问页面后遇到的错误:

在 2012-01-23 06:29:26 +0200 (5010.7ms) 开始 GET "/student_courses" for 127.0.0.1 更新 "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 "students"."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' WHERE "students"."id" = 1 HTML:------------ _ _ 内部服务器错误

内部服务器错误

无法回滚事务 - SQL 语句正在进行中
WEBrick/1.3.1 (Ruby/1.9.3/2011-10-30) 在 127.0.0.1:34718

那么,为什么 SQLite3::BusyException: 数据库现在被锁定了?!

4

3 回答 3

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。这就是水豚的用途。但也不要依赖“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
于 2013-03-06T23:31:24.460 回答
1

扩展 Alex 的评论 Capybara 不会执行 JS,除非它为给定的测试明确打开。

为此,请在您的描述块或单个测试上使用 :js => true ,例如。

describe "in such and such a context", :js => true do
   # some stuff
end
于 2012-01-22T23:19:54.250 回答
-1

它应该工作。使用 capybara,您实际上是通过浏览器测试您的应用程序,它的行为将相同。

于 2012-01-22T22:11:03.457 回答