2020年12月現在、puppeteerとplaywright どっち選んだらいいの？

今年の1月に突如 [microsoft/playwright](https://github.com/microsoft/playwright) が出て、「なに？puppeteerはオワコン？」と一瞬思いましたが、playwrightが出てからもpuppeteerはTypeScript化したりしていますし、いまのところどちらも活発に開発されています。
「puppeteerとplaywrightはどっち使えばいいの？」に対して、2020年12月現在の答えはおそらく「使いたいほうを使えばいい」です。

ただ、「使いたいほう」ってなんやねん？というところがググってもあまり情報が出てこないこともあり、今回の記事では、この選ぶ手がかりになる情報を少し投じておこうかなと思います。

## PythonやC#でも使いたい？

puppeteerは現在のところJavaScriptのライブラリ一本です。
**playwright** はPythonとC#のバインディングがあります。

[microsoft/playwright-python](https://github.com/microsoft/playwright-python)
[microsoft/playwright-sharp](https://github.com/microsoft/playwright-sharp)

とくにC#のほうは、**もともと [puppeteer-sharp](https://github.com/hardkoded/puppeteer-sharp)の開発者が作った hardkoded/playwright-sharp がベースとなってmicrosoft/playwright-sharpが誕生している**ことから、C#ユーザはplaywright-sharpを選択するのが賢明かもしれません。


参考まで、PythonとC#以外の言語については↓の記事でまとめています。
[いろいろな言語に移植されたPuppeteerっぽいライブラリまとめ](https://qiita.com/YusukeIwaki/items/a958a7ebada0369fafe0)

## 対応ブラウザ

多くの記事では、「playwrightが全ブラウザサポートしていて最強！」みたいな感じで言及されがちですが、ここは内部実装をしっかり理解して選びたいところです。

### Chrome

言わずもがな、puppeteerとplaywright両方使えます。

### Firefox

ここが割とライトユーザーには誤解されているところです。

puppeteerはFireffox Nightlyを自動操作できます。
playwrightはFirefox Nightlyを自動操作できません。代わりに、独自に改造を入れたFirefox（playwright経由でダウンロードできるもの）のみを自動操作できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/9323df3a-367b-9a39-eb11-a243fcfce8fd.png)

この事実はplaywrightのREADMEにもあまりわかりやすい形では書かれていなくて、↑だけみると「Playwright最高！これ使わない手はないぞ！」って思ってしまいますよね。

Firefoxに対する考え方がpuppeteerとplaywrightで大きく異なっていることは、下記のissueコメントでplaywrightのメンテナーが書いています。
https://github.com/microsoft/playwright/issues/1765#issuecomment-613178363

あとは、ブラウザのダウンローダや起動パラメータのソースコードを読むことでも違いが明確にわかります。

#### puppeteerのソースコード

:point_down: ブラウザダウンローダ
https://github.com/puppeteer/puppeteer/blob/a16cb8cef4536d70699636c10cd58fb5455471cc/src/node/BrowserFetcher.ts

Firefoxは
https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central
から latestなdmgなりtar.bz2なりをダウンロードするようになっています。素直。


:point_down: 起動パラメータ
https://github.com/puppeteer/puppeteer/blob/a16cb8cef4536d70699636c10cd58fb5455471cc/src/node/Launcher.ts#L270

Chromeと同様に、 `--remote-debugging-port=0` をつけてFirefoxを起動するようになっています。

#### playwrightのブラウザダウンローダのソースコード

:point_down: ブラウザダウンローダ
https://github.com/microsoft/playwright/blob/1ca30fe6e7bce97c05441ae07dbfac30a3df379c/src/install/browserFetcher.ts

Firefoxは
https://playwright.azureedge.net
から、 `/builds/firefox/%s/firefox-ubuntu-18.04.zip` みたいな独自にビルドされたっぽいものをダウンロードするようになっています。


:point_down: 起動パラメータ
https://github.com/microsoft/playwright/blob/1ca30fe6e7bce97c05441ae07dbfac30a3df379c/src/server/firefox/firefox.ts#L75

独自の `-juggler-pipe` というパラメータで、独自命令を送り込むパイプやソケットをこじ開けているみたいです。

ふつうにネットからダウンロードしてきたFirefox Nightlyにこの起動パラメータを指定しても、無効です。playwright経由でダウンロードしてきた独自改造版Firefoxしか動かせ\ません。

### 独自改造版Firefoxのほうが高機能

前述の[issueコメント](https://github.com/microsoft/playwright/issues/1765#issuecomment-613178363)にもサラッと書いてありますが、playwrightがFirefox Nightlyを自動操作できるように対応しないのには、Firefox Nightlyは一部のCDPにしか対応していない未完成状態であるから、という要因も大きそうです。

わかりやすいところでいうと、「入力フォームに**絵文字を入力**できること」みたいなテストの用途では、Firefox Nightlyは使えません。`page.type("🍰")` とかやると、そこでエラーが起きます。

puppeteerの単体試験のコードを見ると、Firefoxでは絵文字の試験をスキップしています。

* https://github.com/puppeteer/puppeteer/blob/a16cb8cef4536d70699636c10cd58fb5455471cc/test/keyboard.spec.ts#L353

playwright（改造されたFirefox）のほうはスキップしていないし、実際に動きます。

* https://github.com/microsoft/playwright/blob/3d6194e8a1580c991c8f13300531388b75ca7701/test/keyboard.spec.ts#L300

---

少し横道それましたが、Firefoxに関してはおおむね以下のような判断基準になります。

* 「Firefoxでしか動かないWebサービス」みたいなものを自動操作したいだけであれば、どっちをつかってもOK
* 「ユーザが使うFirefoxの正式版でテストしないといけない」みたいな状況であれば、どっちも使えない
* Dockerで使うなら、特定のバージョンのFirefox Nightlyをあらかじめ入れておけば動くpuppeteerのほうが簡単
* 絵文字入力とかrequest interceptionなどニッチな操作をしたいときには playwrightのほうを使う必要がある

### Safari

魔改造されたSafariでもよければplaywrightを使いましょう

### Microsoft Edge (Chromiumベースの)

puppeteerでもplaywrightでも使えます。
CDPをフルで使えるChromiumがベースなので。


## まとめ

* puppeteer = CDP(Chrome DevTools Protocol)をベースにしたシンプルなツールキット
* playwright = puppeteerっぽいAPIでいろんなものを自動操作できるように、手段を問わずいろいろやってるツールキット
    * Firefoxに対する考え方がpuppeteerとは大きく異なる

playwrightの勢いはすごいですが、個人的にはChromeが動けば十分なので、puppeteerを愛用しています。
これが来年、吉と出るか凶と出るか....