Выполнение JavaScript в Playwright
В этой главе рассказывается, как выполнять код JavaScript в Playwright, включая выполнение в контексте страницы, передачу параметров и внедрение начального скрипта.
Выполнение в контексте страницы с помощью page.evaluate()
page.evaluate()Выполняйте код в среде JavaScript страницы с доступом к DOM и глобальным переменным страницы.
Пример
await page.goto('https://www.example.com/');
// Получить заголовок страницы (выполняется в контексте страницы)
const title = await page.evaluate(() => {
return document.title;
});
console.log('Заголовок страницы:', title);
// Получить количество всех ссылок на странице
const linkCount = await page.evaluate(() => {
return document.querySelectorAll('a').length;
});
console.log('Количество ссылок:', linkCount);
// Получить позицию прокрутки страницы
const scrollY = await page.evaluate(() => {
return window.scrollY;
});
});
Передача параметров в evaluate
page.evaluate()Его второй параметр передаётся в функцию внутри страницы.
Пример
await page.goto('https://www.example.com/');
// Передать один параметр
const result1 = await page.evaluate((name) => {
return `Привет, ${name}!`;
}, 'ПРИМЕР');
// Передать параметр-объект
const userInfo = { name: 'example', role: 'admin' };
const result2 = await page.evaluate((user) => {
return `${user.name}Его роль: ${user.role}`;
}, userInfo);
// Передать несколько параметров (с использованием деструктуризации)
const result3 = await page.evaluate(
({ x, y }) => {
return x + y;
},
{ x: 10, y: 20 }
);
console.log('10 + 20 =', result3); // 30
});
Передаваемые параметры сериализуются в JSON и отправляются в контекст страницы, поэтому объекты, которые невозможно сериализовать, такие как функции и DOM-элементы, не могут быть переданы.
Возвращаемое значение также сериализуется.
locator.evaluate() Выполнение в контексте элемента
locator.evaluate()Выполняет код в контексте сопоставленного элемента; параметр включает ссылку на DOM-узел этого элемента.
Пример
await page.goto('https://www.example.com/');
// Получить textContent конкретного элемента
const text = await page
.getByRole('heading', { name: 'EXAMPLE' })
.evaluate(node => node.textContent);
// Получить атрибут style элемента
const color = await page
.getByRole('button', { name: 'Search' })
.evaluate(node => getComputedStyle(node).backgroundColor);
});
locator.evaluateAll() Перебор всех совпадающих элементов
evaluateAll()Выполняет один и тот же код для всех совпадающих элементов и возвращает массив.
Пример
await page.goto('https://www.example.com/');
// Получить текст всех пунктов меню
const menuItems = await page
.getByRole('navigation')
.locator('a')
.evaluateAll(links => links.map(link => link.textContent));
console.log('Menu items:', menuItems);
// ['Home', 'Tutorial', 'Tools', ...]
});
page.addInitScript() Внедрение начальных скриптов
addInitScript()Внедрите код JavaScript до загрузки страницы, что можетдо выполнения скриптов страницыизменить окружение браузера.
Пример
// Изменить свойство navigator до загрузки страницы
await page.addInitScript(() => {
// Переопределить обнаружение WebDriver
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
// Мокировать глобальные переменные в window
window.EXAMPLE_CONFIG = {
env: 'test',
version: '1.0.0',
};
});
await page.goto('https://www.example.com/');
// Проверить, что внедрённые переменные вступили в силу
const config = await page.evaluate(() => window.EXAMPLE_CONFIG);
console.log(config); // { env: 'test', version: '1.0.0' }
});
addInitScript()Типичные случаи использования:
| Сценарий использования | Описание |
|---|---|
| Мокировать API браузера | Переопределениеnavigator.webdriver、navigator.languageожидание |
| Внедрить пользовательскую конфигурацию | Установить переменные окружения тестирования, мокировать источники данных и т. д. |
| Отключить функции | Отключить Service Worker, отключить логирование и т. д. |
| Полифилл | Добавить функциональность, от которой зависит страница, но которой не хватает в тестовой среде. |
Использование и ограничения ElementHandle
ElementHandle — это прямая ссылка на DOM-элемент, и он широко использовался в ранних версиях Playwright.
В большинстве сценариев теперь следует использоватьLocatorвместо ElementHandle.
Пример
const handle = await page.$('.my-element');
await handle.click();
// Подход с Locator (новый стиль, рекомендуется)
await page.locator('.my-element').click();
ElementHandle используется только тогда, когда нужно получитьboundingBox()или при выполнении сложных операций с DOM.