LoginSignup
3
3

More than 5 years have passed since last update.

[rails] system specにおけるtake_screenshotの問題を雑に修正する

Last updated at Posted at 2018-06-29

rspec-rails 3.7でsystem specが追加されてfailしたら自動でschreenshotを取ってくれて便利なんですが、いくつか問題があったので雑に修正しました。

注意) 当記事では著者が書いたコードを指して(パッチの当て方や文字列の末尾を取得しているところなどを)「雑に」と言っています。
参考にさせていただいた記事を指しているわけでは決してありません。
Capybara+headless-chrome でフルサイズのスクリーンショットを撮るは素晴らしい記事です。

ファイル名が長すぎてエラーになる。

rspecのネストが深くなるとschreenshotのファイル名が長くなりすぎてエラーが発生してしまいます。

https://github.com/rails/rails/issues/32346
こちらでissueがあがっているんですが、5.2.1 milestone から外されてしまい、対応は少し待たないといけないようです。

仕方ないのでモンキーパッチで雑に対応します。

# frozen_string_literal: true

require 'action_dispatch/system_testing/test_helpers/screenshot_helper'

module ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper
  LINUX_MAX_FILE_NAME_LENGTH = 255
  EXT_NAME = '.png'

  # https://github.com/rails/rails/blob/a3ecf4ff1dbb92259e1627bdd09546211f25d906/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb#L24
  def take_screenshot
    save_image
    puts display_image
  rescue Errno::ENAMETOOLONG
    max_length = LINUX_MAX_FILE_NAME_LENGTH - EXT_NAME.length
    omitted_image_name = image_name[- max_length, max_length]

    path = Rails.root.join("tmp/screenshots/#{omitted_image_name}#{EXT_NAME}")
    page.save_screenshot(path)

    puts "[Screenshot]: #{path}"
  end
end

このファイルをspec/supportにおいて、読み込んであげればOKです。

headless-chrome でフルサイズのスクリーンショットが撮れない

フルサイズのスクリーンショットを取るためにはcapybaraのsave_screenshotfull: trueのオプションを与える必要があるのですが、何故かそうなっていません。↓

しかも、現状 headless-chrome だとfull: trueのオプションを与えてもフルサイズのスクリーンショットが撮れないようです。

こちらの記事(Capybara+headless-chrome でフルサイズのスクリーンショットを撮る)を参考に更にモンキーパッチを当てます。

# frozen_string_literal: true

require 'action_dispatch/system_testing/test_helpers/screenshot_helper'

module ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper
  LINUX_MAX_FILE_NAME_LENGTH = 255
  EXT_NAME = '.png'

  # https://github.com/rails/rails/blob/a3ecf4ff1dbb92259e1627bdd09546211f25d906/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb#L24
  def take_screenshot
    resize_window_to_full_screen

    save_image
    puts display_image
  rescue Errno::ENAMETOOLONG
    max_length = LINUX_MAX_FILE_NAME_LENGTH - EXT_NAME.length
    omitted_image_name = image_name[- max_length, max_length]

    path = Rails.root.join("tmp/screenshots/#{omitted_image_name}#{EXT_NAME}")
    page.save_screenshot(path)

    puts "[Screenshot]: #{path}"
  end

private

  # https://qiita.com/g-fujioka/items/091c400814800f1280ff
  def resize_window_to_full_screen
    # rubocop:disable Metrics/LineLength
    width  = Capybara.page.execute_script('return Math.max(document.body.scrollWidth , document.body.offsetWidth , document.documentElement.clientWidth , document.documentElement.scrollWidth , document.documentElement.offsetWidth);')
    height = Capybara.page.execute_script('return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);')
    # rubocop:enable Metrics/LineLength

    Capybara.current_session.driver.browser.manage.window.resize_to(width, height)
  end
end

これでフルサイズのスクリーンショットが撮れるようになりました。

快適!

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3