Playwright 高度なページ操作

この章では、Playwright の高度なページ操作を紹介します。この部分は実際のテストニーズにより近く、以下を含みます。待機メカニズム、フォーム処理、ポップアップダイアログなどの高度な機能です。


待機メカニズム

Playwright の最大の利点の1つはスマート待機(auto-waiting):ほとんどの操作(例えばclick, fill)は要素が表示され操作可能になるまで自動的に待機します。ただし、複雑なシナリオでは、手動で待機を制御する必要があります。

1. 暗黙の待機(Auto-waiting)

Playwright が内蔵する待機メカニズム:

  • 要素が表示されていること
  • クリック可能 / 操作可能であること
  • ページの読み込みが完了していること

例

await page.click('#submit'); // ボタンが表示されクリック可能になるのを自動待機

2. 明示的な待機

待機メソッドを明示的に呼び出します。例えば、特定のセレクタ、テキスト、リクエストを待機します。

例

await page.waitForSelector('#result', { state: 'visible' });

一般的なstate値:

  • 'attached'→ 要素がDOMに存在する
  • 'visible'→ 要素がページ上で表示されている
  • 'hidden'→ 要素が非表示
  • 'detached'→ 要素が削除された

3. 要素の出現 / 消失を待つ

// 等待元素出现
await page.waitForSelector('#loading', { state: 'visible' });

// 等待元素消失
await page.waitForSelector('#loading', { state: 'hidden' });

4. ネットワークリクエストの完了を待つ

特定のリクエストの完了を待ちます。AJAX リクエストや API 呼び出しでよく使用されます。

// 等待指定 URL 的请求完成
await page.waitForResponse(response => 
  response.url().includes('/api/login') && response.status() === 200
);

5. カスタム待機条件

を通じてpage.waitForFunctionカスタム待機ロジックを実行します。

// 等待页面上计数器达到 10
await page.waitForFunction(() => {
  return document.querySelector('#count').innerText === '10';
});

フォーム処理

フォームはテストで最も一般的なインタラクションシーンです。Playwright はフォームコントロールを操作するための豊富な API を提供します。

1. 入力ボックス操作

await page.fill('#username', 'admin');  // 清空并输入
await page.type('#search', 'Playwright', { delay: 100 }); // 模拟逐字输入

2. ドロップダウンメニュー選択

// 通过 value
await page.selectOption('#country', 'china');

// 通过标签文本
await page.selectOption('#country', { label: 'United States' });

// 通过 index
await page.selectOption('#country', { index: 2 });

3. チェックボックスとラジオボタン

// 勾选复选框
await page.check('#agree');

// 取消勾选
await page.uncheck('#subscribe');

// 点击单选框
await page.check('input[type="radio"][value="male"]');

4. ファイルアップロード

// 直接上传文件
await page.setInputFiles('#upload', 'example.png');

// 上传多个文件
await page.setInputFiles('#upload', ['a.png', 'b.png']);

// 清空文件
await page.setInputFiles('#upload', []);

5. フォーム送信

フォームを送信する方法は2つあります:

  • 送信ボタンをクリックする
  • フォーム送信イベントを直接トリガーする
await page.click('button[type="submit"]');
// 或者
await page.press('#form input[name="email"]', 'Enter');

ポップアップとダイアログ

Playwright はキャプチャして処理できます。ブラウザネイティブのポップアップ(alert, confirm, prompt)、およびカスタムモーダルです。

1. Alert 処理

page.once('dialog', async dialog => {
  console.log(dialog.message()); // 打印弹窗内容
  await dialog.accept(); // 点击 "确定"
});

await page.click('#show-alert');

2. Confirm 処理

page.once('dialog', async dialog => {
  console.log(dialog.message());
  await dialog.dismiss(); // 点击 "取消"
});

await page.click('#show-confirm');

3. Prompt 処理

page.once('dialog', async dialog => {
  console.log(dialog.message());
  await dialog.accept('Playwright'); // 输入内容并确认
});

await page.click('#show-prompt');

4. カスタムモーダル

カスタムモーダル(Bootstrap / Ant Design など)は実際には通常の DOM 要素であり、直接ロケータ + インタラクションの方法で閉じたり入力したりできます。

await page.click('#open-modal');
await page.fill('.modal input[name="name"]', 'Test User');
await page.click('.modal button.confirm');

実践例 —— 登録フォームの自動化テスト

以下の例では、以下を組み合わせて使用します。待機メカニズム、フォーム操作、ファイルアップロード、ダイアログ処理。

例

// register-test.js
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false, slowMo: 500 });
  const context = await browser.newContext();
  const page = await context.newPage();

  // 1. 登録ページを開く
  await page.goto('https://example.com/register', { waitUntil: 'domcontentloaded' });

  // 2. フォームが表示されるのを待つ
  await page.waitForSelector('#register-form', { state: 'visible' });

  // 3. 基本情報を入力
  await page.fill('#username', 'testuser');
  await page.fill('#email', '[email protected]');
  await page.fill('#password', 'Password123');

  // 4. ドロップダウンで国を選択
  await page.selectOption('#country', { label: 'China' });

  // 5. 規約にチェックを入れる
  await page.check('#agree');

  // 6. アバターをアップロード
  await page.setInputFiles('#avatar', 'avatar.png');

  // 7. 送信をクリック
  page.once('dialog', async dialog => {
    console.log('ポップアップ内容:', dialog.message());
    await dialog.accept(); // OKをクリック
  });
  await page.click('button[type="submit"]');

  // 8. 送信完了後の遷移を待つ
  await page.waitForLoadState('networkidle');

  // 9. 結果を検証(ウェルカム文字が含まれているか)
  const successText = await page.textContent('.welcome-message');
  console.log('登録結果:', successText);

  // 10. スクリーンショットを保存
  await page.screenshot({ path: 'register-success.png' });

  await browser.close();
})();

実行後の効果:

  • フォームの自動入力、国の選択、アバターのアップロード
  • ポップアップの自動処理
  • 送信後にスクリーンショットを撮り、ウェルカム情報を検証

API 一覧

以下は、ページナビゲーション、待機、フォーム、インタラクション、ポップアップのよく使われる API:

カテゴリ メソッド / プロパティ 説明
ページナビゲーション page.goto(url[, options]) ページを開く
page.reload([options]) ページを更新
page.goBack([options]) 戻る
page.goForward([options]) 進む
page.waitForLoadState([state, options]) 読み込み完了を待つ
待機メカニズム page.waitForSelector(selector[, options]) 要素の出現/消失を待つ
page.waitForResponse(fn[, options]) 指定したリクエストのレスポンスを待つ
page.waitForFunction(pageFn[, arg, options]) カスタム待機条件
要素ロケーター page.locator(selector) 汎用ロケーター
page.getByRole(role, options) ロールによるロケーター
page.getByText(text) テキストによるロケーター
page.getByPlaceholder(text) 入力ボックスのプレースホルダー
page.getByLabel(text) フォームのラベル
フォーム操作 page.fill(selector, value) 入力ボックス(クリアして入力)
page.type(selector, text[, options]) 一文字ずつの入力をシミュレート
page.press(selector, key) 要素上でキーを押す
page.selectOption(selector, values) ドロップダウンメニュー選択
page.check(selector[, options]) チェックボックス/ラジオボタンをチェック
page.uncheck(selector[, options]) チェックを外す
page.setInputFiles(selector, files) ファイルアップロード
基本インタラクション page.click(selector[, options]) 要素をクリック
page.dblclick(selector[, options]) ダブルクリック
page.hover(selector[, options]) ホバー
page.mouse.move(x, y) マウス移動
page.mouse.click(x, y[, options]) マウスクリック
page.dragAndDrop(src, dest[, options]) 要素をドラッグ
ポップアップ処理 page.on('dialog', handler) ダイアログイベントを監視
dialog.message() ポップアップのテキストを取得
dialog.accept([promptText]) 確認(内容を入力可能)
dialog.dismiss() キャンセル
スクリーンショットとアサーション page.screenshot({ path }) スクリーンショットを保存
page.textContent(selector) テキスト内容を取得
expect(locator).toHaveText(text) テキストのアサーション(必要:@playwright/test)
他の拡張機能)