Playwright Advanced Page Operations
In this chapter, we will introduce Playwright advanced page operations, which will be closer to real testing needs, coveringwait mechanisms, form handling, popup dialogsand other advanced features.
Wait Mechanism
One of Playwright's biggest advantages issmart waiting (auto-waiting): most operations (such asclick, fill) will automatically wait for the element to be visible and operable. However, in complex scenarios, you still need to manually control waiting.
1. Implicit Wait (Auto-waiting)
Playwright's built-in waiting mechanism:
- Element is visible
- Clickable / Interactive
- Page load complete
Example
2. Explicit Wait
Explicitly call wait methods, for example, wait for a selector, text, or request.
Example
Commonstatevalues:
'attached'→ element appears in the DOM'visible'→ element is visible on the page'hidden'→ element is hidden'detached'→ element is removed
3. Wait for Element to Appear / Disappear
// 等待元素出现
await page.waitForSelector('#loading', { state: 'visible' });
// 等待元素消失
await page.waitForSelector('#loading', { state: 'hidden' });
4. Wait for Network Request to Complete
Wait for a specific request to complete, commonly used for AJAX requests or API calls.
// 等待指定 URL 的请求完成
await page.waitForResponse(response =>
response.url().includes('/api/login') && response.status() === 200
);
5. Custom Wait Conditions
Throughpage.waitForFunctionExecute custom waiting logic.
// 等待页面上计数器达到 10
await page.waitForFunction(() => {
return document.querySelector('#count').innerText === '10';
});
Form Handling
Forms are the most common interaction scenario in testing. Playwright provides a rich API to operate form controls.
1. Input Box Operations
await page.fill('#username', 'admin'); // 清空并输入
await page.type('#search', 'Playwright', { delay: 100 }); // 模拟逐字输入
2. Dropdown Menu Selection
// 通过 value
await page.selectOption('#country', 'china');
// 通过标签文本
await page.selectOption('#country', { label: 'United States' });
// 通过 index
await page.selectOption('#country', { index: 2 });
3. Checkboxes and Radio Buttons
// 勾选复选框
await page.check('#agree');
// 取消勾选
await page.uncheck('#subscribe');
// 点击单选框
await page.check('input[type="radio"][value="male"]');
4. File Upload
// 直接上传文件
await page.setInputFiles('#upload', 'example.png');
// 上传多个文件
await page.setInputFiles('#upload', ['a.png', 'b.png']);
// 清空文件
await page.setInputFiles('#upload', []);
5. Form Submission
There are two ways to submit a form:
- Click the submit button
- Directly trigger the form submission event
await page.click('button[type="submit"]');
// 或者
await page.press('#form input[name="email"]', 'Enter');
Popups and Dialogs
Playwright can capture and handlebrowser-native popups(alert, confirm, prompt), as well as custom modals.
1. Alert Handling
page.once('dialog', async dialog => {
console.log(dialog.message()); // 打印弹窗内容
await dialog.accept(); // 点击 "确定"
});
await page.click('#show-alert');
2. Confirm Handling
page.once('dialog', async dialog => {
console.log(dialog.message());
await dialog.dismiss(); // 点击 "取消"
});
await page.click('#show-confirm');
3. Prompt Handling
page.once('dialog', async dialog => {
console.log(dialog.message());
await dialog.accept('Playwright'); // 输入内容并确认
});
await page.click('#show-prompt');
4. Custom Modal
Custom modals (such as Bootstrap / Ant Design) are actually ordinary DOM elements, and you can directly uselocating + interactionto close or input.
await page.click('#open-modal');
await page.fill('.modal input[name="name"]', 'Test User');
await page.click('.modal button.confirm');
Practical Case — Registration Form Automation Testing
The following example will comprehensively usewait mechanisms, form operations, file upload, dialog handling。
Example
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. Open the registration page
await page.goto('https://example.com/register', { waitUntil: 'domcontentloaded' });
// 2. Wait for the form to appear
await page.waitForSelector('#register-form', { state: 'visible' });
// 3. Enter basic information
await page.fill('#username', 'testuser');
await page.fill('#email', 'test@example.com');
await page.fill('#password', 'Password123');
// 4. Select country from dropdown
await page.selectOption('#country', { label: 'China' });
// 5. Check the terms
await page.check('#agree');
// 6. Upload avatar
await page.setInputFiles('#avatar', 'avatar.png');
// 7. Click submit
page.once('dialog', async dialog => {
console.log('Popup content:', dialog.message());
await dialog.accept(); // Click OK
});
await page.click('button[type="submit"]');
// 8. Wait for the redirect after submission
await page.waitForLoadState('networkidle');
// 9. Assert the result (whether it contains welcome text)
const successText = await page.textContent('.welcome-message');
console.log('Registration result:', successText);
// 10. Take a screenshot and save
await page.screenshot({ path: 'register-success.png' });
await browser.close();
})();
Effect after running:
- Automatically fill in the form, select the country, upload the avatar
- Automatically handle popups
- After submission, take a screenshot and verify the welcome message
Complete API
The following is a compilation ofpage navigation, waiting, forms, interaction, popupscommon APIs:
| Category | Method / Property | Description |
|---|---|---|
| Page Navigation | page.goto(url[, options]) |
Open page |
page.reload([options]) |
Refresh page | |
page.goBack([options]) |
Go back | |
page.goForward([options]) |
Go forward | |
page.waitForLoadState([state, options]) |
Wait for loading to complete | |
| Wait Mechanism | page.waitForSelector(selector[, options]) |
Wait for element to appear/disappear |
page.waitForResponse(fn[, options]) |
Wait for specified request response | |
page.waitForFunction(pageFn[, arg, options]) |
Custom wait conditions | |
| Element Locating | page.locator(selector) |
Generic locator |
page.getByRole(role, options) |
Locate by role | |
page.getByText(text) |
Locate by text | |
page.getByPlaceholder(text) |
Input placeholder | |
page.getByLabel(text) |
Form label | |
| Form Operations | page.fill(selector, value) |
Input box (clear and fill) |
page.type(selector, text[, options]) |
Simulate typing character by character | |
page.press(selector, key) |
Press key on element | |
page.selectOption(selector, values) |
Dropdown menu selection | |
page.check(selector[, options]) |
Check checkbox/radio | |
page.uncheck(selector[, options]) |
Uncheck | |
page.setInputFiles(selector, files) |
File upload | |
| Basic Interaction | page.click(selector[, options]) |
Click element |
page.dblclick(selector[, options]) |
Double-click | |
page.hover(selector[, options]) |
Hover | |
page.mouse.move(x, y) |
Mouse move | |
page.mouse.click(x, y[, options]) |
Mouse click | |
page.dragAndDrop(src, dest[, options]) |
Drag element | |
| Popup Handling | page.on('dialog', handler) |
Listen for dialog events |
dialog.message() |
Get popup text | |
dialog.accept([promptText]) |
Confirm (can input content) | |
dialog.dismiss() |
Cancel | |
| Screenshot and Assertion | page.screenshot({ path }) |
Take screenshot and save |
page.textContent(selector) |
Get text content | |
expect(locator).toHaveText(text) |
Assert text (requires using@playwright/test) |