Расширенные операции со страницами в Playwright
В этой главе мы рассмотрим продвинутые операции со страницами в Playwright, которые будут ближе к реальным потребностям тестирования, охватываямеханизмы ожидания, работу с формами, всплывающие диалогии другие продвинутые возможности.
Механизм ожидания
Одно из главных преимуществ Playwright — этоумное ожидание (автоожидание): большинство операций (например,click, fill) автоматически будет ожидать, пока элемент не станет видимым и доступным для взаимодействия. Однако в сложных сценариях вам всё равно потребуется вручную управлять ожиданием.
1. Неявное ожидание (автоожидание)
Встроенный механизм ожидания 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. Отправка формы
Существует два способа отправки формы:
- Нажмите кнопку отправки
- Напрямую вызвать событие отправки формы
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: 'Китай' });
// 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() |
Cancel | |
| Скриншот и утверждение | page.screenshot({ path }) |
Сделать скриншот и сохранить |
page.textContent(selector) |
Получить текстовое содержимое | |
expect(locator).toHaveText(text) |
Проверить текст (требуется использование@playwright/test) |