Playwrightを説明する必要にかられて作成。
なお、本記事の利用用途はE2Eテストではなく、ただのブラウザ操作自動化です。
前提としてNode.js 12以上が必要です。そちらの説明は「NVM for Windowsを使って複数バージョンのnodejsをインストール」をご覧ください。
前準備
実験用にtest-playwrightディレクトリを作ります。今後はこのディレクトリで作業します。
>mkdir test-playwright && cd test-playwright
>mkdir test-playwright && cd test-playwright
>mkdir test-playwright && cd test-playwright
Playwrightのインストール
npmを使ってインストール
>npm install playwright
added 2 packages in 2s
>npm install playwright
added 2 packages in 2s
package.jsonやnode_modulesディレクトリなどが生成されます。
バージョン確認
>npx playwright --version
>npx playwright --version
Version 1.31.2
>npx playwright --version
Version 1.31.2
Playwrightのデモ
Yahoo! JAPANを開く
> npx playwright codegen "https://www.yahoo.co.jp"
> npx playwright codegen "https://www.yahoo.co.jp"
> npx playwright codegen "https://www.yahoo.co.jp"
Yahoo! Japanを開いた状態でChromium とPlaywright Inspector の2つが起動
Playwright Inspectorウィンドウの Target: 「Test Runner」を「Library」に変更

Chromium(Yahoo! Japan)を以下の手順でマウス操作してみます。
- 検索フォームから「Google」とタイプして検索
- 検索結果からGoogleをクリック
- Googleの検索フォームに「Yahoo」とタイプして検索
- Googleの検索結果からYahoo! JAPANをクリック
上記の手順が済んだらPlaywright Inspectorで生成されたコードを確認
※Chromiumを閉じるとPlaywright Inspectorまで一緒に閉じてしまうので注意
出来上がったコード(下記参照)をコピーし、yahoo.cjs と名付けてUTF-8で保存
const { chromium } = require('playwright');
const browser = await chromium.launch({
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
// ---------------------
await context.close();
await browser.close();
})();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
// ---------------------
await context.close();
await browser.close();
})();
上記コードを実行
>node yahoo.cjs
Chromiumが立ち上がり、「Yahoo検索→Google検索→Yahooへ」の操作を自動で行う
スクリーンショットを撮る1行を追加
const { chromium } = require('playwright');
const browser = await chromium.launch({
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
// ここに1行追加しました
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
// ここに1行追加しました
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
ちなみに、以下のコメントアウトした部分がなくても動きます(マウスのために入った余計な操作なので)
const { chromium } = require('playwright');
const browser = await chromium.launch({
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
headless: falseをtrueに変更するとヘッドレスモード(Chromiumを画面非表示)で実行
const { chromium } = require('playwright');
const browser = await chromium.launch({
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
// ここです
headless: true
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
// ここです
headless: true
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.yahoo.co.jp/');
//await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).click();
await page.getByRole('searchbox', { name: '検索したいキーワードを入力してください' }).fill('Google');
await page.getByRole('button', { name: '検索' }).click();
await page.getByRole('link', { name: 'Google https://www.google.com ...' }).click();
//await page.getByRole('combobox', { name: '検索' }).click();
await page.getByRole('combobox', { name: '検索' }).fill('Yahoo');
await page.getByRole('combobox', { name: '検索' }).press('Enter');
await page.getByRole('link', { name: 'Yahoo! JAPAN Yahoo! JAPAN https://www.yahoo.co.jp' }).click();
await page.screenshot({ path : 'yahoo.png'});
// ---------------------
await context.close();
await browser.close();
})();
ざっくりこんな感じ
const { chromium } = require('playwright');
const browser = await chromium.launch({
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.example.jp/');
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.example.jp/');
// ここからやりたいことを書く
フォームを入力したり、プルダウンから選択したり
スクリーンショットを撮ったり、ボタンを押したり
// ここまで
await browser.close();
})();
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.example.jp/');
// ここからやりたいことを書く
フォームを入力したり、プルダウンから選択したり
スクリーンショットを撮ったり、ボタンを押したり
// ここまで
await browser.close();
})();
codegenで作成したコードのため、『「検索」ボタンをクリック』のような記述になっていますが、本来はdata-testid属性を用いて、HTML側で<button data-testid="search">検索</button>
、 Playwright側でawait page.getByTestId('search').click();
とする記述が望ましいようです。
参考