Slide 1

Slide 1 text

2025/09/21 フロントエンドカンファレンス東京 Playwrightはどのように クロスブラウザを サポートしているのか

Slide 2

Slide 2 text

nus3(なすさん)

Slide 3

Slide 3 text

Playwright使ってますか

Slide 4

Slide 4 text

Playwrightを で使ってますか クロスブラウザ

Slide 5

Slide 5 text

Playwrightはクロスブラウザをサポート https://playwright.dev/

Slide 6

Slide 6 text

Playwrightはクロスブラウザをサポート playwright.config.ts Playwrightで操作する ブラウザをconfigファイル で指定できる https://playwright.dev/docs/browsers#run-tests-on-different-browsers

Slide 7

Slide 7 text

Playwrightはクロスブラウザをサポート https://playwright.dev/docs/api/class-browser 対応するブラウザで
 新しいPageを作成し、 指定したURLへ遷移する 実装例

Slide 8

Slide 8 text

Playwrightはクロスブラウザをサポート https://playwright.dev/docs/api/class-browser firefox、chromium、webkit
 どれを使っても
 この部分の実装は変わらない

Slide 9

Slide 9 text

今日話すこと

Slide 10

Slide 10 text

今日話すこと 上記のコードを例に、 Playwrightはなぜ同じコードで Chromium、WebKit、Firefoxを操作できるのか というのを見ていきます

Slide 11

Slide 11 text

Playwrightからブラウザへは どんなコマンドが送られるのか

Slide 12

Slide 12 text

Playwrightで確認できるログ https://github.com/microsoft/playwright/blob/main/docs/src/debug.md#verbose-api-logs DEBUG環境変数による詳細なログ出力をサポート

Slide 13

Slide 13 text

Playwrightで確認できるログ DEBUG=pw:protocolを指定することで Playwrightとブラウザ間で送信したコマンドと 受信したレスポンスのログが確認できる

Slide 14

Slide 14 text

このログをもとに Playwrightから送信された コマンドをブラウザごとに見る

Slide 15

Slide 15 text

Playwright → Chromium 関連するログだけ出力して整形してもらうのをClaudeさんにお願いしました 以下のようなコマンドを送信している Browser.getVersion Target.createBrowserContext Target.createTarget Page.enable Page.navigate

Slide 16

Slide 16 text

Playwright → Firefox 以下のようなコマンドを送信している Browser.enable Browser.getInfo Browser.createBrowserContext Browser.newPage Page.navigate

Slide 17

Slide 17 text

Playwright → WebKit 以下のようなコマンドを送信している Playwright.enable Playwright.createContext Playwright.createPage Playwright.navigate

Slide 18

Slide 18 text

それぞれ比べてみると

Slide 19

Slide 19 text

browser.newPage() page.goto() Target.createBrowserContext Page.navigate Browser.createBrowserContext Page.navigate Playwright.createContext Playwright.navigate ※関連してそうなコマンドを並べただけなので、厳密には違うかも。そんな感じなんだ〜ぐらいの温度感で見てください

Slide 20

Slide 20 text

当たり前かもしれないけども ブラウザによって Playwrightが送っている コマンドは違う

Slide 21

Slide 21 text

Chromiumの場合 https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-createBrowserContext https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-navigate Chrome DevTools Protocolで定められたコマンドを送ってる

Slide 22

Slide 22 text

Firefoxの場合 Playwright's Firefox version matches the recent Firefox Stable build. Playwright doesn't work with the branded version of Firefox since . it relies on patches Each version of Playwright needs specific versions of browser binaries to operate. You will need to use the Playwright CLI to install these browsers. Playwright CLIからインストールされるFirefoxのバイナリには Playwrightによって されている パッチが適用 Playwrightを動作させるためには特定バージョンのブラウザのバイナリが必要 事前にPlaywrightのCLIを使ってインストールする https://playwright.dev/docs/browsers#introduction https://playwright.dev/docs/browsers#firefox

Slide 23

Slide 23 text

Firefoxの場合 https://github.com/microsoft/playwright/blob/main/browser_patches/firefox/patches/bootstrap.diff diffファイルからどのようなパッチが適用されたか確認できる このbootstarp.diffの運用などを明記してる 記載は見つけられなかったが この差分だと、firefoxを起動した際に
 juggler-pipeオプションを指定していた場合、 pipeで標準入力受け取って、標準出力してね みたいな変更が入っていることが読み取れる

Slide 24

Slide 24 text

Firefoxの場合 パッチが適用されたFirefoxでは、Playwrightからのコマンド を受け取れるようになっている また、パッチにはPage.navigateなどのコマンドを 受け取ったら、該当する操作をFirefox側で行うような実装が
 含まれていそう

Slide 25

Slide 25 text

Firefoxの場合 https://github.com/microsoft/playwright/blob/main/browser_patches/firefox/juggler/protocol/PageHandler.js#L388 リポジトリには、例えばPage.navigateコマンドを Firefox側ではどう処理するかの実装もありそう

Slide 26

Slide 26 text

Firefoxの場合 https://github.com/microsoft/playwright/blob/main/browser_patches/firefox/juggler/protocol/PageHandler.js#L388 Firefox側では最終的にbrowsingContext.loadURIといった
 関数を使って、指定したURLへの遷移をしてそう

Slide 27

Slide 27 text

WebKitの場合 Playwright doesn't work with the branded version of Safari since . Instead, you can test using the most recent WebKit build. it relies on patches Firefoxと同様にPlaywright CLIからインストールされる WebKitのバイナリにはPlaywrightによって をが適用されている
 パッチ https://playwright.dev/docs/browsers#webkit

Slide 28

Slide 28 text

WebKitの場合 https://github.com/microsoft/playwright/blob/main/browser_patches/webkit/patches/bootstrap.diff diffファイルからどのようなパッチが適用されたか確認できる 21000行以上あるdiff... Firefoxではコマンドの実装は別ファイルに あったりしたけども、WebKitはdiffに結構変更 が書いてあった印象

Slide 29

Slide 29 text

WebKitの場合 このdiffファイルの中で、Playwright.navigateなどのコマンド を受け取った際にWebkitでどのような処理をするかを
 定義していそう Playwrightの各コマンドの定義をしたり、 各コマンドの実装をしてそう

Slide 30

Slide 30 text

各ブラウザにパッチを 当てることでクロスブラウザを サポートしてるのすごい

Slide 31

Slide 31 text

ただ、各ブラウザに パッチ当てるの大変そう とも思うわけです

Slide 32

Slide 32 text

各ブラウザで同じコマンドを 送れるようにならないかしら

Slide 33

Slide 33 text

そんな仕様が 策定されつつあります

Slide 34

Slide 34 text

https://www.w3.org/TR/webdriver-bidi/ Bidirectional WebDriver Protocol WebDriverを拡張した仕様 WebSocketを介した双方向通信 この仕様に沿った実装を各ブラウザがしていれば、
 同じコマンドが使える

Slide 35

Slide 35 text

https://wpt.fyi/results/webdriver/tests/bidi?label=master&label=experimental&aligned&q=tests%2Fbidi ブラウザ側の実装が進む web platform testsのダッシュボードでの WebDriver BiDiの実装状況 https://fxdx.dev/cdp-retirement-in-firefox/ Firefox 141ではCDPのサポートが完全に 削除。WebDriver BiDiへの移行を推奨

Slide 36

Slide 36 text

Puppeteer WebdriverIO Selenium https://pptr.dev/webdriver-bidi https://webdriver.io/blog/2024/08/15/webdriverio-v9-release/ https://www.selenium.dev/documentation/webdriver/bidi/ ツール側もサポートが進む

Slide 37

Slide 37 text

Playwrightでも WebDriver BiDiを サポートするための 実装が試験的に進んでいる リリースノート等にも記載はなくて、まだ実験的なサポートの段階っぽい

Slide 38

Slide 38 text

PlaywrightでWebDriver BiDiを使う 例えば_bidiChromiumを使うことで、WebDriver BiDiを試せる 現在はChromiumとFirefox用の実装が進められている

Slide 39

Slide 39 text

Chromium Firefox WebDriver BiDiで送られるコマンド ChromiumでもFirefoxでも 同じコマンドが使われている session.new browsingContext.create browsingContext.navigate

Slide 40

Slide 40 text

WebDriver BiDiで送られるコマンド https://www.w3.org/TR/webdriver-bidi/#command-browsingContext-create https://www.w3.org/TR/webdriver-bidi/#command-browsingContext-navigate それぞれのコマンドの仕様もちゃんと確認できる

Slide 41

Slide 41 text

browsingContext.create browsingContext.navigate WebDriver BiDiを使った場合 ※関連してそうなコマンドを並べただけなので、厳密には違うかも。そんな感じなんだ〜ぐらいの温度感で見てください browser.newPage() page.goto()

Slide 42

Slide 42 text

Playwrightの クロスブラウザサポートの の仕組みを見てみて

Slide 43

Slide 43 text

ブラウザごとにパッチを当てるの大変そうだし、
 それを実現してるPlaywrightすごい WebDriver BiDiの仕様策定や実装が進めば パッチをあてない純粋なブラウザをPlaywrightでも
 扱えるようになりそう Playwrightが提供するパッチを当てたブラウザを
 インストールしなくてもよくなる 統一された仕様によって各ブラウザ間での挙動も
 担保されそう WebDriver BiDi楽しみ