両方のフォームで同じフィールド( "Email")を持つ2つのフォームにアクセスするスペックに問題があります。手動でスリープしないと、カピバラさんはテストの2番目の部分での最初の訪問から「メール」フィールドを見つけているようです。
# visit the first form and fill out a subscription
visit new_front_form_subscription_path(@web_form_1.id)
fill_in "Email", with: "[email protected]"
fill_in "Field 1", with: "my first data"
click_button "Subscribe"
# visit the second form and fill out a subscription
visit new_front_form_subscription_path(@web_form_2.id)
sleep 1
fill_in "Email", with: "[email protected]"
fill_in "Field 2", with: "my second data"
click_button "Subscribe"
睡眠がそこに入ると、スペックは飛行色で通過します。スリープなしでは、2番目のフォーム送信は検証エラーを受け取ります-空白の「Email」値のせいです。
これを処理する適切な方法はありますか?仕様に手動スリープを導入するのは嫌いです。私はむしろ、カピバラにすでにページ上にあるもの、またはそれらの線に沿った何かの概念を無視するように伝える方法が欲しいです。
ありがとうございました。
これを使用して解決できる方法がいくつかあります。
2ページ目にのみ存在する別のロケーターを使用して、「Eメール」フィールドを選択します。
find('#second_page #email').set('[email protected]')
スリープの代わりに2番目のページが読み込まれるのを待つステートメントを記述します。
visit new_front_form_subscription_path(@web_form_2.id)
expect(page).to have_css('locator_present_only_at_second_page')
fill_in "Email", with: "[email protected]"
上記の答えは正しいですが、大規模なテストスイートがある場合、各ページで一意の要素を見つける必要があるため、実装するのは困難です。 RailsのMichael Hartl学校を卒業している場合、これを解決する簡単な方法があります。Hartlは、すべてのコントローラアクションに対して異なる@title
インスタンス変数を設定することを教えています。これはapplication.html.erbで使用され、すべてのページにHTMLタイトル要素を設定します。
私は確かにそうしています、そしてそれはページが適切にロードされなかったために失敗した私のすべての不安定なテストを修正する非常に簡単な方法を可能にしました。タイトルタグが表示されていないため、見つかりません。だから私がしたことは、application.html.erbの最後に次のコードを入れました。
<%= content_tag :div, "[#{title}]", class: 'rspec_eyes_only' if Rails.env.test? %>
これにより、テストモードの場合、角かっこで囲まれたタイトルテキストのdivが挿入されます。それから私はRails_helper.rbに入るヘルパーを書きました
def wait_for_page_load(title)
find('div.rspec_eyes_only', text: title)
end
正しいタイトルをテストする別のヘルパーが既にあるので、wait_for_page_load
を追加するように変更しました。
def title_is_correct(title)
full_title = "#{BaseTitle} | #{title}"
wait_for_page_load "[#{full_title}]"
expect(page.title).to eq full_title
end
これらの簡単な変更で、ほとんどすべての不安定なテストがクリアされました。
上記のAndreyの2)を使用した場合は、 holdon gem をチェックして、要素のロードを待機するブロックを作成してから、fill_in
メソッドは、その要素が読み込まれたら、.
通常、この方法で行うことができます。たとえば、モーダルポップアップ(または別のページ)が読み込まれた後に表示されるボタンをクリックするには、次のブロックをマクロファイルに追加します。
def wait_until_modal
page.has_css?('.modal')
end
ここで、クラス.modalはポップアップページのにあります。