はじめに
みなさんこんにちは。インプルの岩崎です。
本日はいつもの記事とすこし変わって、技術調査で調べたフレームワークのお話です。
Playwrightとは
今回紹介するPlaywrightとは、Microsoft が開発した E2E(End-to-End)テスト自動化フレームワークです。
一番の特徴は、ブラウザを自動で操作することができ、以下のことが可能です。
- 画面キャプチャ(スクリーンショット)
- 動画・トレース記録
- 各ブラウザ(Chromium / WebKit / Firefox)対応
- モバイル相当のデバイスでの動作確認
- hover・クリック・フォーム入力などの操作
- ポップアップや新規タブの検知と操作
- 高速で安定した動作(Seleniumより安定)
特に今回、技術して注目した点が、画面キャプチャ(スクリーンショット)、モバイル相当のデバイスでの動作確認、hover・クリック・フォーム入力などの操作、の3点に注目しています。今回は、これらの情報をAIに渡して、画面の分析をしてもらうために、このフレームワークに着目しました。
Playwrightのスクリーンショットの撮り方
Playwrightでは、スクリーンショットを撮影するために、コードが必要です。コードで実行する際には、2つのキャプチャ方法があります。
1つ目は、Playwright Test Runner を使う方式です。
E2Eテストの標準的な書き方に従っており、テスト形式でコードがきれいに整理されます。ブラウザの設定・並列実行などが自動で整うようになっています。npx playwright test で実行し、キャプチャを行うためのコードはtests/xxx.spec.ts に配置します。
2つ目は、Node.js の通常スクリプトとして実行する方式です。
フォルダ名などは自由(scripts/など)にすることができ、Playwright Test Runner を使わないので柔軟にキャプチャなどを実行することができます。自作のプログラムなどを組み込むのであれば、こちらの方が良さそうですね。node capture.js のように直接実行することができます。
それぞれの手法は、下記のような用途に向いています。
| 方法 | 向いている用途 |
|---|---|
| ① Playwright Test Runner | テスト、UI動作チェック、動的操作 |
| ② Node.js スクリプト | スクショ大量生成、AI比較、ツール構築 |
今回のAIと連携して画像解析までをさせる、となると、2つ目のNode.js の通常スクリプトとして実行する方式の方が良さそうですが、今回は練習の意味も込めて、Playwright Test Runner を使う方式も試してみましょう!
① Playwright Test Runner
早速ですが、使ってみましょう。ここでは、まずPlaywrightプロジェクトの構築を行い、実際にAIに画像を渡して分析をしてもらう流れをやってみます。
Playwrightプロジェクトの構築
まずはPlaywightを操作するフォルダを作成します。
mkdir playwright-project
cd playwright-project
続いて、Node.js プロジェクトを作成します。
npm init -y
さて、いよいよPlaywrightをインストールします。
この時点で、Playwright が、Chromium、Webkit、Firefoxの3つを自動インストールします。
npm install -D @playwright/test
npx playwright install
続いて、スクリーンショットを実行するコードを保管しておくファイル(後ほど説明)と、スクリーンショットを保管しておくフォルダを準備しておきましょう。
mkdir tests screenshots
ここまで準備できると、スクリーンショットを取得する準備ができました。一旦ファイル構成のおさらいです。
project-root/
│
├─ package.json
|
├─ node_modules/
│ └─ ...
|
├─ tests/ ← Playwright が自動で読み込むフォルダ
│ └─ ...
│
└─ screenshots/ ← 撮影した画像を保存(あなたの出力場所)
静的なスクリーンショットを撮影する
まずは静的なスクリーンショットを撮影することで、正しくコードが動作しているいか確認して進めてきましょう!
今回は弊社HPをスクリーンショットしてみることにします。かなりアニメーションが入っていますが、全体がとりあえず撮影されるはずです。

先ほど作った tests/ フォルダに、下記のようなファイルを作成します。ファイル名は basic-cap.spec.ts としておきましょう。await page.goto('https://www.impl.co.jp/'); のURLは、みなさんの任意のURLへ書き換えてください。
import { test } from '@playwright/test';
test('basic screenshot', async ({ page }) => {
await page.goto('https://www.impl.co.jp/');
await page.screenshot({
path: 'screenshots/basic.png',
fullPage: true,
});
});
ファイル名は基本的にお任せですが、Playwrightは全てのファイルを認識するわけではありません。ファイル名の後は、必ず下記の4ついずれかが含まれるようにしてください。
*.spec.ts*.spec.js*.test.ts*.test.js
その後、下記のコマンドで実行させてみましょう。すると、screenshots/ フォルダに全体のキャプチャが格納されます。
npx playwright test

しかし、よくよくみてみると、アニメーションの発火が遅くうまく動作していませんね。01の左上など、ひどいですね・・・。
しかし、Playwrightでは、これを柔軟に調節することができます。キャプチャするときに数秒待つコードを追加することで、発火後に撮影できるようにしています。先ほどの上記コードを下記のように書き換えてみましょう。コメントアウトを追加した部分が新たに追加したプログラムです。
import { test } from '@playwright/test';
test('basic screenshot', async ({ page }) => {
await page.goto('https://www.impl.co.jp/');
await page.waitForLoadState('networkidle'); // ページ内のリソースが完全に読み込まれるまで待つ
await page.mouse.wheel(0, 500); // 500pxスクロール
await page.waitForTimeout(1000); // エフェクトが発火する時間待つ。
await page.screenshot({
path: 'screenshots/basic2.png',
fullPage: true,
});
});
すると、先ほどは表示されていなかった文字が出てきましたね。代わりにヘッダーがついてきてしまいましたが、これも先ほどのような調節で解決することができます。
とりあえず撮影できたようでよかったです。このように、柔軟に調節できる点がいいところですね。

動的なスクリーンショットの撮り方
下記コマンドを実行しましょう。https://www.impl.co.jp/ の部分は、みなさんのスクリーンショットを撮影したい任意のHPのURLを入れてください。
npx playwright codegen https://www.impl.co.jp/

すると、ChromiumというブラウザとPlaywright Inspectorというエディターのような画面が起動します。
動的な挙動の場合、何をすると(クリックやホバー)どんな実行結果になるのか、それをすべて明らかにしなければなりません。そのために、ここでどのようなスクリーンショットを撮影したいのか、コード化していきます。
Chromiumは、Playwrightの用ブラウザで、先ほどURLを記載したサイトが表示されています。(今回の場合では、弊社公式サイト)
例えば下記の画像の場合、左下の白い枠(locator 表示)は、「ここを操作したらコードを生成するよ」というPlaywright の機能です。

Playwright Inspectorは、操作ログが自動でコードになる場所 です。いま表示されているコードは、「impl.co.jp にアクセスした」という操作だけが記録された状態です。ここから操作するだけで コードが自動追加されます。

この状態(Playwright Inspector の 左上が Recordになっている状態)で、Chromiumのヘッダーのボタンをぽちぽちしてみましょう。すると、Playwright Inspectorのエディタに、コードが自動で追加されていきます。
await page~ 2行目からの部分が追加された部分で、”Company” をクリックしたということがここからわかるかと思います。


このクリックの動作が、コードをとして自動生成する機能で、「動的に操作した流れを、そのまま自動化するコード」が作られたということです。これをまるっとコピーして、下記のように、画面をキャプチャするプログラムをくっつけることで、動的動作に対してキャプチャが取れるようになっています。(今回はアニメーションの遅延も加味し、待機時間も追加)
import { test, expect } from '@playwright/test';
test('company page capture', async ({ page }) => {
await page.goto('https://www.impl.co.jp/'); // TOPへ
await page.locator('#header').getByRole('link', { name: 'Company' }).click(); // Companyへ移動
await page.waitForTimeout(1200); // 1.2秒待つ(必要に応じて調整) // ページのアニメーションや表示を待つ
// スクリーンショット
await page.screenshot({
path: 'screenshots/hover.png',
fullPage: true
});
});
このファイルも、静的ページをキャプチャした時と同様に、tests/ フォルダに配置しましょう。ファイル名も注意してください。下記のコマンドで実行されます。
npx playwright test
すると、先ほどの静的キャプチャも再度実行されますが、tests/ 内にあるキャプチャのファイルが全て実行され、 hoverした際に表示されるヘッダーのメニューが出てきました!
これで、動的挙動についても問題なくキャプチャできたことがわかります。

② Node.js スクリプト
続けて、Node.jsから呼び出して画像解析できるようにしていきましょう。アプリなどに組み込む場合は、先ほども述べたように、こちらでやるのがいいです。
いきなりアプリに組み込むのも壊しそうで怖いので、まずはサンプルファイルを作って実験をしてみましょう。
実験環境を作る
まずは下記のようなファイル構成で、実験環境を作ってみます。
/playground/
├── capture.js
├── compare.js(任意)
├── package.json
└── screenshots/
下記のコマンドで一気に作っちゃいましょう。
mkdir playground
cd playground
npm init -y
npm install playwright
Node.jsで動かす仕組みを作る
先ほどまでは、spec形式でtest runnerから実施をしてきましたが、今回はNode.jsからPlaywrightを直接叩く形式です。なので、何度も言っていますが、本番システムに組み込みやすい形式です。
簡単にですが、下記のようなコードをchatGPTに作ってもらいました。
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://www.impl.co.jp/');
await page.waitForTimeout(1500); // 動的アニメーション待ち
await page.screenshot({
path: 'screenshots/test.png',
fullPage: true
});
await browser.close();
})();
これを下記のコマンドで実行してみると、screenshots/test.png が生成されるのがわかるかと思います!
node capture.js

先ほどと違い、Node.jsから無事にスクリーンショットを撮ってくることができました。これで本番コードでも動く「Playwright単体モジュール」 が完成です!
ちょっとアレンジを加えてみる
せっかくなので、取得した画像をAIに解析してもらうこともしてみましょう。
簡単にGPTにプログラムを作ってみました。取得した画像をbase64としてGPTに画像を投げ、画像の内容を説明してもらうプログラムになっています。
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://www.impl.co.jp/');
await page.waitForTimeout(1500);
// キャプチャ
const screenshotPath = 'screenshots/test.png';
await page.screenshot({ path: screenshotPath, fullPage: true });
// Playwright終了
await browser.close();
// 画像をbase64として読み込み
const imageData = readFileSync(screenshotPath, { encoding: 'base64' });
// AIに画像を投げる
const result = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "user",
content: [
{ type: "text", text: "この画像の内容を説明して。" },
{
type: "image_url",
image_url: {
url: `data:image/png;base64,${imageData}`
}
}
]
}
]
});
console.log("AIの回答:", result.choices[0].message.content);
})();
これを実行させると、下記のような返答をしてくれました。弊社のサイトを分析してくれていますね笑。
AIの回答: この画像は、ウェブサイトのデザインまたはアプリケーションのインターフェースを示しています。主な内容は以下の通りです。
1. **技術革新**: テクノロジーを使って新しいことを実現するというメッセージが強調されています。
2. **セクション**: 「Strength」(強さ)や「Skill-Repo」(スキルリポジトリ)など、複数のセクションがあり、それぞれに説明が付いているようです。
3. **サービス内容**: モバイルアプリ、ウェブサービス、クラウドサービスなど、提供される具体的なサービスが列挙されています。
4. **連絡先情報**: おそらく、問い合わせのための連絡先情報(電話番号など)が含まれています。
5. **リクルート情報**: 求人情報や会社の情報も示されているようです。
全体的にモダンでシンプルなデザインが採用されており、情報が整理されている印象を受けます。
こんな感じで、他のプログラムともくっつけられるのが、Node.js でのメリットとなります。
おわりに
いかがだったでしょうか?
今回のプログラムはGitHubにもありますので、よければぜひご覧ください!
ご覧いただきありがとうございました。