7 февраля 2020

Краткий ликбез по локаторам в вебе

«Любишь UI-автотесты писать, люби и локаторы подбирать.» (с) Конфуций

Noveo Testing

Конфуций, конечно, был мудрым человеком и еще поговаривал, что знание локаторов пригождается не только тем, кто работает с автоматизацией клиентской части.

Зачем это мне?

🔹 Если вы можете быстро найти локатор элемента, то репортить баги UI-части становится в разы проще. Вместо того, чтобы искать «красную кнопку ОК на странице авторизации пользователя в личный кабинет», разработчик вбивает в поиск «.btn.submit» и моментально находит элемент, для которого нужно сделать исправления.

🔹 Если вы знаете, как работают CSS-селекторы, то можете проверять работу визуальной части не только как пользователь, но и как… скажем, продвинутый пользователь. Например, обнаружить, что выполненный пункт в ToDo-листе не перечеркивается, потому что не подтянулся стиль, который отвечает за то, чтобы текст элемента, находящегося в определенном состоянии, был зачеркнут.

🔹 Вообще механика работы веба — того, что мы, собственно, тестируем — становится намного понятнее, а работать с тем, что понимаешь, в разы приятнее. Кроме того, появляются новые идеи для проверок: а что будет, если мы уберем вот этот атрибут и попробуем ввести в поле невалидное значение? А если у кнопки стереть ‘disabled‘ и кликнуть на нее, что-то произойдет?

🔹 Можно открывать новые для себя направления деятельности: например, одна моя коллега не пишет UI-тесты, но редактирует код страниц и добавляет элементам data-test-* атрибуты. Это требует аналитического мышления, системного подхода и внимательности, а ещё позволяет поработать с кодом, но без написания автотестов (если вдруг вам их писать не очень хочется).

Короче, локаторы нужны и важны, а DevTools (F12 в большинстве браузеров) — наш лучший друг.

Что такое локаторы?

По сути — запросы с тем или иным синтаксисом, которые позволяют нам обращаться к элементам страницы по их уникальным (или не очень) характеристикам.

То есть если обычно вы видите кнопку «Login» и знаете, что надо нажать именно на нее, то в случае с автоматизацией браузеру надо дать команду «нажать», а еще обозначить, что именно жать. Собственно, чтобы взаимодействие браузера происходило с нужным вам элементом, а не соседним или вообще скрытым, и нужно умение писать уникальные локаторы. Еще хорошо, чтобы локаторы были читабельными — тогда вашим коллегам будет проще понимать, к чему именно вы обращаетесь (и что пошло не так в случае проблемы), но это уже, увы, не всегда зависит от QA.

Какие виды локаторов существуют?

Selenium WebDriver ищет элементы с помощью двух методов:

  • Find Element
  • Find Elements

Оба получают на вход параметры: объект класса By + тип запроса (по чему будем искать элемент) и сам локатор. Локатор должен соответствовать типу запроса: если ищем по атрибуту, то в локатор кидаем значение атрибута, если по СSS-селектору — то селектор. Если запрос будет вида

find_element(By.XPATH, "#login_form")

, то, разумеется, вместо рабочего теста мы получим ошибку.

Пара других различий, которые важно знать о методах Find Element и Find Elements:

Noveo testing locators
Различия методов Find Element и Find Elements

Объект класса By может принимать на вход следующие виды локаторов:

  • ID
  • Name
  • XPath
  • Link text
  • Partial link text
  • Tag name
  • Class name
  • CSS selector

При этом ID, Name, Tag name и Class name — частные случаи CSS-селекторов. Таким образом, основные виды локаторов, с которыми мы будем сталкиваться — это CSS-селекторы и XPath. О них и поговорим ниже.

CSS Selector

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

Синтаксис:

  • id (#uniqueid)
  • tag (H1)
  • name ([name=»my-element»])
  • class (.class1.class2)
  • другое значение атрибута ([attribute=»value»])
  • текст в элементе: псевдокласс из jquery :contains()
  • положение потомка: :nth-child(1)

Примеры использования:

  • #test — поиск по ID «test»
  • tag — поиск по тэгу «tag»
  • .my-class — поиск по классу «my-class»
  • .class1.class2 — поиск по классам «class1 class2» или «class2 class1» (обратите внимание, что порядок классов элемента не имеет значения при написании селектора)
  • [name="my-name"] — поиск по имени «my-name»
  • [attribute="value"] — поиск по значению «value» атрибута «attribute»
  • a:contains("test") — поиск по тексту «test», который содержится в элементе
  • #posts > .item:nth-child(2) > .title — составной селектор. Ищет элемент с классом title, который является потомком второго потомка элемента с классом item, который, в свою очередь, потомок элемента с ID = posts.

XPath

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

Синтаксис:

  • / — поиск прямого потомка
  • // — поиск потомка любой степени
  • [ ] — фильтрация
  • Функция text() — поиск по тексту элемента
  • Функция contains() — поиск полного или частичного совпадения
  • Булевы операции and, or, not
  • * — выбор всех элементов

Важный момент: XPath регистрозависим. То есть если запрос вида  //*[@class=”my-class”] находит элемент, то запрос вида //*[@Сlass=”my-Сlass”] тот же элемент не обнаружит.

Возможный вид запроса:

//корень(конкретный или *)/потомок[параметры фильтрации]

Примеры использования:

  • //*[@class=”my-class”] — поиск по всем элементам, у которых есть класс «my-class».
  • //div/p/a[text()=”Пример текста”] — поиск по всем элементам a, содержащим текст «Пример текста» и являющимся прямыми потомками элемента p, который прямой потомок элемента div.
  • //*[@data-test=”select-button” or contains(@class, “login-button”)] — поиск по всем элементам, у которых есть data-test-атрибут со значением «select-button» ИЛИ у которых в имени класса есть «login-button».
  • //div[1] — выбор первого потомка элемента div.

DevTools — наш друг

Чтобы искать элементы быстрее и убедиться, что написанный запрос вернет нам нужное количество элементов страницы, можно (и нужно) использовать DevTools. Они открываются по нажатию F12 или комбинации Ctrl+Shift+I. Во вкладке Elements можно посмотреть код страницы и скопировать уникальный локатор того или иного элемента. Еще пару лет назад таким образом возвращались трудночитаемые монстры, но браузеры умнеют (как и мы), и теперь часто Chrome возвращает отличные лаконичные локаторы.

Noveo Testing DevTools
Селекторы и локаторы можно искать и проверять через DevTools

Как же овладеть искусством поиска красивых локаторов? Практика, практика, практика!

Почитать (и потренироваться) дополнительно можно вот тут:

1. На официальном сайте Selenium.

2. В документации к Selenium для вашего языка программирования. Вот так выглядит вариант для Python: https://selenium-python.readthedocs.io/locating-elements.html

3. В других местах:

4. С готовыми подсказками по CSS-селекторам, XPath и многому другому интересному ;)

Если вы хотите лишний раз попрактиковаться в написании CSS-селекторов — часто используемых локаторов, — рекомендуем вам заглянуть на https://www.w3schools.com/css/exercise.asp и https://flukeout.github.io/.

Тем, кому совсем интересно и хочется больше практики из реальной жизни, поможет вот такое нетрудное упражнение:

  • Выбрать туториал с любой формой из раздела Forms W3Schools (например, первый — Login Form).
  • На странице туториала кликнуть кнопку Try it yourself.
  • Скопировать код из левой части редактора и сохранить на вашем компьютере в формате HTML.
  • Открыть сохраненную HTML-страницу и поискать для каждого элемента разного рода атрибуты и тэги.

А ещё очень рекомендуем обратить внимание на шаги 1.4 — 1.6 курса Автоматизация тестирования с помощью Selenium и Python и на модули 5 и 6 курса Веб-разработка для начинающих: HTML и CSS.

Когда вы чувствуете, что готовы попробовать поиск и написание локаторов на реальном веб-сайте, вы можете использовать песочницы из вот этого поста или что-то из списка ниже:

Надеюсь, этот ликбез оказался вам полезен! Всем интересных задач и красивых локаторов :)

Noveo Testing

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Читайте в нашем блоге

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: