Ruby on Rails開発のインターン (Day 16)

こんにちは、皆さん!

今日はどうやったらグーグルマップ上でマーカーをクリックするのかを見つけようと思う。これは以前のに比べれば、そんなに難しくはないだろうと思うが、後でマーカーから出た情報をもとにテストを書くのに少し時間がとられる気がする。あんまり時間を取られすぎなければいいが。


  • トピック:
  1. capybaraでスクショをとる
  2. capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法
  3. 僕がcapybaraでグーグルマップ上のマーカーをクリックさせた方法


  • 疑問:


  • 問題:
  1. capybaraでグーグルマップ上のマーカーをクリックする方法を探す


  • 学習した内容:
  1. capybaraで自動でスクショを取る方法


  • 今後やってみたいこと:


  • リソース:
  1. Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)
  2. GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails
  3. How can I click on a google map with capybara to create a marker - Stack Overflow


capybaraでスクショをとる

リソース: Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)

僕が試しに直接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"になっているのが確認できる。よって、テスト成功である
f:id:Coding_Studio:20180726045704p:plain

capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法

リソース: GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails

ところで、もっと簡単にスクショを取る方法を見つけた。それは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テストの結果:
f:id:Coding_Studio:20180726083605p:plain


さらに、マップ上の複数のマーカーをクリックさせるという内容も実行した。解決法はいたってシンプルで、僕がマーカーオブジェクトにアクセスでき、そこからマーカーの位置を知ることができるから、マップの中心をその新しいマーカーの位置にずらすことで先ほどと同じ場所をもう一回クリックすればいいのだ。
下記のビデオにこの時、自動で複数のマーカーを1個ずつクリックしたものが記録されている。

CapybaraとRspecでGoogle mapのテスト!

まとめ

capybaraでマップ上のマーカーをクリックする方法を見つけることができたことがすごく嬉しかった。stackOverFlow上の人がサイト上の答えはちゃんと動かなかったと言っていたので、最初はとても心配した。まあ、でも、最終的に手に入れたかったものが自分の手で入ったので、大きな達成感を感じられた。
明日はこのcapybaraテストの内容を職場のプログラムに組み込めれるようにがんばりたい。明日もいいことありますように!!


ご精読ありがとうございました。では、また次回まで✌



Day 17はこちら↓↓
programming-shop.hatenablog.com


Day 15はこちら↓↓
programming-shop.hatenablog.com