playwright vs puppeteer vs selenium-webdriver
モダンなE2Eテストとブラウザ自動化のためのツール選択
playwrightpuppeteerselenium-webdriver類似パッケージ:
モダンなE2Eテストとブラウザ自動化のためのツール選択

playwrightpuppeteerselenium-webdriver はすべてブラウザの自動操作を可能にするnpmパッケージであり、主にエンドツーエンド(E2E)テストやスクレイピング、自動化タスクに使われます。これらはそれぞれ異なるアプローチでブラウザ制御を実現しており、サポートするブラウザ範囲、API設計、安定性、デバッグ機能などに明確な違いがあります。

npmのダウンロードトレンド
3 年
GitHub Starsランキング
統計詳細
パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
playwright25,548,05180,1393.89 MB54517日前Apache-2.0
puppeteer6,812,05193,03962.8 kB2921日前Apache-2.0
selenium-webdriver2,184,30833,76418.4 MB2286日前Apache-2.0

Playwright vs Puppeteer vs Selenium WebDriver:E2Eテストとブラウザ自動化の実践的比較

フロントエンド開発者がE2Eテストやブラウザ自動化を実装する際、playwrightpuppeteerselenium-webdriver の3つが代表的な選択肢になります。これらは目的こそ似ていますが、設計思想や実装方法、サポート範囲に大きな違いがあります。現場で実際に使う観点から、深く掘り下げて比較します。

🌐 サポートブラウザ:1つだけ vs 複数 vs 全般

puppeteerChromium系のみ をサポートします。つまり、ChromeやMicrosoft Edge(Chromium版)は動作しますが、FirefoxやSafariは対象外です。

// puppeteer: Chromium系限定
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

playwrightChromium、Firefox、WebKit(Safariのエンジン)の3つを公式サポート しています。1つのテストコードで複数ブラウザでの動作確認が可能です。

// playwright: ブラウザごとに起動可能
const { chromium, firefox, webkit } = require('playwright');

const browser = await chromium.launch(); // または firefox.launch(), webkit.launch()
const page = await browser.newPage();
await page.goto('https://example.com');

selenium-webdriver は理論上 すべてのWebDriver準拠ブラウザ をサポートしますが、各ブラウザ用のドライバー(chromedriver、geckodriverなど)を別途インストール・管理する必要があります。

// selenium-webdriver: ドライバー依存
const { Builder, By } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

let driver = await new Builder()
  .forBrowser('chrome')
  .setChromeOptions(new chrome.Options())
  .build();

await driver.get('https://example.com');

💡 実務では、FirefoxやSafariでの動作検証が必要なら playwright 一択。Chromium系だけで十分なら puppeteer の軽さが魅力。レガシー環境やマルチ言語対応が必須なら selenium-webdriver を検討。

⚙️ API設計:直感的 vs 冗長

puppeteerplaywright はどちらもモダンで一貫性のあるPromiseベースのAPIを持ち、page.click()page.fill() のように直感的に操作できます。

// puppeteer
await page.goto('https://example.com');
await page.type('#username', 'testuser');
await page.click('#submit');

// playwright
await page.goto('https://example.com');
await page.fill('#username', 'testuser');
await page.click('#submit');

一方、selenium-webdriver はWebDriverプロトコルに忠実なため、要素の取得と操作が分かれており、コードが冗長になりがちです。

// selenium-webdriver
await driver.get('https://example.com');
let username = await driver.findElement(By.id('username'));
await username.sendKeys('testuser');
let submit = await driver.findElement(By.id('submit'));
await submit.click();

また、selenium-webdriver は非同期処理を async/await で書くこともできますが、内部でコマンドキューを管理するため、エラーハンドリングやデバッグがやや複雑です。

🧪 テスト安定性:待機戦略の違い

不安定なE2Eテストの最大の原因は「タイミング」です。各ツールはこの問題に対し、異なるアプローチを取っています。

puppeteerpage.waitForSelector()page.waitForFunction() を使って明示的に待機する必要があります。

// puppeteer: 手動待機
await page.click('#load-data');
await page.waitForSelector('#result'); // 要素が表示されるまで待つ

playwright は多くのアクション(clickfill など)に 自動待機機能 が組み込まれており、要素が操作可能になるまで内部で待機します。

// playwright: 自動待機
await page.click('#load-data');
await page.click('#result'); // 要素がクリック可能になるまで自動で待つ

selenium-webdriverWebDriverWait のような明示的待機(Explicit Wait)を推奨しており、Implicit Wait(暗黙的待機)は非推奨です。

// selenium-webdriver: 明示的待機
const until = require('selenium-webdriver/until');

await driver.findElement(By.id('load-data')).click();
await driver.wait(until.elementLocated(By.id('result')), 5000);

💡 実務では、playwright の自動待機がテストの安定性を大幅に向上させ、メンテナンスコストを削減します。puppeteerselenium-webdriver では待機ロジックの記述漏れがバグの温床になりやすいです。

📱 モバイル・ネットワークエミュレーション

モバイル端末や低速ネットワーク下での動作確認が必要な場合、ツール間でサポート状況が大きく異なります。

playwright はビルドインで デバイスエミュレーションネットワークスロットリング をサポートしています。

// playwright: デバイスエミュレーション
const { devices } = require('playwright');
const iPhone = devices['iPhone 13'];

const context = await browser.newContext({ ...iPhone });
const page = await context.newPage();
// playwright: ネットワーク制限
await context.setOffline(true);
await context.setGeolocation({ latitude: 35.6895, longitude: 139.6917 });

puppeteer もChromiumの機能を活用して同様のことが可能ですが、設定がやや低レベルです。

// puppeteer: ネットワーク制限
const client = await page.target().createCDPSession();
await client.send('Network.emulateNetworkConditions', {
  offline: false,
  latency: 100,
  downloadThroughput: 1.5 * 1024 * 1024 / 8,
  uploadThroughput: 1.5 * 1024 * 1024 / 8
});

selenium-webdriver は標準ではこれらの機能を提供せず、ブラウザ固有の拡張(例:Chrome DevTools Protocol経由)を使う必要があります。そのため、設定が複雑でポータビリティが低いです。

🛠️ デバッグと開発体験

playwrightPWDEBUG=1 環境変数でGUI付きデバッガーを起動でき、タイムトラベルデバッグやスクリーンショット比較も可能です。

PWDEBUG=1 npm test

puppeteerheadless: false オプションでブラウザを可視化できますが、高度なデバッグ機能は備えていません。

// puppeteer: 可視化
const browser = await puppeteer.launch({ headless: false });

selenium-webdriver も同様にヘッドフルモードで実行可能ですが、デバッグ支援機能は最小限です。

📦 インストールとセットアップの手間

puppeteerplaywrightnpm install 時に必要なブラウザバイナリを自動でダウンロードします。追加設定不要で即座に使い始められます。

npm install playwright
# → Chromium, Firefox, WebKit が自動インストール

selenium-webdriver はブラウザドライバーを別途管理する必要があります。たとえばChromeを使うには chromedriver をインストールし、PATHを通すか、コード内でパスを指定する必要があります。

// selenium-webdriver: ドライバーの明示的指定
const service = new chrome.ServiceBuilder('/path/to/chromedriver').build();
chrome.setDefaultService(service);

これはCI環境でのセットアップを煩雑にし、チーム内での環境差異を生む原因になります。

🔄 非推奨状況と将来性

2024年現在、いずれのパッケージも 非推奨ではありませんpuppeteer はGoogleが、playwright はMicrosoftが、selenium-webdriver はSeleniumプロジェクトがそれぞれ積極的にメンテナンスしています。

ただし、puppeteer は2023年にコミュニティ主導のプロジェクトとなり、Googleによる直接的な開発は終了しました。一方、playwright は活発な開発が続いており、新機能(例:Component Testing、Trace Viewer)が継続的に追加されています。

📊 まとめ:選択の指針

観点playwrightpuppeteerselenium-webdriver
サポートブラウザChromium, Firefox, WebKitChromium系のみ全WebDriver準拠ブラウザ(ドライバー要)
APIの使いやすさ非常に直感的(自動待機付き)直感的だが手動待機必要冗長(要素取得と操作が分離)
モバイル/ネットワークエミュレートビルドインで簡単可能だが低レベル標準では不可、ブラウザ依存
デバッグ支援GUIデバッガー、トレース機能ヘッドフルモードのみ最小限
セットアップの手間自動(npm installで完了)自動ドライバー管理が必要
最適なユースケース本格的なE2Eテスト、クロスブラウザ検証スクレイピング、Chromium限定の自動化マルチ言語環境、既存Seleniumインフラとの統合

💡 最終的なアドバイス

  • 新規プロジェクトでE2Eテストを始めるなら、まず playwright を試すべきです。安定性、機能、開発体験のすべてで現代的なニーズに応えています。
  • Chromium系だけで十分で、軽量さを重視するなら puppeteer も有効。特にスクレイピングやPDF生成など、テスト以外の自動化タスクに向いています。
  • selenium-webdriver は、既にSeleniumエコシステムに投資している組織や、複数言語でテストを統一したい場合に限って検討してください。純粋なNode.jsプロジェクトではオーバーヘッドが大きすぎます。

これらのツールは「どれが絶対に優れている」というより、「どんな課題を解決したいか」によって最適解が変わります。あなたのチームの技術スタック、テスト要件、保守コストを見極めて、賢く選んでください。

選び方: playwright vs puppeteer vs selenium-webdriver
  • playwright:

    playwright を選ぶべきなのは、複数のブラウザ(Chromium、Firefox、WebKit)でのテストが必要な場合、または最新のWeb標準やモバイルエミュレーション、ネットワーク条件のシミュレーションといった高度な機能を活用したいときです。特に大規模なE2EテストスイートやCI/CD環境での安定した実行を求めるプロジェクトに適しています。

  • puppeteer:

    puppeteer を選ぶべきなのは、Chromium系ブラウザ(ChromeやEdge)のみを対象とし、シンプルで軽量な自動化スクリプトやスクレイピングを実装したい場合です。Playwrightほどの多機能さは不要で、既存のNode.js環境に手軽に組み込みたいケースに向いています。

  • selenium-webdriver:

    selenium-webdriver を選ぶべきなのは、JavaやPythonなど複数の言語環境で同じテストコードを共有したい場合、あるいは既にSelenium Gridなどのインフラを運用している組織において、JavaScriptベースのテストも統合したいときです。ただし、Node.js専用のユースケースでは他の2つより冗長になることが多いです。

playwright のREADME

🎭 Playwright

npm version Chromium version Firefox version WebKit version Join Discord

Documentation | API reference

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable and fast.

LinuxmacOSWindows
Chromium 143.0.7499.4:white_check_mark::white_check_mark::white_check_mark:
WebKit 26.0:white_check_mark::white_check_mark::white_check_mark:
Firefox 144.0.2:white_check_mark::white_check_mark::white_check_mark:

Headless execution is supported for all browsers on all platforms. Check out system requirements for details.

Looking for Playwright for Python, .NET, or Java?

Installation

Playwright has its own test runner for end-to-end tests, we call it Playwright Test.

Using init command

The easiest way to get started with Playwright Test is to run the init command.

# Run from your project's root directory
npm init playwright@latest
# Or create a new project
npm init playwright@latest new-project

This will create a configuration file, optionally add examples, a GitHub Action workflow and a first test example.spec.ts. You can now jump directly to writing assertions section.

Manually

Add dependency and install browsers.

npm i -D @playwright/test
# install supported browsers
npx playwright install

You can optionally install only selected browsers, see install browsers for more details. Or you can install no browsers at all and use existing browser channels.

Capabilities

Resilient • No flaky tests

Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - a primary cause of flaky tests.

Web-first assertions. Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met.

Tracing. Configure test retry strategy, capture execution trace, videos and screenshots to eliminate flakes.

No trade-offs • No limits

Browsers run web content belonging to different origins in different processes. Playwright is aligned with the architecture of the modern browsers and runs tests out-of-process. This makes Playwright free of the typical in-process test runner limitations.

Multiple everything. Test scenarios that span multiple tabs, multiple origins and multiple users. Create scenarios with different contexts for different users and run them against your server, all in one test.

Trusted events. Hover elements, interact with dynamic controls and produce trusted events. Playwright uses real browser input pipeline indistinguishable from the real user.

Test frames, pierce Shadow DOM. Playwright selectors pierce shadow DOM and allow entering frames seamlessly.

Full isolation • Fast execution

Browser contexts. Playwright creates a browser context for each test. Browser context is equivalent to a brand new browser profile. This delivers full test isolation with zero overhead. Creating a new browser context only takes a handful of milliseconds.

Log in once. Save the authentication state of the context and reuse it in all the tests. This bypasses repetitive log-in operations in each test, yet delivers full isolation of independent tests.

Powerful Tooling

Codegen. Generate tests by recording your actions. Save them into any language.

Playwright inspector. Inspect page, generate selectors, step through the test execution, see click points and explore execution logs.

Trace Viewer. Capture all the information to investigate the test failure. Playwright trace contains test execution screencast, live DOM snapshots, action explorer, test source and many more.

Looking for Playwright for TypeScript, JavaScript, Python, .NET, or Java?

Examples

To learn how to run these Playwright Test examples, check out our getting started docs.

Page screenshot

This code snippet navigates to Playwright homepage and saves a screenshot.

import { test } from '@playwright/test';

test('Page Screenshot', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await page.screenshot({ path: `example.png` });
});

Mobile and geolocation

This snippet emulates Mobile Safari on a device at given geolocation, navigates to maps.google.com, performs the action and takes a screenshot.

import { test, devices } from '@playwright/test';

test.use({
  ...devices['iPhone 13 Pro'],
  locale: 'en-US',
  geolocation: { longitude: 12.492507, latitude: 41.889938 },
  permissions: ['geolocation'],
})

test('Mobile and geolocation', async ({ page }) => {
  await page.goto('https://maps.google.com');
  await page.getByText('Your location').click();
  await page.waitForRequest(/.*preview\/pwa/);
  await page.screenshot({ path: 'colosseum-iphone.png' });
});

Evaluate in browser context

This code snippet navigates to example.com, and executes a script in the page context.

import { test } from '@playwright/test';

test('Evaluate in browser context', async ({ page }) => {
  await page.goto('https://www.example.com/');
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    }
  });
  console.log(dimensions);
});

Intercept network requests

This code snippet sets up request routing for a page to log all network requests.

import { test } from '@playwright/test';

test('Intercept network requests', async ({ page }) => {
  // Log and continue all network requests
  await page.route('**', route => {
    console.log(route.request().url());
    route.continue();
  });
  await page.goto('http://todomvc.com');
});

Resources