SeleniumとCapybaraでページ全体のスクリーンショットをとる

よくあるやつだけど、実は結構難しい。PhantomJsのメンテナンスが終了してしまったいま、実際に使うのは本物のブラウザになる。 しかしChromeはページ全体のスクリーンショットを取ることはできないのだ。そんなのスクロールすればいいし、ウィンドウサイズを変更することでも 大体なんとかなるためその挙動が問題になることはあまりないとは思う。 そもそもW3C的にはこの挙動が正しいらしい。 とはいえそういうわけにいかない時もあるのだ。

それじゃFirefoxを使えばいいのか、というとまたこれも違う。最新版のFirefoxとそのドライバーでは挙動がChromeと同じものになってしまった。 そんなわけでいろいろと試行錯誤を繰り返し、うまくいく組み合わせがなんとなく判明した。

  • Firefox 47.0
  • Selenium 2.53.1
  • selenium-webdriver gem 3.6.0

この組み合わせで、かつmarionetteを無効にしたらいけた。

require 'selenium-webdriver'
require 'capybara'
require 'headless'

Headless.new(destroy_at_exit: true).start

Capybara.register_driver :firefox do |app|
  caps = Selenium::WebDriver::Remote::Capabilities.firefox(marionette: false)
  Capybara::Selenium::Driver.new(app, {
    browser: :remote,
    url: 'http://localhost:4444/wd/hub',
    desired_capabilities: caps
  })
end

session = Capybara::Session.new(:firefox)
session.visit('http://localhost:8000')
session.current_window.resize_to(1140, 640)
session.save_screenshot('screenshot.png')

結局PhantomJsが一番便利だったんだけど、まぁ仕方ない。あれはもう古いのだ。