Написание кастомных команд

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

Основы создания кастомных команд

Чтобы создать кастомную команду, необходимо использовать метод browser.addCommand(). Этот метод позволяет добавлять новый функционал в объект browser или element. После добавления команды, она становится доступной для использования в тестах точно так же, как и стандартные команды WebdriverIO.

Пример базовой кастомной команды:

browser.addCommand('customCommand', function () {
  // Логика выполнения команды
});

После добавления команды, её можно использовать в тестах следующим образом:

browser.customCommand();

Структура кастомной команды

Кастомная команда может быть добавлена как в объект browser, так и в объект element. Разница заключается в том, что команды, добавленные в объект element, будут работать только с элементами DOM, в то время как команды в объекте browser будут доступны для работы с браузером в целом.

  1. Добавление команды в объект browser: Эта команда доступна для выполнения на уровне всего браузера. Она может взаимодействовать с браузерными настройками, окном или сессией.
browser.addCommand('setBrowserSize', function (width, height) {
  return browser.setWindowSize(width, height);
});
  1. Добавление команды в объект element: Такие команды могут взаимодействовать с конкретным элементом на странице.
$('[data-test="submit"]').addCommand('clickAndWait', function () {
  this.click();
  browser.waitUntil(() => this.isDisplayed(), 5000, 'Button is not visible');
});

Использование параметров в кастомных командах

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

Пример команды с параметрами:

browser.addCommand('setText', function (selector, text) {
  const element = $(selector);
  element.setValue(text);
});

Использование этой команды:

browser.setText('#input', 'Test input value');

Доступ к контексту команды

Каждая кастомная команда в WebdriverIO имеет доступ к контексту, на котором она была вызвана. В случае команды, добавленной в browser, контекстом будет объект браузера, а в случае команды, добавленной к элементу, контекстом будет объект самого элемента.

Чтобы работать с этим контекстом, можно использовать this в теле команды:

browser.addCommand('maximizeWindow', function () {
  this.setWindowSize(1920, 1080);
});

Или для команды элемента:

$('button').addCommand('scrollIntoViewIfNeeded', function () {
  this.scrollIntoView();
});

Добавление асинхронности

WebdriverIO использует асинхронный подход для работы с браузером, поэтому в кастомных командах может понадобиться использовать async/await для выполнения асинхронных операций. В случае асинхронной команды важно, чтобы сама команда была асинхронной, иначе она не сможет корректно работать с ожиданиями.

Пример асинхронной команды:

browser.addCommand('waitForPageLoad', async function (timeout = 5000) {
  await browser.waitUntil(async () => {
    return (await browser.execute(() => document.readyState)) === 'complete';
  }, { timeout });
});

Использование:

browser.waitForPageLoad();

Пример сложной кастомной команды

Иногда в кастомных командах требуется выполнять несколько действий одновременно. В таких случаях можно комбинировать логику и использовать различные методы WebdriverIO для работы с элементами.

Пример команды для входа в систему:

browser.addCommand('login', async function (username, password) {
  await $('#username').setValue(username);
  await $('#password').setValue(password);
  await $('#submit').click();
  await browser.waitUntil(async () => {
    return (await $('#welcome-message').isDisplayed());
  }, { timeout: 5000, timeoutMsg: 'Login failed' });
});

Использование:

browser.login('user', 'password');

Проверка и отладка кастомных команд

Кастомные команды, как и любые другие методы в WebdriverIO, могут быть отлажены с использованием console.log или browser.debug(). Эти методы позволяют отслеживать, как выполняются команды, и выявлять возможные ошибки.

Пример отладки:

browser.addCommand('logInAndCheck', async function (username, password) {
  console.log(`Logging in with ${username}`);
  await $('#username').setValue(username);
  await $('#password').setValue(password);
  await $('#submit').click();
  const successMessage = await $('#success-message').getText();
  console.log(successMessage);
});

Производительность и тестирование кастомных команд

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

Использование кастомных команд позволяет существенно сократить код тестов, сделать их более читаемыми и поддерживаемыми. Создание гибких и переиспользуемых команд — это лучший способ организовать тесты, улучшив их структуру и повысив удобство работы с тестовыми сценариями.