Ruby on Rails開発のインターン (Day 16)
こんにちは、皆さん!
今日はどうやったらグーグルマップ上でマーカーをクリックするのかを見つけようと思う。これは以前のに比べれば、そんなに難しくはないだろうと思うが、後でマーカーから出た情報をもとにテストを書くのに少し時間がとられる気がする。あんまり時間を取られすぎなければいいが。
- トピック:
- 疑問:
- 問題:
- capybaraでグーグルマップ上のマーカーをクリックする方法を探す
- 学習した内容:
- capybaraで自動でスクショを取る方法
- 今後やってみたいこと:
- リソース:
- Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)
- GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails
- How can I click on a google map with capybara to create a marker - Stack Overflow
capybaraでスクショをとる
僕が試しに直接page.save_screenshot('screenshot.png')
というコードをposts_controller_spec.rb
内で実行しようとしたら、失敗して、下記のエラーメッセージが出てきた。
Selenium::WebDriver::Error::WebDriverError: Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
それで、このサイトにある指示通り、インストールしたのち、 今度はこの
$ export PATH=$PATH:/usr/local/bin/ $ whereis geckodriver geckodriver: /usr/local/bin/geckodriver
ここまで設定ができたら、capybaraテストを実行したときに、URLの左側にロボットのマークが表示されるはず。これはロボットが自動でそのページに指定された行動をとることを表す。そして、私たちはその一連の動作をこのページでライブで見れるということだ。
そして、そのデモが終わると、スクショが/tmp/capybara/screenshot.png
で見つかるでしょう。このフォルダーは.gitignore
でネット上には送られないようになっているので、心配無用。(まあ、でも、逆に見つけにくかったけど笑)
僕は下記のコードで実行して、クリックした後にボタンの内容が"Thank you"に変わるというコード。
<div id="map" style="width: 400px; height: 400px;"></div> <button id="button" onclick="changeContent()">Click Me!</button> <%= javascript_tag do %> function initialize(){ var map_center = new google.maps.LatLng(51.5, -0.12); var map = new google.maps.Map(document.getElementById('map'), {zoom: 15, center: map_center}); var center_marker = new google.maps.Marker({position: map_center, map: map}); var info = "<p>Success!</p>"; var infowindow = new google.maps.InfoWindow({ content: info }); center_marker.addListener('click', function(){ infowindow.open(map, center_marker) }); } function changeContent(){ document.getElementById('button').innerHTML = "Thank you"; } <% end %>
下のは実際にcapybaraに撮られたscreenshot.png
。"Click Me!"が"Thank you"になっているのが確認できる。よって、テスト成功である
capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法
ところで、もっと簡単にスクショを取る方法を見つけた。それはcapybara-screenshot
ジェムを使うことだ。使うためにはまず、Gemfile
に下記のようにジェムを入れる。
gem 'capybara-screenshot', :group => :test
僕はRspecを使っているからここより先の内容はRspecを使う際のインストラクションになる。ほかの媒体を使う場合はこのサイトを参照にしてください。
そしたら、rspec_spec.rb
の中に下記のを入れる (僕の場合、require 'capybara/rspec'
を他のところからインポートしているが、下記のを入れるときは必ずrequire 'capybara/rspec'
より下に入れてください。)
require 'capybara-screenshot/rspec'
そしたら、もうスクショをとるためのコードを書く準備は整った!
僕の場合は、下記のを古いバージョンのスクショと入れ替える感じでposts_controller_spec.rb
に追加した。
Capybara.save_path = "app/assets/images" Capybara::Screenshot.screenshot_and_save_page
1行目はスクショがどこに保存されるかで、2行目のコードでスクショを保存する。
そしたら、驚くことにスクショだけでなく、ディベロッパーツールで表示されるhtmlコードまでもがapp/assets/images
に保存されていた。
僕がcapybaraでグーグルマップ上のマーカーをクリックさせた方法
within_frame(locator_of_frame_with_map) do map = find(locator_of_map).native page.driver.browser.action.move_to(map, x, y).click.perform end
まあ、でも、これはなぜだかわからないが残念ながらうまくいかなかったので、within_frame
のくくりを消した。また、僕は下記のようにマップを実行しているから、
<div id="map"></div>
下記のようにルビーコードを書いた
map = find('#map').native page.driver.browser.action.move_to(map, 200, 190).click.perform
説明はこうだ:
- 1行目でマップオブジェクトにたどり着く。よって、2行目でマップに何かできる。
- 2行目でマウスを(x, y)=(200, 190)のポイントに行かせた。これは400x400のマップの中心のやや上である。
- この場所を選んだ理由はそこがちょうどマップの中心に位置するマーカーのクリックできるところであるからだ。
- そして、その場所でcapybaraにクリックをさせる。これはつまりマーカーの詳細を表示するようにしたことになる。
最初はマップ内の座標を得ようと思ったが、できず、考えてみた結果、僕たちがマップ上にクリックするときだって画面の中心という感じでしか画面上のものをとらえることはできないから、このxとyの座標はすごく腑に落ちた。
以下がcapybaraテストの結果:
さらに、マップ上の複数のマーカーをクリックさせるという内容も実行した。解決法はいたってシンプルで、僕がマーカーオブジェクトにアクセスでき、そこからマーカーの位置を知ることができるから、マップの中心をその新しいマーカーの位置にずらすことで先ほどと同じ場所をもう一回クリックすればいいのだ。
下記のビデオにこの時、自動で複数のマーカーを1個ずつクリックしたものが記録されている。
CapybaraとRspecでGoogle mapのテスト!
まとめ
明日はこのcapybaraテストの内容を職場のプログラムに組み込めれるようにがんばりたい。明日もいいことありますように!!
ご精読ありがとうございました。では、また次回まで✌