コンテンツへスキップ

Playwrightを使ったブラウザ操作自動化

Playwrightを説明する必要にかられて作成。

なお、本記事の利用用途はE2Eテストではなく、ただのブラウザ操作自動化です。

前提としてNode.js 12以上が必要です。そちらの説明は「NVM for Windowsを使って複数バージョンのnodejsをインストール」をご覧ください。

前準備

実験用にtest-playwrightディレクトリを作ります。今後はこのディレクトリで作業します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>mkdir test-playwright && cd test-playwright
>mkdir test-playwright && cd test-playwright
>mkdir test-playwright && cd test-playwright

Playwrightのインストール

npmを使ってインストール

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>npm install playwright
added 2 packages in 2s
>npm install playwright added 2 packages in 2s
>npm install playwright

added 2 packages in 2s

package.jsonやnode_modulesディレクトリなどが生成されます。

バージョン確認

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>npx playwright --version
Version 1.31.2
>npx playwright --version Version 1.31.2
>npx playwright --version
Version 1.31.2

Playwrightのデモ

Yahoo! JAPANを開く

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> 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)を以下の手順でマウス操作してみます。

  1. 検索フォームから「Google」とタイプして検索
  2. 検索結果からGoogleをクリック
  3. Googleの検索フォームに「Yahoo」とタイプして検索
  4. Googleの検索結果からYahoo! JAPANをクリック

上記の手順が済んだらPlaywright Inspectorで生成されたコードを確認

※Chromiumを閉じるとPlaywright Inspectorまで一緒に閉じてしまうので注意

出来上がったコード(下記参照)をコピーし、yahoo.cjs と名付けてUTF-8で保存

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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(); })();
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();
})();

上記コードを実行

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>node yahoo.cjs
>node yahoo.cjs
>node yahoo.cjs

Chromiumが立ち上がり、「Yahoo検索→Google検索→Yahooへ」の操作を自動で行う

スクリーンショットを撮る1行を追加

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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');

(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();
})();

ちなみに、以下のコメントアウトした部分がなくても動きます(マウスのために入った余計な操作なので)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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(); })();
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を画面非表示)で実行

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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');

(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();
})();

ざっくりこんな感じ

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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(); })();
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();とする記述が望ましいようです。

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA