Выполнение JavaScript в Playwright

В этой главе рассказывается, как выполнять код JavaScript в Playwright, включая выполнение в контексте страницы, передачу параметров и внедрение начального скрипта.


Выполнение в контексте страницы с помощью page.evaluate()

page.evaluate()Выполняйте код в среде JavaScript страницы с доступом к DOM и глобальным переменным страницы.

Пример

test('Получить данные страницы', async ({ page }) => {
  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()Его второй параметр передаётся в функцию внутри страницы.

Пример

test('Передать параметры на страницу', async ({ page }) => {
  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-узел этого элемента.

Пример

test('Получить DOM-атрибуты элемента', async ({ page }) => {
  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()Выполняет один и тот же код для всех совпадающих элементов и возвращает массив.

Пример

test('Получить текст всех элементов списка', async ({ page }) => {
  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 до загрузки страницы, что можетдо выполнения скриптов страницыизменить окружение браузера.

Пример

test('Inject initial script', async ({ page }) => {
  // Изменить свойство 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.

Пример

// Подход с ElementHandle (старый стиль, не рекомендуется)
const handle = await page.$('.my-element');
await handle.click();

// Подход с Locator (новый стиль, рекомендуется)
await page.locator('.my-element').click();

ElementHandle используется только тогда, когда нужно получитьboundingBox()или при выполнении сложных операций с DOM.

Другие расширения