Comments 12
Извините, а //*[string-length(element)]? Хотя о красоте это не совсем). Иногда при парсинге элементы динамические помогает и так если на стороне сервера сильно против).
Чтобы поменьше использовать xpath мы пришли к соглашению с разработчиками по использованию особой спецификации для атрибутов элементов в DOM https://ouia.readthedocs.io Идея в том, чтобы иметь предсказуемый селектор для любых компонентов в UI. Например, есть кнопка, которая в html выглядит так:
<button class="someClass">Some Text</button>
В соответствии с нашей спецификацией кнопка должна иметь следующий вид:
<button data-ouia-component-type="Button" data-ouia-component-id="someId" class="someClass">Some Text</button>
В итоге можно прийти к универсальному селектору:
.//*[@data-ouia-component-type=<имя компонента> and @data-ouia-component-id=<id компонентa>]
Конечно, полностью уйти от произвольных селекторов не получится, но следуя соглашению, можно значительно упростить сопровождение тестов и повысить их стабильность.
У меня тоже был подобный опыт, я был в команде тестирования. Но в итоге пришлось от подобного отказаться: часто при рефакторинге или переверстке страницы разработчики могли полностью удалить блоки кода и написать заново, как итог атрибуты пропадали и тесты сыпались.
Подход работает, но для этого нужны формальные договоренности писать дополнительные атрибуты и делать это всегда.
как итог атрибуты пропадали и тесты сыпались
Так это ж значит что тест отработал себя, разве нет?
Что-то значительно поменялось - тест не прошёл. Значит нужно писать новый тест под новые требования.
То что он упал - хорошо. То из-за чего упал - плохо
Пример: на форме есть кнопка с текстом "Отправить" с атрибутом data-test="submit". После рефакторинга осталась такая же кнопка "Отправить", но атрибут пропал. В итоге тест упал, хотя кнопка на месте и форма работает. Мы могли искать, например, по тексту, тогда бы тест мог бы пройти успешно.
Поэтому дополнительные атрибуты только для тестов не всегда стабильно работают и нужно понимать риски их изменения или исчезновения
Мы пошли дальше и встроили необходимые нам атрибуты в нашу библиотеку компонентов https://www.patternfly.org/v4/developer-resources/open-ui-automation
А идея была хороша: сконструировать декларативный язык для произвольной выборки данных из иерархических древовидных структур. Вот как SQL для таблиц, а это будет такое же, но для деревьев. И, вообще-то, это получилось, но не прижилось. Наверное, для мэйнстрима это слишком сложно оказалось, как и Haskell.
"Невилируйте проблемы в вёрстке и коде, подстраивайтесь под костыльный проект. Ну...лишь бы тесты работали"
"." - это не "вложенный текст". Это node. То есть весь элемент, включая теги.
И если как вы говорите "завтра заказчик может поменять дизайн", то почему не может появиться атрибут совпадающий с вашим текстом?
<button title="Настройки кое-чего другого">Остальные настройки</button>
Хотела сказать большое спасибо автору! Очень не хватало таких статей по XPath.
Сначала писала только с css-селекторами (на курсе было написано что XPath следует избегать), но по опыту XPath очень помогает и даже нравится больше).
Фильтры по номерам мне помогают допустим взять один элемент из какого-то множества одинаковых. Для динамического контента так же можно использовать css-селекторы. И допустим смотреть, что класс поменялся.
Поиск по вложенному тексту и использования отношений прям огонь! Я использовала функции ancestor и descendant, а так намного удобнее.
ХPath: что нужно делать, а что нет