2013-11-27 4 views
5

私はCapybara、Cucumber、Poltergeistを使用しています。私は送信イベントをキャッチし、それを防ぐために(バックグラウンドでAJAXリクエストを行う)フォーム提出ボタンに付けられたJavaScript関数をテストしています。 AJAXの有無にかかわらず、ページは同じに見えるが、AJAXのアプローチははるかに高速で、ブラウジングエクスペリエンスなどを妨げない。カピバラで、ページが*リロードされていない(JavaScript onClickインターセプトが機能していない)ことをどのようにテストできますか?

実際にフォームが送信されなかったことをテストするには変更はリロードではなく動的AJAX呼び出しの結果ですか?

答えて

0

Capybaraは、ユーザーレベルの機能テストを目的としています。フォームにAJAXを使用するか、従来のフォーム送信を使用するかなど、実装の詳細をテストする簡単な方法はありません。エンドユーザーエクスペリエンスの観点からテストを書くことをお勧めします。

あなたが行うことができます物事のカップルがあります。

  • カピバラはファインダーとアサーションのための待機時間をサポートしています。 Capybara.default_wait_timeCapybara.using_wait_time、またはwaitオプションをアサーションメソッドに渡すことで、いくつか設定できます。待ち時間を短く設定すると、送信ボタンをクリックした結果がすぐに戻ることがわかります。

  • JasmineなどのJavaScriptユニットと統合テストフレームワークを参照してください。これは、イベントバインディングとAJAX呼び出しを設定するJavaScriptコードをテストするために使用できます。スパイを使用して、ボタンがクリックされたときに期待されるAJAX呼び出しが確実に行われるようにすることができます。

+0

ありがとうございました。ジャスミンはJSコードのためのものだと思っていました。ブラウザの一連のイベントのコンテキストでも使用できることを意味しますか? –

+0

これはJavaScriptのテストに使用できます。私はPhantomJSと、FirefoxとChromeの両方に頭を使わずに使ったことがあります。これは、CapybaraにJasmineテストランナーのブラウザをロードさせ、そのページに失敗がないことを主張します。 DOM相互作用のテストに役立つ[jasmine-jquery](https://github.com/velesin/jasmine-jquery)などの便利なライブラリがあります。 –

+0

私はこれを仕事に取り入れました。私はあなたに完全に同意しますが、リロードしていないページはユーザーエクスペリエンスまたは予想される動作の一部であると主張しています。思考? –

2

私は同じ問題を持っていたし、解決策を考え出した、おそらくない最高の一が、それは動作します:)

#support/reload.rb 
def init_reload_check 
    page.evaluate_script "window.not_reloaded = 'not reloaded';" 
end 

def not_reloaded 
    page.evaluate_script("window.not_reloaded") == "not reloaded" 
end 

#Ajax Test 
it "should not reload the page", js: true do 
    init_reload_check 
    click_link "Ajax Link" 
    expect(not_reloaded).to be_truthy 
end 
+0

ニース。私はリロードが起こるのを待つために私のテストで 'sleep 0.01'を追加しなければならなかったが、Ajax(WebSocketではなく)によってトリガーされなかったので、あなたはCapybaraの" Ajaxが起こるのを待つ" マジック。 –

+0

私は読みやすさのためにそれをさらに修正しました。新しい回答として投稿しました。あなたが気にしないことを願っています。 –

3

@jules'と答えたの修正版:

describe "My page", :js do 
    it "reloads when it should" do 
    visit "/" 

    expect_page_to_reload do 
     click_link "Reload me" 
    end 
    end 

    def expect_page_to_reload 
    page.evaluate_script "$(document.body).addClass('not-reloaded')" 
    yield 
    expect(page).not_to have_selector("body.not-reloaded") 
    end 
end 

EDIT2017-01-19:

実際の質問には奇妙には答えられなかったこの古い回答が見つかりましたが、反対側にしてください(ページがリロードされていることを確認してください)。

def expect_page_not_to_reload 
    page.evaluate_script %{$(document.body).addClass("not-reloaded")} 
    expect(page).to have_selector("body.not-reloaded") 
    yield 
    sleep 0.5 # Give it a chance to reload before we check. 
    expect(page).to have_selector("body.not-reloaded") 
end 

どちらの答えは、クラスを追加するためのjQueryに依存している:これは、我々は、ページがないリロードをしていることを確認するために我々のアプリで現在何をすべきかです。

0
feature "User creates comment", do 
    context "with JavaScript enabled", js: true do 

    scenario "creates comment via AJAX" do 

     initial_page_id = assign_page_id 

     # Perform AJAX action 
     ... 

     page_reloaded = current_page_id != initial_page_id 
     expect(page_reloaded).to eq(false) 

    end 

    def assign_page_id 
     page_id = SecureRandom.hex 
     page.evaluate_script "window.pageIdForTesting = '#{page_id}'" 
    end 

    def current_page_id 
     page.evaluate_script("window.pageIdForTesting") 
    end 

    end 

    context "without JavaScript" do 
    # Can be used if progressively enhancing 
    ... 
    end 
end 
関連する問題