🎃
Playwright の無駄づかい
2021年8月現在、Ruby on Rails で使い捨て可能な E2E テスト環境をより手軽に手に入れる方法をまとめます。
概要
次の環境で Playwright server/client (not official feature) によるブラウザ操作を実現します。
この記事の目標は、簡単なフォーム操作をエンドツーエンドテストすることとします [1] 。
ただし、試験的な機能を使用しているため組み合わせなどで動作しなくなることがあります。
名称 | Version | Docker Image |
---|---|---|
Ruby | 3.0.2 | ruby:3.0.2-bullseye |
Ruby on Rails | 6.1.4.1 | |
Playwright | 1.14.1 | mcr.microsoft.com/playwright:v1.14.1-focal |
Turnip | 4.3.0 | |
Playwright client for Ruby | 1.14 | |
Playwright driver for Capybara | 0.1.5 |
扱わないこと
試していないので、次のような設定や比較は扱いません。
- PC上のブラウザを使う設定
- Docker イメージの軽量化や日本語対応
- Selenium with Puppeteer#connect や Cuprite との比較
- PlaywrightのBrowserType#connectOverCDP
- Python で同じようなことを試す
したごしらえ
E2E テスト対象は scaffold で生成した Blog システムを使用します。コンテナ内のソースコードには Visual Studio Code Remote - Containers などでアクセスしてください。
Docker
docker-compose.yml
version: "3.8"
services:
rails:
restart: "no"
image: rails:6.1.4
tty: true
environment:
- TZ=Asia/Tokyo
- RAILS_LOG_TO_STDOUT=true
- RAILS_SERVE_STATIC_FILES=true
ports:
- "3000:3000"
build:
context: .
dockerfile: Dockerfile.rails
args:
RUBY_VERSION: "3.0.2"
PLAYWRIGHT_VERSION: "1.14.1"
playwright:
restart: "no"
image: playwright:1.14.1
build:
context: .
dockerfile: Dockerfile.playwright
args:
PLAYWRIGHT_VERSION: "1.14.1"
Dockerfile.rails
ARG RUBY_VERSION
FROM ruby:${RUBY_VERSION}-bullseye
# See: https://github.com/nodesource/distributions
RUN set -eux; \
apt-get update; \
curl -fsSL https://deb.nodesource.com/setup_14.x | bash -; \
apt-get install -y --no-install-recommends \
\
nodejs \
; \
rm -rf /var/lib/apt/lists/*
# See: https://github.com/microsoft/playwright
RUN PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --global playwright@${PLAYWRIGHT_VERSION}
# See: https://railsguides.jp/getting_started.html
RUN gem install rails -v 6.1.4.1; \
rails new /opt/blog --database=sqlite3 -M -C -J -T --skip-webpack-install
WORKDIR /opt/blog
RUN rails db:create; \
rails generate scaffold Article title:string body:text; \
rails db:migrate
EXPOSE 3000
CMD [ "rails", "server", "--binding=0.0.0.0", "--port=3000" ]
Dockerfile.playwright
# See: https://playwright-ruby-client.vercel.app/docs/article/guides/playwright_on_alpine_linux#server-code
ARG PLAYWRIGHT_VERSION
FROM mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-focal
WORKDIR /root
RUN npm install playwright@${PLAYWRIGHT_VERSION} && ./node_modules/.bin/playwright install
# TODO: 必要であればフォントなどをインストールしてください。
EXPOSE 4545
CMD ["./node_modules/.bin/playwright", "run-server", "4545"]
正確ではありませんが、コンテナは下図のような関係になります。
Turnip などの設定
RSpec 経由で E2E を実行する最低限の設定をします。
Gemfile
group :test do
gem 'rspec', '~> 3.10'
gem 'rspec-rails', '~> 5.0', '>= 5.0.2'
gem 'turnip', '~> 4.0', '>= 4.0.1'
gem 'playwright-ruby-client', '~> 1.14'
gem 'capybara-playwright-driver', '~> 0.1.5'
end
.rspec
--require test_helper
--require turnip/rspec
spec/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'capybara/rspec'
require 'capybara_helper'
Dir.glob("spec/steps/**/*step.rb") { |f| load f, true }
config/environments/development.rb
# Backend host エラーの回避
config.hosts << 'rails'
Playwright client for Ruby + Playwright driver for Capybara
起動するブラウザを変えるには browser_type を変更すればよいはずです。
spec/capybara_helper.rb
require 'capybara-playwright-driver'
# Note: 最小限の変更にしたいので Playwright.create を Playwright.connect_to_playwright_server に置き換える
# See: https://github.com/YusukeIwaki/playwright-ruby-client/blob/1.14.0/lib/playwright.rb
# See: https://github.com/YusukeIwaki/capybara-playwright-driver/blob/0.1.5/lib/capybara/playwright/driver.rb#L46-L48
module CapybaraPlaywrightDriverPatch
private def playwright_execution
@playwright_execution ||= ::Playwright.connect_to_playwright_server('ws://playwright:4545/ws')
end
end
Capybara::Playwright::Driver.prepend(CapybaraPlaywrightDriverPatch)
# See: https://github.com/YusukeIwaki/capybara-playwright-driver
Capybara.register_driver(:playwright) do |app|
driver = Capybara::Playwright::Driver.new(app, browser_type: :firefox, headless: true,
viewport: { width: 480, height: 360 })
driver.on_save_screenrecord do |video_path|
# video_path: playwright container 内のパス
end
driver
end
Capybara.default_max_wait_time = 5
Capybara.default_driver = :playwright
Capybara.save_path = 'tmp/capybara'
Capybara.configure do |config|
config.default_driver = :playwright
config.javascript_driver = :playwright
end
Capybara.app_host = 'http://rails:3000'
テストコードの実行
実行したときの WebM を Gif に変換したもの↓
-
フォーム操作だけであれば Playwright である必要はありませんので、無駄づかいと言えるでしょう(タイトル回収ノルマ達成)。 ↩︎
Discussion
そのGemの作者です。ご紹介&興味深い無駄遣いありがとうございます。
たしかにdocker-composeだとリモート接続になるので、Capybaraドライバにもそのオプションが必要そうですね。
次のバージョンで対応しようと思います。https://github.com/YusukeIwaki/capybara-playwright-driver/pull/44https://rubygems.org/gems/capybara-playwright-driver/versions/0.1.6 で対応しました。
(ドキュメントも近々更新します)
コメントだけでなく Capybaraドライバ側のオプション対応までもいただけるとは。
大変ありがとうございます。
※僭越ながら記事の先頭にコメントへのリンクを追加させてもらいました。