Playwright(プレイライト)は、Microsoftが開発しているオープンソースのブラウザ自動化・E2Eテストフレームワークです。1つのAPIでChromium・Firefox・WebKitを動かし、要素が操作できる状態になるまで自動で待つため、待機処理をほとんど書かずに安定したテストを組めます。
この記事では「なぜ安定して速いのか」という仕組みを、最新版の1.64.1(2026年10月14日公開)を手元で動かして確かめた結果とあわせて説明します。そのうえで、できること、対応言語と動作要件、Seleniumとの違い、Apache-2.0ライセンスでの商用利用、採用すべき場面と見送る場面を整理します。
まとめ:Playwrightの仕組みと選び方の要点
- 仕組み:テストコード→Playwrightのドライバ→ブラウザの3層構成です。ローカルで起動したブラウザとはTCPではなくパイプで直結し、ChromiumはCDP、FirefoxとWebKitはPlaywright用に拡張したプロトコルで制御します。WebSocketを使うのは、launchServerで立てたブラウザサーバーや既存ChromeのCDP接続先へつなぐときで、同じマシン内でも別マシンでも同じです。
- 安定する理由:クリックなどの前に「表示・静止・イベントを受け取れる・有効」を確認するauto-waitと、テストごとに新しいブラウザコンテキスト(Cookieやストレージが独立したセッション)を作る分離の2つです。
- 対応:言語はJavaScript/TypeScript・Python・Java・.NET。Node.jsは22・24・26系が推奨で、Python版は1.61以降Python 3.10以上が必要です。
- ライセンス:本体はApache-2.0(.NET版のパッケージはMIT)で、商用利用も無料です。本体のライセンス料とは別に、Azureなどの有料サービスやCIの実行基盤に費用が発生する場合があります。
- 選び方:新規のWebアプリのE2EテストならPlaywrightを第一候補にします。Selenium資産が大きい現場、ネイティブアプリ、静的HTMLの取得だけなら別の手段が合います。
Playwrightとは|読み方・提供元・現在のバージョン
読み方は「プレイライト」です。英単語のplaywrightは「劇作家・脚本家」を意味し、テストという筋書きをブラウザに演じさせる道具という名前になっています。GitHubのリポジトリmicrosoft/playwrightは2019年11月に作られ、npmでは2020年2月1日(UTC)に0.10.0、2020年5月6日に1.0.0が公開されました。
開発チームは、GoogleでPuppeteerを作ったメンバーです。0.10.0のREADMEは「GoogleでPuppeteerを最初に作ったのと同じチーム」と説明し、Chromeだけを扱うPuppeteerの考え方をすべての主要なレンダリングエンジンへ広げることを目標に掲げていました(v0.10.0のREADME)。PuppeteerとPlaywrightのAPIが似ているのはこの経緯によります。
現在の最新版は1.64.1(npmの公開日時は2026年10月14日)で、1.xのままおおむね1〜2か月ごとにマイナー版が出ています。版ごとの変更点や更新手順はPlaywrightの最新バージョンは1.63|確認・更新方法とリリース履歴【2026年9月】にまとめています。
Playwrightの仕組み|テストコードからブラウザまでの3層
Playwrightは「テストコード(クライアント)」「ドライバ(サーバー側の実装)」「ブラウザ」の3層で動きます。どの言語から使っても、実際にブラウザを操作するのはNode.jsで書かれた同じドライバです。公式ドキュメントも各言語版について「同じ実装を共有している」と説明しています(Supported languages)。
プロセス構成:Node.jsは同一プロセス、Pythonはドライバを子プロセスで起動
Node.js(@playwright/test)では、テストコードとドライバが同じNode.jsプロセスの中で動きます。Python・Java・.NETでは、ライブラリがドライバを子プロセスとして起動し、標準入出力(stdin/stdout)のパイプでJSONメッセージをやり取りします。
Python版1.64.0で確かめると、Pythonプロセスの子として playwright/driver/node … run-driver が起動していました。このnodeのファイル記述子0と1はどちらもPIPEで、TCPソケットは開いていません。Python版のパッケージにはNode.js v24.21.0の実行ファイルが同梱されており、driverディレクトリだけで133MBあります。Python環境にNode.jsを入れなくても動くのはこのためです。起動処理はplaywright-pythonの_transport.pyで、run-driver を引数に stdin=PIPE, stdout=PIPE でサブプロセスを作っています。
ローカル起動したブラウザとのパイプ接続
ドライバがローカルのブラウザを起動するとき、デバッグ用の通信路としてパイプを指定します。v1.64.1のソースでは、Chromiumに --remote-debugging-pipe、Firefoxに -juggler-pipe、WebKitに --inspector-pipe を付けています(chromium.ts)。WSL上のWebKitだけは例外で、ポートを使います。
次の表は、Intel Macで各ブラウザを2回目に起動した際の計測例です。起動時間はlaunchの開始から完了まで、コンテキスト作成時間はnewContextを2回順に実行した合計で、環境や実行時の負荷によって変わります。
| ブラウザ(1.64.1同梱版) | 起動フラグ | プロトコル | 起動時間 | コンテキスト2個 |
|---|---|---|---|---|
| Chromium(Chrome for Testing 156) | –remote-debugging-pipe | CDP | 731ms | 14ms |
| Firefox 157.0 | -juggler-pipe | Juggler | 3,141ms | 299ms |
| WebKit 27.2 | –inspector-pipe | WebKit Inspector | 869ms | 370ms |
ChromiumのプロセスをlsofでTCPの待ち受けを調べると、該当は0件でした。ブラウザは外部からの接続口を開けておらず、ドライバとだけパイプでつながっています。FirefoxとWebKitは、PlaywrightのチームがCDPに近い操作をできるよう手を入れたビルドで、これが npx playwright install で専用のブラウザを入れる理由です。市販のFirefoxやSafariをそのまま動かしているわけではありません。
環境変数 DEBUG=pw:protocol を付けて実行すると、ドライバとブラウザの間を流れるメッセージを見られます。browser.newContext() は Target.createBrowserContext に、ボタン1回のクリックは次のCDPメソッドの組み合わせに変換されていました。
// click.mjs
import { chromium } from '@playwright/test';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.setContent('<button>OK</button>');
await page.click('button');
await browser.close();
DEBUG=pw:protocol node click.mjs
# page.click('button') 1回で送られたCDPメソッド(回数)
Runtime.callFunctionOn 8 # 要素の取得と表示・有効・静止の確認
DOM.scrollIntoViewIfNeeded 1 # 画面内へスクロール
DOM.getContentQuads 1 # クリック座標の計算
Input.dispatchMouseEvent 3 # マウス移動・押下・解放
クリックは「要素を探す→状態を確かめる→座標を計算する→本物のマウスイベントを送る」という段階を踏みます。JavaScriptで element.click() を呼ぶのではなく、人がクリックしたときと同じ入力イベントを発生させるため、要素の上に別の要素が重なっていればクリックは成立しません。
WebSocket接続:ブラウザサーバーと既存Chromeへの接続
WebSocketが出てくるのは、ブラウザを別のプロセスやマシンで動かす構成です。chromium.launchServer() でブラウザサーバーを立てると ws://[::1]:61537/<トークン> の形のエンドポイントが返り、別のスクリプトから chromium.connect() でつなげます。既に起動しているChromeへCDPで接続する connectOverCDP() や、Dockerやクラウドのブラウザを使う構成もこの形です。
この記事の旧版は「テストコードとサーバーが単一のWebSocketで接続する」と書いていましたが、launch() で起動するローカル実行はパイプです。launchServer() や connectOverCDP() を使う場合は同じマシンの中でもポートで待ち受けるので、CIではバインド先とコンテナ間の通信経路をあわせて設計します。
ブラウザ・コンテキスト・ページの階層と分離
Playwrightは「ブラウザ→ブラウザコンテキスト→ページ」の階層で対象を扱います。ブラウザコンテキストはCookie・localStorage・キャッシュを独立して持つセッションで、1つのブラウザプロセスの中にいくつでも作れます。2つのコンテキストで同じURLを開き、片方で document.cookie = 'user=alice' とlocalStorageの値を書き込んだところ、もう片方からはCookieが空文字、localStorageはnullで、状態は混ざりませんでした。
分離が安い点も効いています。上の表のとおり、Chromiumはブラウザ起動に731msかかる一方、コンテキスト2個の作成は14msでした。@playwright/testはテストごとに新しいコンテキストを作るため、前のテストのログイン状態が次のテストに漏れません。ログイン済みの状態を使い回したいときは、storageState で保存した状態を読み込ませます。
auto-wait(actionabilityチェック)の中身
Playwrightは操作の前に、対象の要素に対してactionabilityチェックを行い、すべて通るまで待ってから操作します。確認項目は操作によって違い、たとえばクリックは次の4つを、入力(fill)は表示・有効・編集可能を確認します。
- Visible:要素が表示されている(サイズが0でない・visibility:hiddenでない)
- Stable:要素の境界ボックスの位置とサイズが、連続する少なくとも2回のアニメーションフレームで同じ
- Receives Events:ほかの要素に覆われておらず、クリック位置でイベントを受け取れる
- Enabled:disabled属性などで無効になっていない
無効のボタンを置き、1.5秒後にJavaScriptで有効にするページで page.click() を実行すると、待機コードを書かなくても約1,600ms後にクリックが成立しました。ずっと無効のままにすると、タイムアウトで失敗し、エラーには何を待っていたかが記録されます。待つ上限は、@playwright/testではアクション個別の上限がなく、テスト全体の既定30秒が効きます。Python版の click() は既定30,000msです(Timeouts)。次は上限を2秒にして失敗させた例です。
page.click: Timeout 2000ms exceeded.
Call log:
- waiting for locator('#c')
- locator resolved to <button id="c" disabled>送信</button>
- attempting click action
2 × waiting for element to be visible, enabled and stable
- element is not enabled
- retrying click action
透明でない要素がボタンを覆っている場合は、「element is visible, enabled and stable」まで進んだうえで <div></div> intercepts pointer events と出て止まります。テストが失敗したとき、このCall logを読めば「無効のまま」なのか「何かに覆われている」のかを切り分けられます。sleepを延ばしても直らない場合は、Call logで待機中の条件を確認し、無効状態や操作点を覆う要素など、記録された原因を調べます。
Playwrightでできること
- クロスブラウザテスト:Chromium・Firefox・WebKitを同じコードで実行。
channel: 'chrome'などでインストール済みのChromeやEdgeも使える - ヘッドレス実行とUIモード:CIでは画面なしで実行し、手元では
npx playwright test --uiで1ステップずつ確認 - ネットワークの傍受とモック:
page.route()でAPIの応答を差し替え、外部サービスに依存しないテストにする - 端末のエミュレーション:画面サイズ・UA・タッチ・位置情報・タイムゾーンを指定
- 失敗の調査:スクリーンショット、動画、トレース(操作ごとのDOMとネットワークの記録)
- codegen:ブラウザを操作するとテストコードを生成
- AIとの連携:1.56でテストの計画・生成・修復を行うTest Agents、1.62でMCPサーバーとCLIを同梱
コマンドの使い分けはPlaywright CLIコマンド一覧|test・codegen・installと1.63の新オプション、AIアシスタントからブラウザを操作する設定はPlaywright MCPとは?設定・使い方からDify連携まで実務ガイド【2026年版】で扱っています。画面が増えてテストが膨らんだら、Page Object Model(POM)とは?Playwright・Seleniumの実装例と保守コストの実測の構成で整理すると保守しやすくなります。
対応ブラウザ・対応言語と動作要件
ブラウザは、版ごとに決まったビルドが組み合わされています。1.64.1では Chromium=Chrome for Testing 156.0.8078.4、Firefox 157.0、WebKit 27.2 です(npx playwright install --dry-run で確認)。Playwrightの版を上げたら、対応するブラウザも入れ直す必要があります。
言語ごとの要件は次のとおりです。公式ドキュメントの記載と、配布パッケージに実際に設定されている条件が食い違っている箇所があります。
| 言語 | パッケージ | 公式ドキュメントの要件 | 配布物の実際 |
|---|---|---|---|
| JavaScript/TypeScript | @playwright/test | Node.js 22・24・26系 | Node.js 20未満は起動時に終了 |
| Python | playwright(PyPI) | Python 3.8以上 | 1.61以降は3.10以上 |
| Java | com.microsoft.playwright | Java 8以上 | ― |
| .NET | Microsoft.Playwright | .NET Standard 2.0(.NET 8推奨) | ― |
Pythonのずれは実害があります。PyPIの requires_python は1.60.0まで「>=3.9」、1.61.0(2026年6月29日)から「>=3.10」に変わりました。macOS標準のPython 3.9.6で pip install playwright を実行すると、エラーにならずに1.60.0が入ります。最新版の機能が使えない原因がPythonの版にあると気付きにくいので、Python版は3.10以上の環境で使い、pip show playwright で入った版を確認してください。公式の記載はPython版のInstallationにあります。
OSはWindows 11以降・Windows Server 2019以降・WSL、macOS 14以降、Debian 12/13、Ubuntu 22.04/24.04/26.04が対象です(System requirements)。インストールでつまずいたときの対処はPlaywrightのインストール方法とできない時の対処|バージョン確認・Windows・Pythonを参照してください。
PlaywrightとSeleniumの違い
差が出るのはブラウザとの通信方式です。Seleniumは言語バインディングがW3C WebDriverのHTTPリクエストを組み立て、ChromeDriverなどのドライバがそれを受けてブラウザを操作します。1操作ごとにHTTPの往復が入ります。Selenium 4はWebSocketで双方向に通信するWebDriver BiDiにも対応を進めていますが、主な操作は従来のWebDriverです。
| 観点 | Playwright 1.64 | Selenium 4.51 |
|---|---|---|
| ブラウザとの通信 | パイプでCDP等に直結 | HTTPでドライバ経由(W3C WebDriver) |
| 待機 | auto-wait内蔵 | 明示的な待機を書く |
| テスト分離 | テストごとにコンテキスト | ドライバ起動の単位で管理 |
| 対応言語 | JS/TS・Python・Java・.NET | Java・Python・JS・C#・Ruby |
| ブラウザ | 同梱のChromium/Firefox/WebKit | 手元のChrome・Firefox・Edge・Safari |
| ライセンス | Apache-2.0(.NET版はMIT) | Apache-2.0 |
新規にE2Eテストを始めるなら、操作前の状態確認を自動化でき、標準のpageフィクスチャでテストを分離できるPlaywright Testが向いています。ただし、アプリ固有の準備完了や処理結果は、アサーションなどで明示的に確認します。Rubyで書きたい、既存のSelenium GridやSaaSの実機環境に乗っている、テストが数百本単位で既にある、といった条件ならSeleniumを続けるほうが移行コストを払わずに済みます。Selenium側の仕組みと採用判断はSeleniumとは?WebDriverの仕組みと4系の実行手順・ツール選定を解説で詳しく比べています。
Playwrightのライセンスと商用利用
Playwright本体のライセンスはApache-2.0です(v1.64.1のLICENSE。npmの playwright-core の package.json の license 欄もApache-2.0)。PythonとJavaのバインディングもApache-2.0で、.NET版(NuGetのMicrosoft.Playwright)だけはMITです。いずれも商用利用を制限しない許諾型のライセンスです。社内システムのテストや受託開発、製品への組み込みを含め、商用利用でもライセンス料はかかりません。Playwright自体を再配布する場合は、ソースでもバイナリ(オブジェクト形式)でも、ライセンス文の添付、変更したファイルへの変更の明示、NOTICEファイルにある帰属表示の引き継ぎが必要です(Apache License 2.0の第4条)。テストに使うだけなら追加の手続きは要りません。
費用が発生しうるのは周辺サービスです。Azure App TestingのPlaywright Workspacesは、クラウド上のブラウザでテストを並列実行する有料サービスで、最初のワークスペースに限り、30日間・ブラウザ実行時間の合計100分を上限とする無料試用があり、無料枠を超えた利用は従量課金です(Microsoft Learn)。前身のMicrosoft Playwright Testingは2026年3月8日に廃止されています。自分のPCやCIで実行する場合も、Playwright本体のライセンス料は不要ですが、CIや実行基盤の利用料は別途発生する場合があります。
なお、npx playwright install で入るブラウザは、それぞれのブラウザのライセンスに従います。Chromium用の配布ビルドは1.57からChrome for Testingへ移行しました。ただしLinux arm64は当初対象外で、1.63から切り替わっています。
Playwrightの使い始め(最小構成)
Node.jsのプロジェクトで次を実行すると、設定ファイル、サンプルテスト、ブラウザ一式が用意されます。
npm init playwright@latest
次のコードをtests/example.spec.tsとして保存します。ページを開き、タイトルとリンクの表示を確かめる最小のテストで、1.64.1で実行すると1件成功します。getByRole は画面上の役割(リンク・見出し・ボタンなど)とその名前で要素を探すロケーターで、CSSのクラス名変更に強いので公式も推奨しています。example.comは2026年10月時点で見出しが無く、テストや監視に使わないよう本文で求めているため、例に使っていません。
import { test, expect } from '@playwright/test';
test('トップページの表示確認', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
});
実行は npx playwright test、トレースも記録する場合は npx playwright test --trace on を使います。生成されたHTMLレポートは npx playwright show-report で開きます。toBeVisible() などのアサーションも、条件を満たすまで既定5秒は再試行します。
Playwrightを使うべき場面・見送る場面
Playwrightが効くのは、複数ブラウザで動作を保証したいWebアプリのE2Eテスト、ログインや非同期の描画を含む画面フロー、CIで毎回回す回帰テストです。auto-waitとテストごとのコンテキストが、タイミングや前のテストの状態に左右される失敗を減らします。チームでテストやCIの仕組みづくりから進めたい場合は、DevOps・CI/CD導入支援で相談を受けています。
次の条件に当てはまるなら、Playwrightは選びません。
- JavaScriptを使わない静的なHTMLを取得するだけ:ブラウザの起動(Chromiumで約0.7秒)が無駄になります。HTTPクライアントでHTMLを取るほうが速く軽く済みます(スクレイピングとは?クローリング・APIとの違いと実装・法務の判断を解説)
- iOS・Androidのネイティブアプリ:Playwrightが扱うのはブラウザだけです。AndroidではChromeに加えてWebViewや一部の端末操作にも実験的に対応していますが、iOS・Androidのネイティブアプリを横断してテストする用途ではAppiumを選びます(Appium Desktopは終了|Appium 3時代のInspector移行)
- Python 3.9以前から上げられない環境:1.61以降は利用できません。Python 3.9では1.60.0までで、3.8以前では対応する版がさらに古くなります
- Internet Explorerでの動作確認や、既存のSeleniumテストが大量に安定稼働している現場
ブラウザ操作を自動化する方式全体(コード・記録型RPA・AIエージェント)の中でどれを選ぶかはBrowser Automationとは?ブラウザ操作を自動化する4つの方式と選び方【2026年】で比べています。
よくある質問
Playwrightの読み方と意味は?
「プレイライト」と読みます。英語のplaywrightは劇作家・脚本家の意味です。Microsoftが開発しているオープンソースのブラウザ自動化・E2Eテストフレームワークで、GoogleでPuppeteerを作ったチームが開発し、npmでは2020年2月に0.10.0が公開されました。
PlaywrightはWebSocketでブラウザと通信しているのですか?
ローカルで起動したブラウザとはWebSocketではなくパイプで通信します。Chromiumは –remote-debugging-pipe でCDP、FirefoxとWebKitは専用のプロトコルです。WebSocketを使うのは launchServer で立てたブラウザへ connect するときや、connectOverCDP で既存のChromeにつなぐときです。
PlaywrightとSeleniumはどちらを選ぶべきですか?
新規のWebアプリのE2Eテストなら、auto-waitとテストごとの分離が既定で効くPlaywrightが向いています。Rubyで書く場合や、既存のSelenium Grid・大量のSeleniumテストがある場合はSeleniumを続けるほうが合理的です。
Playwrightは商用利用でも無料ですか?
無料です。ライセンスは本体がApache-2.0、.NET版がMITで、商用でもライセンス料はかかりません。本体のライセンス料とは別に、Playwright Workspacesなどの有料サービスやCIの実行時間・ストレージに費用が発生する場合があります。
PlaywrightはPythonでも使えますか?何ができますか?
使えます。pip install playwright のあと playwright install でブラウザを入れます。1.61以降はPython 3.10以上が必要で、3.9では1.60.0が入ります。できることはNode.js版と同じで、ブラウザ操作、スクリーンショット、ネットワークのモックなどです。テストランナーはpytest-playwrightを組み合わせます。