puppeteer-rubyでChromeブラウザ自動操作

趣味で開発しているpuppeteer-rubyがだいぶまともに動くようになってきたので、このあたりで一筆を。

puppeteer-ruby爆誕のきっかけ

f:id:YusukeIwaki:20200605001527p:plain

そういえば過去の2記事(puppeteer-rubyを作ろうとして挫折した - YusukeIwakiのブログ, やっぱりPuppeteerをRubyから使えないと困るので、puppeteer-rubyを作ることにした - YusukeIwakiのブログ)には書いていなかった。puppeteer-rubyを作ろうと思った一番の理由を。

まず、Rubyで自動テストするならSeleniumがある。それなのにSeleniumではなくpuppeteerを使う最大の理由は... waitForSelector だ。

「まだかなーまだかなー」とポーリングでDOM要素が現れるのを待つSeleniumとは対照的に、「DOMに変化があったら都度おしえてねー」とリスナー仕掛けてDOM要素が現れるのを監視するのがpuppeteer。SeleniumではときどきDOM要素が現れるのを検知できないことがあるが、puppeteerは(MutationObserverがバグらない限りは)DOM要素が現れる瞬間を絶対に逃さない。

「Rubyで受け入れテストや自動テストを書きたいけど、Seleniumの精度だとしんどい」 っていう人はたぶん自分以外にも居るんじゃないか。

そんな思いからpuppeteer-rubyは誕生した。(支離滅裂w)

(2020.08.30 追記) Capybaraで運用中の受け入れテストをpuppeteer-rubyで補強することができる

「こんなこともできます」程度の内容ですが、別記事に載せてます

yusukeiwaki.hatenablog.com

「Capybaraで書いた受け入れテストが、何故かタイムアウトエラーで落ちて、リトライとか色々しんどい・・・」「けど、改めてCypressやCodeceptJSなどで再実装するのもしんどい・・・」という場合に。puppeteer-rubyはCapybaraを置き換えるものではなく共存することができるので、既存テストの弱い部分だけをpuppeteerのwaitForSelector/waitForNavigationで補強することができます!

最近のpuppeteer-rubyのアップデート

waitForSelectorは、2週間前くらいに実装した。

github.com

あとは、地味に写真のアップロードとかできないと困るので、ファイルのアップロードも実装した。

github.com

waitForSelectorで一気に気が抜けてしまったので、最近は実に低調である。

 

そんなことはどうでもいい。自動操作だ。

無駄な前置きは長すぎた。自動操作の話をしよう。

puppeteer-rubyをインストール

$ bundle init
$ echo 'gem "puppeteer-ruby"' >> Gemfile
$ bundle install

とりあえずggrksしてみよう。

qiita.com

ggrks.rb を作って

require 'puppeteer'

search_keyword = ARGV.join(" ")
search_keyword = "puppeteer" if search_keyword.empty?

launch_options = {
  # ブラウザ画面を表示しながら(ヘッドレスモードを無効にする)。
  headless: false,

  args: [
    # ゲストセッションで操作する。
    "--guest",

    # ウインドウサイズをデフォルトより大きめに。
    '--window-size=1280,800',
  ],

  # 人間味のある速度で入力/操作する。
  slow_mo: 50,
}

Puppeteer.launch(launch_options) do |browser|
  page = browser.pages.first || browser.new_page

  page.viewport = Puppeteer::Viewport.new(width: 1280, height: 800)

  page.goto("https://google.com/")
  page.type_text("input[name='q']", search_keyword)

  await_all(
    page.async_wait_for_navigation,
    page.keyboard.async_press("Enter"),
  )

  sleep 10
end

以下のように実行すると・・・

$ bundle exec ruby ggrks.rb

ぐりぐり動いて検索結果画面が出る。

f:id:YusukeIwaki:20200605225226p:plain

サンプルは書くモチベーションがなくなってきたので・・・

実はサンプルスクリプトのリポジトリを用意してあるw

github.com

今後も公開できるような(秘匿情報を含まない)スクリプトはどんどんアップしていこうと思う。

 

まとめ

ただの、puppeteer-rubyの宣伝でした。

まだちょっと不安定だけど、「Rubyで受け入れテストや自動テストを書きたいけど、Seleniumの精度だとしんどい」っていうのに共感するかたはぜひ使ってみてください。

rubygems.org

(2020.08.16追記: 0.0.11でだいぶ安定して動くようになりました。 puppeteer-ruby 0.0.11で完走率が劇的に改善。ブラウザの自動操作が快適に。 - YusukeIwakiのブログ )