PuppeteerからPlaywrightへ：移行する価値はある？

[![Group36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/e0000cf9-fb66-ce34-20dc-8b43609aa4e7.png)](https://leapcell.io/?lc_t=q_playvspup)

# PuppeteerからPlaywrightへ：この移行は価値があるのか？

皆さん、こんにちは！PuppeteerからPlaywrightへの切り替えを検討している方はいますか？この移行はどのくらい簡単か、または難しいのでしょうか？そして本当に価値があるのでしょうか？コードレベルで予想外の変更はあるのでしょうか？Playwrightにはどんな新しくて面白い機能が隠されているのでしょうか？心配しないでください。この記事ではこれらの面白いことについて話します。

## PuppeteerとPlaywrightの現状大開示
一見すると、この2つのツールには多くの共通点があります。しかし、ここ2年間で、それらの開発速度は異なる馬力の2台のスポーツカーのように、徐々に開きを空けています。Playwrightは精力的に開発されており、Puppeteerを凌ぎました。この強い勢いにより、多くの人がPlaywrightに切り替えています。この記事では、具体的にどのように移行するか、またこの変更が私たちにもたらすクールな新機能について詳しく説明します。記事は少し長いですが、内容はとてもシンプルで学びやすいです！

## なぜ移行するのか？
以前、Cypress、Selenium、Playwright、Puppeteerの比較テストを行いました（詳細は記事のリンクをクリック）。簡単にまとめると、以下の理由があります：
 - Playwrightは非常に頻繁にアップデートされ、Puppeteerよりもはるかに多くの新機能があります！
 - 現実世界のエンドツーエンド（E2E）テストでは、Playwrightは優れたパフォーマンスを発揮し、テストケースを極めて高速に実行します（詳細は記事のリンクを参照）！
 - Playwrightはより安定しており、信頼できるパートナーのようです。
 - GitHub、Twitter、Slackなどのコミュニティでは、Playwrightがかなり人気があり、一方Puppeteerのコミュニティは少し寂れているようです。

## 変更リストの比較
まず、比較表を見てみましょう。数分間見渡して、その後で詳しく調べましょう。

| Puppeteer | Playwright |
| ---- | ---- |
| puppeteer.launch(...) | playwright.chromium.launch(...) |
| browser.createIncognitoBrowserContext(...) | browser.newContext(...) |
| page.setViewport(...) | page.setViewportSize(...) |
| page.waitForSelector(selector) <br> page.click(selector); | page.click(selector) |
| page.waitForXPath(XPathSelector) | page.waitForSelector(XPathSelector) |
| page.$x(xpath_selector) | page.$(xpath_selector) |
| page.waitForNetworkIdle(...) | page.waitForLoadState({ state: 'networkidle' }) |
| page.waitForFileChooser(...) | 削除され、異なる方法で処理されます。 |
| page.waitFor(timeout) | page.waitForTimeout(timeout) |
| page.type(selector, text) | page.fill(selector, text) |
| page.cookies([...urls]) | browserContext.cookies([urls]) |
| page.deleteCookie(...cookies) | browserContext.clearCookies() |
| page.setCookie(...cookies) | browserContext.addCookies(cookies) |
| page.on('request',...) | page.routeを通じて処理されます |
| elementHandle.uploadFile(...) | elementHandle.setInputFiles(...) |
| 厄介なファイルダウンロード。 | ダウンロードに対するサポートが向上。 |

## 変更詳細の大開示
### パッケージのインポート
Puppeteerでは、スクリプトの冒頭は次のようになります：
```javascript
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    //...
```
Playwrightでは、次のようになります：
```javascript
const { chromium } = require('playwright');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    //...
```
Playwrightは非常に配慮深く、クロスブラウザサポートが付属しています。自由に実行するブラウザを選択できます。例えば`const { webkit } = require('playwright');`のようにです。Puppeteerでは、launchインターフェイスの設定を通じてこれを実現する必要があります。例えば：
```javascript
const browser = await puppeteer.launch({ product: 'firefox' })
```

### ブラウザコンテキスト
Puppeteerでは、ブラウザコンテキストは次のように使用されます：
```javascript
const browser = await puppeteer.launch();
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
```
Playwrightでは、コンテキストはさらに重要で、使用方法が少し異なります：
```javascript
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
```
Puppeteerと同様に、基本的な使用や1ページのフローの場合は、デフォルトのコンテキストを使用できます：
```javascript
const browser = await chromium.launch();
const page = await browser.newPage();
```

### 待機
Playwrightには強力な自動待機メカニズムがあり、常に手動で待つ必要はありません。ただし、待機はUI自動化で最も面倒な部分の1つであり、1つまたは複数の条件が満たされるまでスクリプトを順守して待機させる方法を知っておく必要があります。この点に関して、Playwrightには次のような変更があります：
 - `page.waitForNavigation`と`page.waitForSelector`は依然として存在しますが、自動待機メカニズムにより、多くの場合、必ずしも必要ではありません。
 - `page.waitForEvent`が追加されました。
 - Puppeteerの`page.waitForXPath`は`page.waitForSelector`に統合され、XPath式を自動的に認識できます。
 - `page.waitForFileChooser`は削除されました。新しい使用方法については、「ファイルのアップロード、E2Eアカウント設定」を参照してください。
 - `page.waitForNetworkIdle`は`page.waitForLoadState`に統合されました。
 - `page.waitForUrl`が追加され、ページのメインフレームがURLを読み込むのを待つことができます。
 - `page.waitFor(timeout)`は`page.waitForTimeout(timeout)`になりました。
正式な製品では`page.waitForTimeout`を使用しないでください。この強制待機はテストにのみ適しています。

### ビューポートの設定
Puppeteerの`page.setViewport`はPlaywrightでは`page.setViewportSize`になります。

### 入力
Puppeteerの`page.type`は依然として使用できます。微細なキーボードイベントを制御したい場合は、依然として便利なヘルパーです。その他に、Playwrightには`page.fill`が追加され、フォームの入力とクリアに非常に便利です。

### クッキー
Puppeteerを使用する場合、クッキーはページレベルで処理されます。Playwrightでは、BrowserContextレベルで操作できます。
以前：
```javascript
page.cookies([...urls])
page.deleteCookie(...cookies)
page.setCookie(...cookies)
```
現在：
```javascript
browserContext.cookies([urls])
browserContext.clearCookies()
browserContext.addCookies(cookies)
```
これらのメソッドにはいくつかの小さな違いがあるので、クッキーを渡すときは注意してください。

### XPathセレクタ
Playwrightは`//`または`..`で始まるXPathセレクタを自動的に認識できますが、Puppeteerでは別のインターフェイスがあります。

### デバイスエミュレーション
Playwrightのデバイスエミュレーションはブラウザコンテキストレベルで行うことができ、次のようになります：
```ini
const pixel2 = devices['Pixel 2'];
const context = await browser.newContext({
...pixel2,
});
```
また、パーミッション、位置情報、その他のデバイスパラメータを制御することもできます。クールですよね？

### ファイルダウンロード
Puppeteerではヘッドレスモードでのファイルダウンロードはかなり厄介ですが、Playwrightでははるかに簡単です：
```javascript
const [download] = await Promise.all([
    page.waitForEvent('download'),
    page.click('#orders > ul > li:nth-child(1) > a')
])

const path = await download.path();
```
これは完全な例です。

### ファイルアップロード
Puppeteerの`elementHandle.uploadFile`は`elementHandle.setInputFiles`になります。詳細はファイルアップロードの例を参照してください。

### リクエストのインターセプト
Puppeteerでは、リクエストのインターセプトは次のように行われます：
```dart
await page.setRequestInterception(true)

page.on('request', (request) => {
    if (request.resourceType() === 'image') request.abort()
    else request.continue()
})
```
Playwrightでは、`page.route`を使用して指定されたパターンのURLをインターセプトできます：
```javascript
await page.route('**/*', (route) => {
  return route.request().resourceType() === 'image'
? route.abort()
    : route.continue()
})
```
完全な例はこちらを参照してください。

## 注目すべき新機能
PuppeteerからPlaywrightに切り替える際には、Playwrightの新機能をしっかり理解する必要があります。これらの新機能があなたのテストやモニタリング設定に新しい驚きをもたらすかもしれません！

### 新しいセレクタエンジン
PlaywrightはUI要素を参照する非常に柔軟な方法を提供します。cssやXPathに加えて、以下のようなものもあります：
 - Playwright固有のセレクタ、例えば`:nth - match(:text("Buy"), 3)`。
 - テキストセレクタ、例えば`text=Add to Car`。
 - チェーンセレクタ、例えば`css=preview >> text=In stock`。
独自のカスタムセレクタエンジンを作成することもできます。セレクタの詳細情報と使用方法については、「セレクタの使用」を参照してください。

### 状態の保存と再利用
Playwrightは、与えられたセッションの認証状態（クッキーとlocalStorage）を簡単に保存できます。これは、次回スクリプトを実行するときに直接使用でき、認証時間を節約できます。とても配慮深いですよね？

### Locator API
PlaywrightのLocator APIは、指定された要素を取得するロジックをカプセル化しています。これにより、異なる時点でスクリプト内の最新のDOM要素を簡単に取得できます。

### インスペクタ
Playwrightのインスペクタは、スクリプトのデバッグ時に非常に便利なGUIツールです。スクリプト内の命令を1ステップずつ実行でき、エラーの原因を簡単に特定できます。

### テスト
Playwrightには、E2Eテストで非常に便利なTestメカニズムがあります。例えば、ビルトインの並列化、フックなどです。

### トレースビューア
Playwrightのトレースビューアを使用すると、PlaywrightテストまたはBrowserContextトラッキングAPIによって記録されたトレースを調査できます。トラッキングを通じて、スクリプトの実行を明確に確認できます。

### テストジェネレータ
Playwrightのテストジェネレータを使用すると、ブラウザ内のインタラクションを記録でき、出力はチェックして実行できる完全なスクリプトになります。

## 移行プロセス中の注意点
PuppeteerからPlaywrightへの移行プロセス中には、上記の様々な変更と新機能を理解するだけでなく、いくつかの詳細にも特別に注意する必要があります。

### バージョン互換性の問題
Playwrightをインストールして使用する際には、そのバージョンがプロジェクトで使用する他の依存ライブラリと互換性があることを確認してください。Playwrightの異なるバージョンでは、APIの使用方法や機能的な特性にわずかな違いがある場合があります。公式ドキュメントを注意深く参照し、プロジェクトに適したバージョンを選択してください。同時に、使用しているブラウザのバージョンとPlaywrightの互換性にも留意してください。一部の新機能は特定のブラウザのバージョンで正常に動作する必要がある場合があります。

### 設定の調整
移行後、一部の設定を対応する調整が必要になる場合があります。例えば、Puppeteerでは特定の起動パラメータや設定オプションを使い慣れているかもしれませんが、Playwrightでは設定方法やパラメータ名が異なる場合があります。Playwrightのドキュメントに従って、ブラウザを起動するための設定を再設定する必要があります。これには、ヘッドレスモードを有効にするか、プロキシを設定するか、ブラウザのパフォーマンスパラメータを調整するなどが含まれます。

### エラーハンドリング
PlaywrightのエラーハンドリングメカニズムもPuppeteerとは異なります。移行プロセス中には、コードがPlaywrightによって投げられる様々な例外を正しくキャッチし、処理できるようにしてください。Playwrightのエラーメッセージには通常、詳細なエラー原因とスタックトレースが含まれており、問題の迅速な特定と解決に役立ちます。try - catch文を使って例外をキャッチし、異なるエラータイプに応じて処理を行うことができます。例えば、操作を再試行したり、エラーメッセージをログに記録したりすることができます。

### チームコラボレーション
もしあなたのプロジェクトがチームで共同開発するプロジェクトである場合、Playwrightに移行する際には、すべてのチームメンバーがこれらの変更に気付いていることを確認してください。チームトレーニングを組織して、Playwrightの新機能や使用方法を共有することで、皆ができるだけ早く新しいツールに慣れることができます。同時に、プロジェクトのコード規約やドキュメントを更新して、チームメンバーがPlaywrightを使用する際に統一された基準に従うようにしてください。

## 移行後の最適化の提案
移行を完了した後、作業は終わりではありません。Playwrightの利点を最大限に活かすために、コードを最適化することもできます。

### 並列化機能の活用
PlaywrightのTestメカニズムは、ビルトインの並列化を提供しており、これによりテストケースの実行時間を大幅に短縮することができます。プロジェクトの実際の状況に応じて、並列実行するテストケースの数を合理的に設定し、マルチコアCPUの性能を最大限に活用し、テストの効率を向上させることができます。

### 待機戦略の最適化
Playwrightの自動待機メカニズムはすでに非常に強力ですが、一部の複雑なシナリオでは、待機戦略をさらに最適化する必要がある場合があります。例えば、ページ要素の読み込み特性に応じて、待機タイムアウトを合理的に設定し、待機時間が長すぎることによるテスト効率の低下を避けることができます。同時に、できるだけ強制待機時間を使用せず、要素が表示されるかクリック可能になるなど、よりインテリジェントな待機条件を使用するようにしてください。

### コードの再構築
移行プロセス中に、元々Puppeteerで書かれていた一部のコードがPlaywrightではより簡潔かつ効率的に実装できることに気付くかもしれません。このとき、適切にコードを再構築し、冗長なコードを削除し、コードの可読性と保守性を向上させることができます。同時に、Playwrightが提供する新機能を活用して、テストケースを最適化し、もっと堅牢で信頼性の高いものにすることができます。

## まとめ
PuppeteerからPlaywrightへの移行には、新しい変更を学び、適応するためにいくらかの時間とエネルギーを費やす必要がありますが、長期的に見れば、非常に価値があります。Playwrightは、パフォーマンス、安定性、新機能の点で明らかな利点を持っており、テストや自動化タスクにより高い効率とより良い体験をもたらすことができます。移行のポイントをマスターし、移行プロセス中に様々な詳細に注意し、移行後にコードを最適化すれば、この移行を成功裏に完了し、Playwrightの力を借りてプロジェクトを新しいレベルに引き上げることができます！

# [Leapcell：Webホスティング、非同期タスク、Redisの次世代サーバレスプラットフォーム](https://leapcell.io/)

[![barndpic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/ad848dbb-51ab-dd1b-b2ad-e344cb24d6b8.png)](https://leapcell.io/?lc_t=q_playvspup)


最後に、Playwrightを展開するのに最適なプラットフォーム[Leapcell](https://leapcell.io/)をおすすめします。

### 1. 多言語対応
 - JavaScript、Python、Go、またはRustで開発可能。  

### 2. 無制限のプロジェクトを無料で展開
 - 使用量に応じてのみ課金 — リクエストがなければ料金はかかりません。

### 3. 抜群のコスト効率
 - 使い切り制で、アイドル時の料金はかかりません。  
 - 例：25ドルで平均応答時間60msで694万回のリクエストに対応可能。  

### 4. ストリームライン化された開発者体験
 - 直感的なUIによる簡単なセットアップ。  
 - 完全自動化されたCI/CDパイプラインとGitOps統合。  
 - アクション可能な洞察のためのリアルタイムメトリックとロギング。  

### 5. 簡単なスケーラビリティと高性能
 - 高い同時接続数を簡単に処理するための自動スケーリング。  
 - オペレーションオーバーヘッドはゼロ — 構築に集中できます。  

[![Frame3-withpadding2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/1ecec7aa-57c0-7182-0556-048ff65d6924.png)](https://leapcell.io/?lc_t=q_playvspup)


[ドキュメントでもっと詳しく探索！](https://docs.leapcell.io/)

LeapcellのTwitter：[https://x.com/LeapcellHQ](https://x.com/LeapcellHQ)