Выполнение JavaScript кода на странице

WebdriverIO предоставляет мощные возможности для взаимодействия с веб-страницами, включая выполнение произвольного JavaScript кода внутри контекста браузера. Это особенно важно для задач, которые невозможно выполнить через стандартные методы API, например, получение сложных значений из DOM, манипуляции с элементами или вызов внутренних функций приложения.


Метод browser.execute()

Метод execute позволяет выполнить JavaScript код на странице и вернуть результат в тестовый скрипт. Синтаксис:

const result = await browser.execute((arg1, arg2) => {
    // код, который будет выполнен в браузере
    return document.title + ' - ' + arg1 + ' - ' + arg2;
}, 'значение1', 'значение2');
console.log(result); // выводит результат выполнения кода

Особенности использования:

  • Аргументы после функции автоматически передаются внутрь функции в браузере.
  • Возвращаемое значение передается обратно в Node.js.
  • Внутри функции нельзя использовать переменные из внешнего контекста Node.js напрямую.

Асинхронный JavaScript через browser.executeAsync()

Для работы с асинхронным кодом используется executeAsync. Она ожидает вызов специального callback для завершения выполнения:

const result = await browser.executeAsync((done) => {
    setTimeout(() => {
        done('Асинхронный результат');
    }, 1000);
});
console.log(result); // 'Асинхронный результат'

Особенности:

  • Функция должна вызвать переданный параметр done при завершении.
  • Позволяет работать с асинхронными API внутри браузера, такими как fetch.

Примеры практического использования

1. Получение текста всех элементов списка

const items = await browser.execute(() => {
    return Array.from(document.querySelectorAll('ul li')).map(el => el.textContent);
});
console.log(items);

2. Скроллинг страницы до нужного элемента

await browser.execute((selector) => {
    const element = document.querySelector(selector);
    if (element) {
        element.scrollIntoView({ beh * avior: 'smooth', block: 'center' });
    }
}, '#target-element');

3. Вызов функций приложения, определённых в глобальном контексте

const userData = await browser.execute(() => {
    return window.getUserData(); // функция определена в скриптах страницы
});
console.log(userData);

4. Модификация DOM элементов

await browser.execute(() => {
    document.body.style.backgroundColor = 'lightblue';
});

Работа с аргументами и возвращаемыми значениями

Методы execute и executeAsync автоматически сериализуют данные между Node.js и браузером. Поддерживаются следующие типы:

  • Примитивы: string, number, boolean, null, undefined
  • Объекты и массивы (без циклических ссылок)
  • WebElement объекты, полученные через селекторы WebdriverIO

Возвращаемые значения автоматически десериализуются и могут быть использованы как обычные JavaScript объекты в тесте.


Ограничения и рекомендации

  • Код выполняется в контексте страницы, поэтому доступ к Node.js модулям недоступен.
  • Избегать выполнения сложной логики с долгими таймерами внутри execute, так как это может увеличить время выполнения тестов.
  • Для часто используемых фрагментов лучше создавать функции на стороне страницы или отдельные утилиты в тестовом проекте.

Интеграция с WebdriverIO селекторами

WebdriverIO позволяет комбинировать execute с элементами:

const text = await browser.execute((el) => el.textContent, await $('#my-element'));
console.log(text);

Здесь WebdriverIO автоматически передаст объект элемента в контекст браузера. Это упрощает манипуляции с конкретными элементами, не полагаясь на глобальные селекторы.


Отладка JavaScript в тестах

Для удобства отладки можно выводить результаты прямо в консоль браузера:

await browser.execute(() => {
    console.log('Тестовое сообщение', document.title);
});

Кроме того, можно использовать debugger; внутри функции, чтобы остановить выполнение кода при подключении к DevTools.


Использование методов execute и executeAsync делает WebdriverIO универсальным инструментом для автоматизации сложных сценариев тестирования, предоставляя полный контроль над DOM и внутренними функциями веб-приложения.