Найти в Дзене

HTML для тестировщика. Углублённый Xpath. Часть 2.

Уже изучили как можно подобраться к нужному элементу. Сегодня немного углубимся в синтаксис поиска элементов. Его редко используют из за постоянной смены страницы и добавлении новых элементов. В основном будем использовать его, но немного усовершенствуем и добавим параметры К примеру нам нужна кнопка button. Чтобы взять её с любым параметром, нужно прописать: Да такой синтаксис может быть не уникальным и у какого нибудь элемента может быть такой же набор параметров. Для этого мы можем добавлять несколько параметров, чтобы определить нужный. Сейчас мы прописали параметры у одного элемента, можно прописывать у всех, которые есть в вашем пути Думаю что логика понятна, тут самое главное научиться определять уникальный параметр и не писать трёхэтажные запросы. Думаю тут и так понятно, мы просто указываем параметры, но не указываем их значения. Иногда нам известны только параметры, и нужны все элементы, для этого можно не указывать конкретный элемент, а заменить его * У многих элементов ест
Оглавление

Уже изучили как можно подобраться к нужному элементу. Сегодня немного углубимся в синтаксис поиска элементов.

Поиск элементов по разным параметрам

Полный путь

  • html/body/div/article[1]

Его редко используют из за постоянной смены страницы и добавлении новых элементов.

Относительный путь

  • //article[1]

В основном будем использовать его, но немного усовершенствуем и добавим параметры

Использование параметров у любого элемента страницы

-2

К примеру нам нужна кнопка button. Чтобы взять её с любым параметром, нужно прописать:

  • //button[@type='button']

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

  • //button[@type='button'][@class='_mainMenuItem__action_zlwrnv_17']

Сейчас мы прописали параметры у одного элемента, можно прописывать у всех, которые есть в вашем пути

  • //nav[@data-test='main-menu']//button[@type='button'][@class='_mainMenuItem__action_zlwrnv_17']

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

Элемент без значений параметров

  • //nav[@data-test]//button[@type][@class]

Думаю тут и так понятно, мы просто указываем параметры, но не указываем их значения.

Любой элемент с нужными параметрами

Иногда нам известны только параметры, и нужны все элементы, для этого можно не указывать конкретный элемент, а заменить его *

  • //*[@data-test='main-menu']

Поиск по тексту

-3

У многих элементов есть текст, по которому легко написать поиск.

  • //button[text()='Developer Tools']

С прошлой статьи мы уже можем проверять все наши локаторы. Как видим данный локатор не уникален и нужно будет дописывать к нему параметры.

-4

Поиск по тексту внутри элемента

Описанный выше способ работает только в том элементе, где расположен текст. Ниже вариант, который перебирает все дочерние элементы (которые расположены внутри элемента) и ищет в них написанный текст.

-5

У nav нет текста, но у дочернего button есть

  • //nav[contains(.,'Developer Tools')]

Последний элемент

К примеру нам нужен последний div

-6
  • //nav/div[last()]

Первый элемент

  • //nav/div[1]

Лайфхак если не можешь написать уникальный локатор

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

-7
  • //nav/div[last()]

К примеру этот локатор выдаёт 2 значения, представим, что мы не можем его никак найти по другому. Для этого просто прописываем следующее

-8
  • (//nav/div[last()])[1]

То есть мы говорим из данного запроса выбери 1 запись (или какую вам нужно).

А можно ли идти по dom дереву в обратную сторону?

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

Предок

Элемент, который находится на 1 уровень выше.

-9
  • //nav[contains(.,'Developer Tools')]/parent::div

Тут важно отметить, что только на 1 уровень, напишете на 2 уровне вам ничего не найдётся.

Дочерний элемент

Редко используется, так как обычный поиск тоже работает через дочерние элементы

  • //nav[contains(.,'Developer Tools')]/child::div

Все предки элемента

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

  • //nav[contains(.,'Developer Tools')]/ancestor::div

Все потомки элемента

Вот тут мы уже можем выбрать все элементы, расположенные ниже в определённом элементе и также поиск по "верхушкам"

  • //nav[contains(.,'Developer Tools')]/descendant::div

Абсолютно все элементы расположенные ниже нужного

Здесь поиск будет заходить во все главные и дочерние элементы.

  • //nav[contains(.,'Developer Tools')]/following::div

Соседний элемент расположенный ниже

-10
  • //nav[contains(.,'Developer Tools')]/following-sibling::div

Абсолютно все элементы расположенные выше нужного

  • //nav[contains(.,'Developer Tools')]/preceding::div

Все соседи до текущего элемента

//nav[contains(.,'Developer Tools')]/preceding-sibling::div

Мы разобрали с вами основные особенности поиска элементов, думаю сейчас найти какой либо элемент не составит труда.

Если у вас есть вопросы или вы просто хотите стать частью команды тестировщиков, то переходи в ТГ канал, где можем пообщаться с единомышленниками и найти много интересных и полезных знаний! Также если вам нужна индивидуальная консультация, менторство и помощь в создании проекта пишите в ТГ канал!

Обучение тестированию