# Поиск элементов с помощью XPath
# В работе с веб-страницами не всегда получается найти селектор, однозначно описывающий путь к нужному элементу. В такой ситуации для тестировщика лучшим решением проблемы будет пойти к фронтенд-разработчику проекта и договориться о специальном атрибуте, который будет использоваться в автотестах. Таким образом можно повысить тестируемость приложения. Увы, проекты бывают разные, и не всегда это возможно. И когда другого выхода больше нет, а автоматизировать как-то надо, можно обратиться к помощи языка запросов XPath.



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

# Прежде всего, XPath (XML Path Language) это язык запросов, который использует древовидную структуру документа. Проверять XPath-запросы можно точно так же как и CSS-селекторы - в консоли разработчика. Откройте консоль на странице с котиками http://suninjuly.github.io/cats.html, и давайте на её примере разберемся в основах синтаксиса. Попробуйте вбить каждый из запросов-примеров в строку поиска, чтобы увидеть, что именно находит поисковый запрос.

#  1. XPath запрос всегда начинается с символа / или //
# Символ / аналогичен символу > в CSS-селекторе, а символ // - пробелу. Их смысл:
# # 
# el1/el2 - выбирает элементы el2, являющиеся прямыми потомками el1;
# el1//el2 - выбирает элементы el2, являющиеся потомками el1 любой степени вложенности.
# Разница состоит в том, что в XPath, когда мы начинаем запрос с символа /,  мы должны указать элемент, являющийся корнем нашего документа. Корнем всегда будет элемент с тегом <html>. Пример: /html/body/header

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

# Важно! Такой поиск может быть неоднозначным. Например, запрос //div вернет вам все элементы с тегом <div>. Избегайте неоднозначных ситуаций, они плохо влияют на здоровье ваших автотестов.

# 2. Символ [ ] - это команда фильтрации
# Если по запросу найдено несколько элементов, то будет произведена фильтрация по правилу, указанному в скобках.

# Правил фильтрации очень много:

# по любому атрибуту, будь то id, class, title (или любой другой). Например, мы хотим найти картинку с летящим котом, для этого можно выполнить запрос //img[@id='bullet']
# по порядковому номеру. Допустим, мы хотим выбрать вторую по порядку карточку с котом. Для этого найдем элемент с классом "row" и возьмем его второго потомка: //div[@class="row"]/div[2]
# по полному совпадению текста. Да, XPath - это единственный способ найти элемент по внутреннему тексту. Если мы хотим найти блок текста с котом-Лениным, можно воспользоваться XPath селектором //p[text()="Lenin cat"]. Такой селектор вернет элемент, только если текст полностью совпадет. Здесь важно сказать, что не всегда поиск по тексту - это хорошая практика, особенно в случае мультиязычных сайтов.
# по частичному совпадению текста или атрибута. Для этого нужна функция contains. Запрос //p[contains(text(), "cat")] вернет нам все абзацы текста, которые содержат слово cat. Точно так же можно искать по частичному совпадению других атрибутов, это удобно, если у элемента несколько классов. Посмотрите на код навбара сайта с котами. Его можно найти селектором //div[contains(@class, "navbar")]
# в фильтрации еще можно использовать булевы операции (and, or, not) и некоторые простые арифметические выражения (но вообще не стоит, наверное). Допустим, мы хотим найти картинку обязательно с data-type "animal" и именем "bullet", для этого подойдет запрос: //img[@name='bullet-cat' and @data-type='animal']
#  3. Символ * - команда выбора всех элементов
# Например можем найти текст в заголовке запросом //div/*[@class="jumbotron-heading"]. Это может быть удобно, когда мы не знаем точно тег элемента, который ищем.
# Что важно знать про XPath, чтобы пользоваться им безболезненно:

# Не используйте селекторы вида //div[1]/div[2]/div[3] без крайней нужды: по такому селектору невозможно с первого раза понять, что за элемент вы ищете. А когда структура страницы хоть немного изменится, то ваш селектор с большой вероятностью перестанет работать;
# Если есть возможность использовать CSS-селекторы: сlass, id или name - лучше использовать их вместо поиска по XPath;
# Можно искать по полному или частичному совпадению текста или любого атрибута;
# Можно использовать булевы операции и простую арифметику;
# Можно удобно перемещаться по структуре документа (переходить к потомкам и к родителям);
# Подойдет, когда у сайта всё плохо с атрибутами и нет возможности достучаться до разработчиков;
# Есть мнение, что поиск по XPath в среднем медленнее, чем по css. Но достоверно это неизвестно;
# Не стоит использовать разные расширения для браузеров по поиску XPath: они подбирают нечитабельные и переусложненные селекторы. Лучше потратить немного времени и разобраться в синтаксисе самостоятельно, тем более, что он не очень сложный.
# В курсе мы не будем работать с XPath-селекторами, и в основном будем использовать CSS. В случае необходимости можно познакомиться с XPath подробнее по следующим ссылкам:

# https://www.w3schools.com/xml/xpath_syntax.asp

# https://msdn.microsoft.com/ru-ru/library/ms256086(v=vs.120).aspx

# https://msiter.ru/tutorials/xpath/syntax

# https://habr.com/post/114772/

# http://internetka.in.ua/xpath-start-part1/

# http://internetka.in.ua/xpath-start-part2/

# http://internetka.in.ua/xpath-start-part3/

# http://internetka.in.ua/xpath-start4/﻿

# https://testerslittlehelper.wordpress.com/2016/07/10/real-xpath/

# https://drive.google.com/file/d/0B_IyyodHL4rXcU1BY1R1TzFXbmc/view

