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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 6

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

RSpec

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

1668閲覧

railsのRspecの結合テストコードで要素をクリックした時に背景色が変化したことを真偽値で表現できるのか?

hitosi0317

総合スコア1

Ruby on Rails 6

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

RSpec

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/06/29 06:44

編集2022/01/12 10:55

実現したいこと

railsの結合テストコードで要素をクリックした時に背景色が変化したことを真偽値で表現したい。

詰まっている問題

現在結合テストコードで要素をクリックするところまでは,行けたんですがクリックした時にCSSが適用されているかどうかの確認ができておりません。要素の内容を確認する(Capybara::Node::Matcher)検索メソッドなどを一通り確認して試しているんですがうまいこと行かないです。組み合わせの問題なのかスペルミスでうまいこといっていないのか?

(例)こんな感じで試しました。
イメージ説明

実際のページ

画像: ブロックをクリックするとCSSが適用される.
![イメージ説明

実際のコード

views/motions/index.html.erb

Ruby

1<div class="plan-image"> 2<div class="container text-center "> 3<%if user_signed_in? %> 4<% if @motion != nil && current_user.motion != [] && current_user.motion.last.created_at.strftime("%Y%m%d") == @now.strftime("%Y%m%d")%> 5<h1 class="text-center">本日の予定</h1> 6<div class="row g-5"> 7<div class="border p-3 col-lg-6 col-sm-12"> 8<h2 class="center"><%= current_user.nickname%>さんの本日の時間割</h2> 9 <div class="plan border fs-2 py-3 w-75 mx-auto" data-id=<%= current_user.motion.last.id %> data-check=<%= current_user.motion.last.checked %>> 10<% if current_user.motion.last.plans1.present?%> 11 <%= current_user.motion.last.plans1 %> 12 <%= current_user.motion.last.count1.strftime('%H:%M') %> 13 </div> 14<% end %> 15<% if current_user.motion.last.plans2.present?%> 16 <div class="plan border fs-2 py-3 w-75 mx-auto" data-id=<%= current_user.motion.last.id %> data-check=<%= current_user.motion.last.checked %>> 17 <%= current_user.motion.last.plans2 %> 18 <%= current_user.motion.last.count2.strftime('%H:%M') %> 19 </div> 20<% end%> 21<% if current_user.motion.last.plans3.present?%> 22 <div class="plan border fs-2 py-3 w-75 mx-auto" data-id=<%= current_user.motion.last.id %> data-check=<%= current_user.motion.last.checked %>> 23 <%= current_user.motion.last.plans3 %> 24 <%= current_user.motion.last.count3.strftime('%H:%M') %> 25 </div> 26<% end %> 27<% if current_user.motion.last.plans4.present?%> 28 <div class="plan border fs-2 py-3 w-75 mx-auto" data-id=<%= current_user.motion.last.id %> data-check=<%= current_user.motion.last.checked %>> 29 <%= current_user.motion.last.plans4 %> 30 <%= current_user.motion.last.count4.strftime('%H:%M')%> 31 </div> 32<% end %> 33 <% if current_user.motion.last.plans5.present?%> 34 <div class="plan border fs-2 py-3 w-75 mx-auto" data-id=<%= current_user.motion.last.id %> data-check=<%= current_user.motion.last.checked %>> 35 <%= current_user.motion.last.plans5 %> 36 <%= current_user.motion.last.count5.strftime('%H:%M') %> 37 </div> 38<% end %> 39<h2 class="center">メモ<h2> 40<div class="border w-75 mx-auto p-3" , style="word-wrap: break-word;"> 41<p><%= current_user.motion.last.memo %></p> 42</div> 43</div>

spec/factories/motions.rb

rspec

1FactoryBot.define do 2 factory :motion do 3 weight { '33' } 4 plans1 { '学習' } 5 plans2 { '学習' } 6 plans3 { '学習' } 7 plans4 { '学習' } 8 plans5 { '学習' } 9 count1 { '15:30' } 10 count2 { '16:30' } 11 count3 { '17:30' } 12 count4 { '18:30' } 13 count5 { '19:30' } 14 memo { 'テスト確認します' } 15 association :user 16 end 17end

spec/system/motions_spec.rb

RSpec.describe '予定完了機能', type: :system, js: true do before do @user = FactoryBot.create(:user) @motion = FactoryBot.build(:motion) end context '予定完了作成' do it '予定をクリックするとCSSが適用される' do # サインする sign_in(@user) # 予定作成ページへのボタンがあることを確認する expect(page).to have_link('本日の予定を設定する') # 予定作成ページへ移動する visit new_motion_path # フォームに値を入力する fill_in 'motion_weight', with: @motion.weight fill_in 'motion_plans1', with: @motion.plans1 fill_in 'motion_count1', with: @motion.count1 fill_in 'motion_plans2', with: @motion.plans2 fill_in 'motion_count2', with: @motion.count2 fill_in 'motion_plans3', with: @motion.plans3 fill_in 'motion_count3', with: @motion.count3 fill_in 'motion_plans4', with: @motion.plans4 fill_in 'motion_count4', with: @motion.count4 fill_in 'motion_plans5', with: @motion.plans5 fill_in 'motion_count5', with: @motion.count5 fill_in 'motion_memo', with: @motion.memo # 送信するとmotionモデルのカウントが1上がることを確認する expect do find('input[name="commit"]').click end.to change { Motion.count }.by(1) # トップページに遷移することを確認する expect(current_path).to eq(root_path) # 予定をクリックする binding.pry page.all('.plan')[0].click page.all('.plan')[1].click page.all('.plan')[2].click page.all('.plan')[3].click page.all('.plan')[4].click # CSSが適用されたことを確認する end end

最後のCSSが適用されているかどうかの確認を表現したいんですが、これがうまいこといかない。
わかる方がいらっしゃいましたらお力添えお願いたします.

追記

javascript/packs/checked.js

javascript

1function check() { 2 const plans = document.querySelectorAll(".plan"); 3 plans.forEach(function (plan) { 4 if (plan.getAttribute("data-load") != null) { 5 return null; 6 } 7 plan.setAttribute("data-load", "true"); 8 plan.addEventListener("click", () => { 9 const planId = plan.getAttribute("data-id"); 10 const XHR = new XMLHttpRequest(); 11 XHR.open("GET", `/motion/${planId}`, true); 12 XHR.responseType = "json"; 13 XHR.send(); 14 XHR.onload = () => { 15 if(XHR.status != 200) { 16 alert(`Error ${XHR.status}: ${XHR.statusText}`); 17 return null; 18 } 19 const item = XHR.response.plan; 20 if (item.checked === true) { 21 plan.setAttribute("data-check", "true"); 22 } else if (item.checked === false) { 23 plan.removeAttribute("data-check"); 24 } 25 }; 26 }); 27 }); 28} 29setInterval(check, 1000);

javascript/stylesheets/application.scss

css

1@import "bootstrap"; 2 3 4div[data-check="true"] { 5 background-color: red; 6} 7 8 9.top-image{ 10 background: url(https://publicdomainq.net/images/202106/05s/publicdomainq-0055890rbu.jpg); 11 background-size: cover; 12} 13 14 15a,li{ 16 color: black; 17 text-decoration: black; 18 list-style: none; 19}

page.all('.plan')[0].matches_style?( 'background-color' => 'rgb(255, 0, 0)' )
page.all('.plan')[0].matches_style?( 'background-color' => 'red' )
このような指定の仕方をするとCSSが適用されていてもfalseを返されてしまう。

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

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

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

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

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

suama

2021/07/01 22:48

> 最後のCSSが適用されているかどうかの確認を表現したいんですが、これがうまいこといかない。 試されたコードはありますか? こういうMatcherを使ってみたけど、値が取れなかったとかいうのがあれば、追記いただけると。
hitosi0317

2021/07/04 16:27

返信ありがとうございます。 大変遅くなって申し訳ありません一応上記のように追記したんですけど.matches_style?というmatcheを使うのが正しいのか、うまいこといかないんですよね。何か他に試す方法がありましたらよろしくお願いします。
guest

回答1

0

こんばんは。
page.all('.plan')[0].click .... の処理で、クリックのイベントでAjaxリクエストを送信して、その結果を受けてCSSを変更している、で良いでしょうか。

Capybaraのテストではうまくテストできなくても、ブラウザでの操作では、背景色の変更は正しくできていると想定しております。

動かさないとなんとも言えないのですが、よくあるのが、Ajaxの処理を待たずにテスト(マッチャーでの確認)が進んでしまうといった点です。

wait_for_ajax で検索すると、ajaxの処理を待ってからテストをすると言った記事がいくつか出てくると思います。

こんな感じのメソッドを定義して、マッチャーの前に挟んでいたりしました。
なにかヒントになれば幸いです。

ruby

1 def wait_for_ajax 2 Timeout.timeout(Capybara.default_max_wait_time) do 3 loop until finished_all_ajax_requests? 4 end 5 end 6 7 def finished_all_ajax_requests? 8 page.evaluate_script('jQuery.active').zero? 9 end

投稿2021/07/05 12:50

suama

総合スコア1997

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問