質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Capybara

Capybaraは、 Rubyで開発されているWebアプリケーションテストフレームワークです。Webブラウザ不要でブラウザ上のユーザー操作及びJavaScriptの挙動を自動化することができます。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

2442閲覧

RSpec・Capybaraを使用した、jQueryの自動スクロール(scrollTop)のテスト方法

yukihide1188

総合スコア44

Capybara

Capybaraは、 Rubyで開発されているWebアプリケーションテストフレームワークです。Webブラウザ不要でブラウザ上のユーザー操作及びJavaScriptの挙動を自動化することができます。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/09/12 11:54

前提・実現したいこと

Rails(devise)で作成した新規登録のformに、jQueryでエラーメッセージの表示とその箇所への自動スクロール機能を実装しました。
0. 未入力のままtext_fieldからフォーカスが外れるとエラーメッセージが表示される
0. そのまま新規登録しようとすると、submitは中断され、エラーメッセージがウィンドウ中央になるように自動でスクロールされる。

この機能をsystem specでテストしようと思ったのですが、記述方法が分からずうまくいきません。アドバイスいただけないでしょうか。

該当のソースコード

haml

1.new-user-title 2 新規登録 3 4 .new-user-form 5 = form_for(resource, as: resource_name, url: registration_path(resource_name), html: {id: 'new-user'}) do |f| 6 7 .new-user-employee 8 = f.label :employee_id, '社員ID', class: 'new-user-employee__title-label' 9 = f.text_field :employee_id, autocomplete: "username", id: 'user-employee', class: 'new-user-employee__input-text' 10 11 ------------------- (中略) ------------------- 12 13 .new-user-actions 14 = f.submit "新規登録", class: 'user-register-button'

jQuery

1(document).on('turbolinks:load', function(){ 2 $('#user-employee').blur(function(){ 3 if ($(this).val() == '') { 4 $(this).before(`<div id='presence-error' class='error-message'>社員IDを入力してください</div>`); 5 $(this).addClass('error-frame'); 6 }; 7 }); 8 9 $('#new-user').submit(function() { 10 if ($('div').hasClass('error-message')) { 11 let errorPosition = $('.error-message').offset().top 12 let whindowHalf = $(window).height() / 2 13 $('html, body').animate({scrollTop:(errorPosition - whindowHalf)}) 14 return false; 15 }; 16 }); 17});

RSpec

1RSpec.describe 'Users', type: :system do 2 describe '新規登録', js: true do 3 it '新規登録ボタンを押した時、エラー箇所まで自動スクロールされること' do 4 fill_in 'user[employee_id]', with: '' 5 click_on '新規登録' 6 expect(page).to have_content '社員IDを入力してください' 7 end 8 end 9end 10

上記の状態でRSpecを実行すると、jQueryの.submitの記述があってもなくてもテストが通ってしまいます。

試したこと

  • GitHub/Capybaraを参考に、page.save_screenshot('screenshot.png')でスクリーンショットを確認すると、ページ全体がブラウザ画面に収まってしまっていた。そこで、page.driver.browser.manage.window.resize_to(500, 100)をRSpecに追加し、ウィンドウのサイズを縮小。

=> 変化なし [原因] rspec + capybaraのpageの中身 - xengineer's diaryを参考にputs page.bodyでpageの中身を確認すると、hamlのbody全てが対象になっていました。

  • ecpect(page).to have_contentpage部分を現在ウィンドウで表示されている場所にすればいいと考えググってみる。

=> 見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

rails (6.0.3.2)
ruby (2.7.1)
rspec-rails (4.0.1)
capybara (3.33.0)
selenium-webdriver (3.142.7)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

スクロールすることを確かめたいのであれば、

page.execute_script('window.scroll(0, 1000)') # 適当なところにスクロール位置セットしておく click_on '新規登録' # sleep 1 スクロールに時間かかるだろうなので、適宜 sleep や待ち合わせるメソッドが必要かも scrollY = page.evaluate_script('window.pageYOffset') # スクロール位置取得 # scrollY = page.evaluate_script('document.documentElement.scrollTop') expect(scrollY).to eq(0) # 望む位置になっているか

投稿2020/09/12 15:55

編集2020/09/13 12:08
unhappychoice

総合スコア1531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukihide1188

2020/09/13 07:32 編集

ありがとうございます。 sleep 1 を設定したら、スクリーンショット上ではうまく動いているようなのですが、 やはりテストではjQuerynの記述があってもなくても結果が同じになってしまいます。 page.driver.browser.manage.window.resize_to(1000, 300) fill_in 'user[employee_id]', with: '' page.execute_script('window.scroll(0, 1000)') scrollY_b = page.execute_script('window.pageYOffset').to_i click_on '新規登録' sleep 1 scrollY = page.execute_script('window.pageYOffset').to_i expect(scrollY).to eq(0) 試しに scrollY = page.execute_script('window.pageYOffset').to_i をいろいろな位置に置いてみたのですが、全て値は0でした。 ( scrollY = page.execute_script('window.pageYOffset') とすると、 scrollY => nill となってしまったため、 .to_i を付けました)
unhappychoice

2020/09/13 12:08

失礼しました、 execute_script は値を返さないようなので、 evaluate_script でどうでしょうか
yukihide1188

2020/09/13 13:42

できました!ありがとうございます!! it '新規登録ボタンを押した時、エラー箇所まで自動スクロールされること' do page.driver.browser.manage.window.resize_to(1000, 300) fill_in 'user[employee_id]', with: '' click_on '新規登録' sleep 1 errorCenterPosition = page.evaluate_script('Math.floor($(".error-frame").offset().top - ($(window).height() / 2))') scrollY = page.evaluate_script('window.pageYOffset') expect(scrollY).to eq(errorCenterPosition) end 最終的にこんな感じになりました。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問