XPath селекторы

XPath (XML Path Language) — мощный язык запросов, позволяющий находить элементы в DOM-структуре веб-страницы. В WebdriverIO XPath используется для точного указания местоположения элементов, особенно когда стандартные CSS-селекторы оказываются недостаточно гибкими.

Основы синтаксиса XPath

XPath предоставляет два основных типа путей: абсолютные и относительные.

  • Абсолютный путь начинается с корня документа (/) и описывает точное расположение элемента:
const element = await $('//html/body/div[2]/div[1]/button');

Такой путь надежен только при стабильной структуре страницы, иначе изменения DOM сломают селектор.

  • Относительный путь начинается с двойного слеша (//) и ищет элемент в любом месте DOM:
const element = await $('//button[@id="submit"]');

Относительные XPath предпочтительнее, так как они устойчивее к изменениям верстки.

Основные конструкции XPath

  1. Поиск по тегу
const element = await $('//input');

Находит все элементы <input> на странице.

  1. Поиск по атрибуту
const element = await $('//input[@name="username"]');

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

const element = await $('//input[@type="text" and @name="username"]');
  1. Поиск по тексту элемента
const element = await $('//button[text()="Войти"]');

Для частичного совпадения используется contains():

const element = await $('//button[contains(text(),"Войти")]');
  1. Поиск по порядку (индексы) Если на странице несколько элементов, можно выбрать конкретный:
const element = await $('(//input[@type="text"])[2]');

Обратите внимание, что индексация начинается с 1.

  1. Навигация по DOM XPath позволяет перемещаться вверх, вниз и по соседним элементам:
const parent = await $('//input[@id="username"]/..'); // родительский элемент
const nextSibling = await $('//label[@for="username"]/following-sibling::input');
const prevSibling = await $('//input[@id="password"]/preceding-sibling::label');

Функции XPath

  • contains(@attribute, 'value') — проверка наличия подстроки в атрибуте.
const element = await $('//a[contains(@href,"login")]');
  • starts-with(@attribute, 'value') — проверка начала строки в атрибуте.
const element = await $('//input[starts-with(@id,"user")]');
  • text() — поиск по текстовому содержимому.
const element = await $('//span[text()="Ошибка"]');
  • normalize-space(text()) — удаление лишних пробелов при поиске текста.
const element = await $('//span[normalize-space(text())="Ошибка"]');

Комбинированные XPath

XPath позволяет комбинировать условия для более точного поиска:

const element = await $('//div[@class="form-group" and .//input[@name="email"]]');

Здесь выбирается <div> с классом form-group, внутри которого есть <input> с именем email.

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

WebdriverIO поддерживает XPath через метод $ для одного элемента и $$ для нескольких:

const submitButton = await $('//button[@type="submit"]');
await submitButton.click();

const inputs = await $$('//input[@type="text"]');
for (const input of inputs) {
    await input.setValue('Тестовое значение');
}

Динамические элементы и XPath

Для элементов с изменяющимися атрибутами полезно использовать частичные совпадения и функции:

const dynamicButton = await $('//button[contains(@id,"btn_")]');

Можно комбинировать по тексту и атрибуту для большей надежности:

const element = await $('//button[contains(@id,"btn_") and text()="Отправить"]');

XPath и производительность

Использование XPath может быть медленнее, чем CSS-селекторы, особенно для больших страниц с глубокой вложенностью. Рекомендуется:

  • Использовать относительные XPath вместо абсолютных.
  • Минимизировать использование // без необходимости.
  • Комбинировать атрибуты и текст для точного поиска.

Практические примеры

  1. Клик по кнопке с конкретным текстом:
await $('//button[text()="Подтвердить"]').click();
  1. Заполнение всех текстовых полей формы:
const inputs = await $$('//form//input[@type="text"]');
for (let i = 0; i < inputs.length; i++) {
    await inputs[i].setValue(`Значение ${i+1}`);
}
  1. Проверка наличия элемента с частичным совпадением атрибута:
const alert = await $('//div[contains(@class,"alert-success")]');
const isDisplayed = await alert.isDisplayed();

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