Playwright 高度なページ操作
この章では、Playwright の高度なページ操作を紹介します。この部分は実際のテストニーズにより近く、以下を含みます。待機メカニズム、フォーム処理、ポップアップダイアログなどの高度な機能です。
待機メカニズム
Playwright の最大の利点の1つはスマート待機(auto-waiting):ほとんどの操作(例えばclick, fill)は要素が表示され操作可能になるまで自動的に待機します。ただし、複雑なシナリオでは、手動で待機を制御する必要があります。
1. 暗黙の待機(Auto-waiting)
Playwright が内蔵する待機メカニズム:
- 要素が表示されていること
- クリック可能 / 操作可能であること
- ページの読み込みが完了していること
例
2. 明示的な待機
待機メソッドを明示的に呼び出します。例えば、特定のセレクタ、テキスト、リクエストを待機します。
例
一般的な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');
実践例 —— 登録フォームの自動化テスト
以下の例では、以下を組み合わせて使用します。待機メカニズム、フォーム操作、ファイルアップロード、ダイアログ処理。
例
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) |