2

カピバラとのリンクでJavaScriptを実行できますclick_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)で127.0.0.1のGET "/student_courses"を開始しました。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 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)at 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

もう 1 つ、テストで 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

それはうまくいくはずです。カピバラを使用すると、基本的にブラウザーを介してアプリケーションをテストし、同じように動作します。

于 2012-01-22T22:11:03.457 に答える