
Playwright CLIをWSLで動かしてみた
概要
こんにちは、クラスメソッド製造ビジネステクノロジー部の田中聖也です。
Playwright CLI(ターミナルのコマンドでブラウザを操作できるツール)がWSL上で動かせるのか気になったので検証してみました。

結論
先に結論を表にまとめます。
| 項目 | 必要か | 何をすれば入るか |
|---|---|---|
| ブラウザ | 必要(Windows側のブラウザは使われない) | playwright-cli install(Chromiumを~/.cache/ms-playwrightにダウンロード) |
| OSライブラリ | 必要(まっさらなUbuntu 24.04のWSLでは) | playwright-cli install-browser chromium --with-deps(内部でsudo apt-get) |
| Claude Code用のスキル | 任意(pnpmで使うならSKILL.mdの修正が必要) | playwright-cli install --skillsのあと、SKILL.mdをpnpm exec playwright-cli向けに直す |
※2026年10月時点の情報です。
環境
| 項目 | バージョン |
|---|---|
| ホストOS | Windows 11 Pro (10.0.26200) |
| WSL | 3.0.3.0 (WSL2、カーネル 6.18.54.1) |
| WSLg | 1.0.79 |
| ディストリビューション | Ubuntu 24.04.5 LTS (検証用に新規作成) |
| Node.js | v24.22.0 (NodeSource、Linux側) |
| pnpm | 12.14.0 (corepack) |
| @playwright/cli | 0.1.22 (内部のplaywrightは1.64.0-alpha) |
| ブラウザ | Chrome for Testing 155.0.8059.12 (chromium v1247) |
| Claude Code | 2.1.302 (ネイティブ版、WSL側、Opus 5.5) |
準備
検証用にまっさらなディストリビューションを作る
既存のUbuntuは別の用途でライブラリが入っている可能性があって、「何をインストールする必要があるか」を正確に判断できません。
そこで検証専用に、まっさらなディストリビューションを追加しました(PowerShellで実行)。
wsl --install Ubuntu-24.04 --name pw-clean --no-launch
wsl -l -v
--nameで既存のUbuntuと別名にできて、--no-launchを付けると初回起動時のユーザー作成が行われず、既定ユーザーはrootになります。
作った直後の状態は次のとおりでした。
| 項目 | 値 |
|---|---|
| dpkgパッケージ数 | 523 |
| node | なし |
| 日本語フォント | 0件(fc-list :lang=ja) |
~/.cache/ms-playwright |
なし |
※この手順は必須ではありません。検証用で念のために実施しています。
Node.jsとpnpmのインストール
Node.jsはLinux側に入れます(pwuserで実行)。
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo corepack enable pnpm
pnpm --version
Node導入で増えたdpkgパッケージはnodejsとapt-transport-httpsの2つだけで、ブラウザ用のライブラリは入っていません。
検証用のアプリ
操作対象には、ViteでTodoアプリ(追加・完了切り替え・編集・削除、localStorageに保存)を作りました。
getByRoleで取りやすいように、ボタンのaria-labelにTodoのタイトルを含めています。
mkdir -p ~/work && cd ~/work
pnpm create vite todo-e2e --template react-ts --no-interactive < /dev/null
cd todo-e2e
pnpm install
pnpm run dev
やってみた
各手順の前後でdpkg-query -W -f='${Package}\n' | sortの結果を保存して、パッケージの増減を差分で確認しました。
手順1: @playwright/cliを追加する
cd ~/work/todo-e2e
pnpm add -D @playwright/cli
Packages: +3
Agent skills awaiting approval: @playwright/cli.
Run "pnpm approve" to review them.
devDependencies:
+ @playwright/cli 0.1.22
- 追加されたのは
@playwright/cli、playwright、playwright-coreの3パッケージだけ - dpkgの差分は0件。この時点ではOSパッケージもブラウザも増えません
node_modules/.binにできるのはplaywright-cliだけで、playwrightコマンドはできません(ここが後でハマります)- 「Agent skills awaiting approval」はpnpm 12の権限承認の表示で、今回は承認していません
失敗1: ブラウザなしでopenするとChromeを探しに行って失敗する
pnpm exec playwright-cli open http://localhost:5173/
Error: Daemon pid=976: Daemon process exited with code 1
[PlaywrightError: Chromium distribution 'chrome' is not found at /opt/google/chrome/chrome
Run "pnpm exec playwright install chrome"] {
設定ファイルが無いときは、Google Chrome本体(/opt/google/chrome/chrome)を探しに行きます。
Windows側のChromeを見に行ってくれる、ということはありませんでした。
手順2: playwright-cli installでChromiumを入れる
pnpm exec playwright-cli install-browser chromium --dry-run # 入る内容を先に確認
pnpm exec playwright-cli install
✅ Workspace initialized at `/home/pwuser/work/todo-e2e`.
Downloading Chrome for Testing 155.0.8059.12 (playwright chromium v1247) from https://cdn.playwright.dev/builds/cft/155.0.8059.12/linux64/chrome-linux64.zip
... 100% of 189.1 MiB
Downloading FFmpeg (playwright ffmpeg v1011) ... 100% of 2.3 MiB
✅ Created default config for chromium at .playwright/cli.config.json.
20秒ほどで完了しました。ダウンロードされたものは次のとおりです。
| ダウンロードされたもの | 置き場所 | サイズ(zip → 展開後) |
|---|---|---|
| Chrome for Testing 155.0.8059.12 | ~/.cache/ms-playwright/chromium-1247 |
189.1MiB → 399M |
| FFmpeg | ~/.cache/ms-playwright/ffmpeg-1011 |
2.3MiB → 4.9M |
生成された.playwright/cli.config.jsonは、Chromiumを使う設定になっています。
{
"browser": {
"browserName": "chromium",
"launchOptions": {
"channel": "chromium"
}
}
}
失敗2: installだけではlibnspr4.soが無くて起動しない
installした直後にもう一度openしてみます。
pnpm exec playwright-cli open http://localhost:5173/
[pid=1358][err] /home/pwuser/.cache/ms-playwright/chromium-1247/chrome-linux64/chrome: error while loading shared libraries: libnspr4.so: cannot open shared object file: No such file or directory
...
- [pid=1358] <process did exit: exitCode=127, signal=null>
今度はブラウザのプロセスが起動直後に落ちました(exit 127)。
ldd(実行ファイルが必要とする共有ライブラリを表示するコマンド)で確認すると、足りないのは5つでした。
$ ldd ~/.cache/ms-playwright/chromium-1247/chrome-linux64/chrome | grep 'not found'
libnspr4.so => not found
libnss3.so => not found
libnssutil3.so => not found
libsmime3.so => not found
libasound.so.2 => not found
手順3: install-browser chromium --with-deps でOSライブラリを入れる
pnpm exec playwright-cli install-browser chromium --with-deps --dry-run
pnpm exec playwright-cli install-browser chromium --with-deps
また、install-browser chromiumはChrome Headless Shell(ヘッドレス専用の軽量ブラウザ)も270MBほどダウンロードします。ただ、playwright-cliはヘッドレスでもChromium本体(--headless付き)を起動するので、今回の使い方では使われません。
手順4: TodoのCRUDを一通り操作する
ここからは、openしたブラウザに対してTodoのCRUDを手で操作しました。
$ playwright-cli open http://localhost:5173/
### Browser `default` opened with pid 2765.
$ playwright-cli snapshot
- main [ref=f1e3]:
- heading "Todoリスト" [level=1] [ref=f1e4]
- generic [ref=f1e5]:
- generic [ref=f1e6]: 新しいTodo
- textbox "新しいTodo" [ref=f1e7]
- button "追加" [ref=f1e8] [cursor=pointer]
- paragraph [ref=f1e9]: Todoはありません
snapshotは、ページの要素ツリーをref(要素に振られる参照ID)付きで返してくれます。
clickやfillのtargetには、このrefでも、Playwrightのロケーターでも指定できました。
$ playwright-cli fill f1e7 牛乳を買う
await page.getByRole('textbox', { name: '新しいTodo' }).fill('牛乳を買う');
$ playwright-cli click f1e8
await page.getByRole('button', { name: '追加' }).click();
$ playwright-cli fill "getByLabel('新しいTodo')" 記事の下書きを書く
$ playwright-cli press Enter
完了の切り替え、タイトルの編集、読み込み直し、削除も一通り操作できました。
localStorageの中身はlocalstorage-getで確認できます。
$ playwright-cli reload
$ playwright-cli localstorage-get todo-e2e:todos
todo-e2e:todos=[{"id":"64d8e510-...","title":"牛乳を買う","completed":true},{"id":"cf923dc9-...","title":"記事を公開する","completed":false},{"id":"59f46fe0-...","title":"Playwrightを試す","completed":false}]
読み込み直しても、完了状態と編集後のタイトルが残っていました。
| 編集中 | 編集後(保存 / Escでキャンセル) |
|---|---|
![]() |
![]() |
注意点が1つあって、編集すると、その行の子要素は描画し直されて新しいrefが振られます(f1e14からf1e39など)。読み込み直すと、refの頭もf1からf2に変わります。
前のsnapshotのrefを使い回すと目的の要素を取れないので、続けて操作するならロケーターで指定する方が安定しますね。
手順5: --headedでWindows側にウィンドウを出す
pnpm exec playwright-cli -s=headed open --headed http://localhost:5173/
pnpm exec playwright-cli -s=headed fill "getByLabel('新しいTodo')" 'WSLgで表示'
pnpm exec playwright-cli -s=headed press Enter
WSL側はDISPLAY=:0、WAYLAND_DISPLAY=wayland-0で、WSLg(WSL上のLinux GUIアプリをWindowsのデスクトップに表示する仕組み)が有効な状態です。
Windows側のスクリーンショットで確認すると、「Todo E2E - Google Chrome for Testing (pw-clean)」というウィンドウが出ていることを確認できました。

手順6: playwright-cli install --skills
Claude Code用のスキルを入れる--skillsも試しました。
pnpm exec playwright-cli install --skills
✅ Workspace initialized at `/home/pwuser/work/todo-e2e`.
✅ Skill installed to `.claude/skills/playwright-cli`.
作られたのはワークスペース直下の.claude/skills/playwright-cli/(11ファイル)だけで、ホームディレクトリには何も作られませんでした。
ただ、スキルの中身はnpx(15か所)か、グローバルインストールされたplaywright-cliを前提に書かれています。今回のようにpnpmでpnpm exec playwright-cliとして使う場合、Claude Codeがこのとおりに実行するとどうなるのかが気になったので、実際に試してみました。
Claude CodeはWSL側に入れて、~/work/todo-e2eで起動します。
curl -fsSL https://claude.ai/install.sh | bash
source ~/.profile # ~/.local/bin を PATH に入れるため
cd ~/work/todo-e2e
claude
インストーラーが「~/.local/bin is not in your PATH」と警告して、claude: command not foundになりました。
Ubuntuの~/.profileは、ログインした時点で~/.local/binがあればPATHに足す作りです。ログインしたあとにインストーラーが~/.local/binを作ったので、PATHに入っていませんでした。source ~/.profileするか、入り直せば通ります。
なお、Claude Codeを入れてもdpkgの差分は0件でした。
起動して/skillsを実行すると、playwright-cliが出てきました。プロジェクトの.claude/skills/はそのまま読み込まれます。
失敗3: スキルのとおりだとコマンドが通らず、Claude Codeが遠回りする
依頼文にはあえてplaywright-cliの名前を入れずに、次のように頼みました。
http://localhost:5173/ の Todo アプリをブラウザで開いて、「牛乳を買う」という Todo を1件追加し、一覧に表示されることを確かめてください。
ツール名を出さなくても、最初にSkill(playwright-cli)が読み込まれました。そのあとのBashは次のとおりです。
| # | Claude Codeが実行したコマンド | 結果 |
|---|---|---|
| 1 | playwright-cli open http://localhost:5173/ ... |
command not found(exit 127) |
| 2 | npx --no-install playwright --version |
playwright: not found(exit 127) |
| 3 | ls -la && cat package.json; ...; curl ... http://localhost:5173/ |
package.jsonに@playwright/cliを見つける |
| 4 | ls node_modules/.bin | grep -i playwright |
playwright-cliを見つける |
| 5 | node_modules/.bin/playwright-cli open ... && snapshot |
成功 |
| 6 | node_modules/.bin/playwright-cli fill e7 "牛乳を買う" && click e8 && ... |
成功(「未完了 1 件 / 全 1 件」) |
スキルに書かれた2つの方法はどちらも失敗しましたが、Claude Codeが自分でpackage.jsonを読んで、node_modules/.bin/playwright-cliを直接使う方法に切り替えてくれました。
結果としてTodoは追加できたものの、Bash 6回のうち4回は失敗と調査に使われています。
手順7: SKILL.mdをpnpm向けに直す
そこで、SKILL.mdを3か所だけ書き換えました(references/はそのまま)。
-allowed-tools: Bash(playwright-cli:*) Bash(npx playwright:*) Bash(npx --no-install playwright:*)
+allowed-tools: Bash(pnpm exec playwright-cli:*) Bash(playwright-cli:*) Bash(npx playwright:*) Bash(npx --no-install playwright:*)
---
# Browser Automation with playwright-cli
+> **In this project**, `playwright-cli` is installed as a devDependency with pnpm and is NOT on PATH.
+> Run every `playwright-cli` command in this document as `pnpm exec playwright-cli ...` (e.g. `pnpm exec playwright-cli open https://example.com/`).
+> Do not use `npx` or `npm install -g`.
末尾のInstallation節も、npx --no-install playwright --versionとnpm install -g @playwright/cli@latestを案内していたので、pnpm exec playwright-cli --versionで確認し、無ければインストールする前にユーザーに聞く、という内容に置き換えています。
新しいセッションで同じ依頼をすると、1回目からpnpm exec playwright-cliを使ってくれました。
pnpm exec playwright-cli open http://localhost:5173/ && pnpm exec playwright-cli --raw snapshot
pnpm exec playwright-cli fill e7 "牛乳を買う" && pnpm exec playwright-cli click e8 && pnpm exec playwright-cli --raw snapshot; cat .playwright-cli/console-....log
pnpm exec playwright-cli close
| 項目 | 直す前 | 直したあと |
|---|---|---|
| Bashの回数 | 6回(失敗2、調査2、操作2) | 3回(操作2、ブラウザを閉じる1) |
| 失敗したコマンド | 2つ | なし |
| 許可の確認 | 1回 | 0回 |
| 1ターンの所要時間 | 28.7秒 | 19.2秒 |
allowed-toolsにBash(pnpm exec playwright-cli:*)を足したので、許可の確認も出なくなりました。
pnpmで使うなら、install --skillsのあとにSKILL.mdを直しておくのが良さそうです。
※どちらも1回ずつしか試していないので、回数や時間には多少ばらつきがあると思います。
実行手順まとめ
# 1: Node.jsとpnpmをLinux側に入れておく(/mnt/c側のものが見えていないことを確認)
which node pnpm
# 2: プロジェクトはWSL側(~/配下)に作ってCLIを追加
mkdir -p ~/work/pw-cli && cd ~/work/pw-cli
pnpm init
pnpm add -D @playwright/cli
# 3: ブラウザ(Chromium)と設定ファイルを入れる
pnpm exec playwright-cli install
# 4: OSライブラリを入れる(sudoが必要。日本語フォントも入る)
pnpm exec playwright-cli install-browser chromium --with-deps
# 5: 動作確認
pnpm exec playwright-cli open https://example.com
pnpm exec playwright-cli snapshot
pnpm exec playwright-cli close-all
# 6: (Claude Codeから使う場合)スキルを入れて、SKILL.mdをpnpm exec向けに直す
pnpm exec playwright-cli install --skills
※手順3のあとに手順4を実行する順番で検証しています。逆の順番は試していません。












