PlaywrightをRubyから使うコードをCloud Native BuildpacksとCloud Runで動かす
やりたいこと
実ブラウザを使い、認証が必要で API のないサイトから自動で必要な情報を取得し、それをチェックする処理を定期的に行いたい。
業務でもプライベートでも意外と欲しくなるものだと思う。
これが Google Apps Script から API で取得できる程度のものであれば面倒な仕組みを作らなくても最初からアリモノだけで処理できるが、任意のサイトの情報を扱いたいとなると難しい。
実現方法の選択肢
じゃあどうするかというと、選択肢は以下のような感じになると思う。
- インフラ
- 生サーバ(VPS)
- 手作りコンテナ
- 何らかのレールに乗った自動生成コンテナ
- ブラウザ
- Selenium WebDriver / WebdriverIO
- Cypress
- Playwright
- 言語
- JavaScript
- JavaScript 以外
今回はすべて最後の選択肢で、
- 何らかのレールに乗った自動生成コンテナ
- Playwright
- JavaScript 以外
でやってみたい。
cf. SeleniumとPlaywrightとCypressとWebdriver.ioのアーキテクチャーについて
選択理由
WebDriver はすでに経験があるし、wait に失敗してコケるテストの課題など、実際に困っているので Playwright の経験値を稼いでおきたい。Playwright 自体初めてなのにあえて Ruby でやっていく。
インフラはぶっちゃけ生サーバでやるのが生サーバを触れる人には楽なんだけど、生サーバを使い始めると便利でアレもコレもやらせたくなって捨てにくくなりがちだし、そうなると保守、セキュリティなど面倒ごとが増えてしまう。簡単に実現できるが維持が面倒。IaC 化もなかなか大変。個人的には Docker イメージを自分でメンテするのはまったく好きではないけど、ディスポーザブルであることを重視して今回は上記のセットで考える。Cloud Native Buildpacks はベースイメージのメンテナンスを素から考える必要がなく、概ねクラウドベンダーに丸投げでき、かつビルドも賢いところがメリットとして大きいと考えている。
成果物
wtnabe/example-cnbp-playwright-ruby
利用しているインフラ
- Cloud Run
- Cloud Build
- Cloud Storage + FUSE
Cloud Storage + FUSE については Cloud Run + Cloud Storage FUSE試してみた (2024-02-11) | あーありがち に詳しく書いてあるので参照してもらえるとありがたい。
感想
Cloud Native Buildpacks はまだ builder の成熟度が足りてないので工夫が必要。これほんとにもったいない。
Playwright でブラウザの環境を準備するのは普段使っているローカルの環境だとすごく簡単だけど、必要なライブラリの足りていない Linux 上で再現するのはあれこれ準備が必要。予想はついていたことではあるけど、ちょっと面倒。
Playwright からのブラウザの操作は確かにやや速い感じがする。WebDriver で動いていたテストケースを Playwright に置き換えて計測しているわけではないのであくまで参考程度ではあるが、手元で Chromium を起動して試行錯誤している感覚はかつてより早く感じる。(単純に手元の PC が速くなっている可能性もある。)
Playwright 用の API がブラウザ上の JS のよくあるそれとやや趣が異なり、戸惑う。しかも Ruby なので Playwright Integration が自動生成してくれるコードとも若干異なり、やや効率がよくない印象。とは言え基本的な部分は大きく変わらない。標準サポートの Python に寄せてあるっぽい?
すでに Ruby ベースのテストコードがあってそれの高速化を図りたい、WebDriver ではタイミングの調整が大変、といった課題がない場合は、あえて Ruby で Playwright を選ぶのはイマイチかもしれない。簡単なコードを動かしたいだけなら JS で動かして、その成果物が生成されたタイミングで Ruby なりなんなり別の言語での処理にスイッチしてあげる方が、全体の効率はよいかもしれない。
メモリは意外と Cloud Run 標準の 512 MB でも Chromium + 日本語フォントでなんとか動く。
ここまできたらあとは
- 手元で動作を練っていく
- 自動デプロイで反映
- Cloud Scheduler で定期実行(これは Cloud Run の Web UI から手動でセットしてもそんなに問題なさそう)
をセットすればオッケー。結構イケるんじゃないかな。
以下は単なるメモ。
やったこと
- Playwright を利用できるように run image および Cloud Native Buildpacks の buildpack と extension を用意
- Google Cloud Build でインフラの準備からデプロイをすべて自動化
- 成果物に Cloud Build 用の設定も入れてある
分かったこと
注意点
- playwright は playwright そのもののインストールのあとに
playwright install
でブラウザのインストールも必要 - 通常の
playwright install
ではシステムのホームディレクトリ以下にインストールしようとするが、Cloud Native Buildpacks の run image のユーザー cnb のホームディレクトリは実行時にクリアされているのか、何度試してもインストール済みのバイナリを取り出すことはできなかったPLAYWRIGHT_BROWSERS_PATH=0
と環境変数をセットするとプロジェクトの ./node_modules/ 以下にインストールしてくれるので、それを利用する
- Cloud Native Buildpacks の google-22 builder は multi buildpack への対応が不十分で、Ruby と Node.js の両方を利用している場合に npm の install が自動で走らない
- 回避策として post-buildpack の機能が使える
- Pack CLI 0.33 の PPA は壊れている。少なくとも Ubuntu 22.04 の環境に add-apt-repository しようするとなぜか存在しない Ubuntu の release の source を追加しようとして update に失敗してしまう
- Pack CLI : CNCF Buildpacks
- 今回は仕方ないので手動でゴニョゴニョしたが、こういう不備はマジでカジュアルにごっそり時間持っていくので困る
改めて分かったこと
- Cloud Native Buildpacks の extension は pack 0.33 時点ではまだ experimental feature なので config で enable にしておく必要アリ
- 今回はビルド用の sh script の中で enable してるので絶対忘れない
- Cloud Native Buildpacks の heroku 22 builder は extension には対応していない