CSS vs XPath - кто сильнее?

@UaTanya В вашем примере ни CSS ни XPath не нужен, Selenium умеет находить ссылки по тексту своим нативным методом. Правда не знаю, реализован ли этот метод в PHPUnit_Selenium2TestCase (кажется вы его используете), но на будущее рекомендую посмотреть на альтернативную библиотеку php-webdriver.

Вцелом, XPath позволяет двигаться как в глубину так и в ширину по DOM дереву, в то время, как CSS только в глубину. Например, через XPath можно написать поиск элемента по его лейблу, что например, очень полезно для форм. С другой стороны, XPath крайне не удобен в обслуживании.

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

1 лайк

Спасибо, но что делать в том случае если программисты в проекте часто используют элементы, у которых каждый раз css меняется (это не их прихоть, а так нужно).
Например, вот так

css=#tableeditor-145-button_copy
css=#tableeditor-191-button_copy

и т.д.
Текста у этого элемента нет, а есть неизменяемый xpath.

Возможно для такого случая знаете лучшие решения, чем xpath?

for ($i = 100; $i<1000; $i++) {
   $el = $driver->findElement(WebDriverBy::id("#tableeditor-$i-button_copy"));
   if (!$el) continue;
}

Но не советую воспринимать это серьезно )

А вцелом да, отличное место для XPath - как ни крути, локатор тут будет короткий, плюс как раз возможность движка позволяют делать нечеткий поиск по атрибутам.

Идеальный мир для селениума - все элементы имеют постоянные id:)

4 лайка

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

Вот можете просто привести пример локаторов, которые вы перевели из xpath в css и указать почему вы их перевили в такой вид?

Эффективные и гибкий локаторы - это прямой результат эффективной совместной работы тех кто автоматизирует и верстальщиков с программистами. Можно просто плыть по течению и писать локаторы, которые получаются. А можно взять волю в кулак и решить проблемы организационно, при этом решая неявно вопросы уникальности, гибкости и поддержки локаторов.

Так нужно тогда использовать другие элементы, которые могут задать уникальность локатора. Тут вот как раз css или xpath в помощь. Или программно высчитывать id как указал @davert

Понятно, что такого идеального мира тяжело найти, но поверьте в наших силах поменять это. Просто надо задаться целью, вот и все.

1 лайк

Ну и @dzhariy ушел немного в сторону указав примеры создания локаторов с разными javascript библиотеками используемыми в веб-приложении, подключаемся к обсуждению.

Полностью согласен. Успех достигается лишь совместной работой.

Ага, только разрабам, как правило, пофиг, либо же они в принципе не знаю как устроен framework, работая с ним только на уровне реализуемого языка.

Вот интересно, как отличается скорость на мобильных броузерах, поддерживающих и css и xpath.

Давай проверим?

Ну в любом случае xpath позволяет сделать все то-же и еще немного по сравнению с css :smile:
Все достаточно доходчиво было описано в вебинаре миши про гибкие локаторы.
к примеру частенько встречается такая вот радость набор из таких вот блоков:

<div>
      <label>Some Text Label</label>
      <input>type="text"</label>
</div>

то для xpath метод получения текстового поля с таким шаблоном будет такой:

public WebElement getTextField(String label){
    return driver.findElement(
           By.xpath(".//label[contains(text(), '"+label+"')]/parent::div//input"));
}

при желании можно еще и на запчасти разобрать.
А вот как подобное сделать с помощью css?

contains – это конечно, сейчас – железный аргумент. Такой селектор, аля input:contains(text) планировался в CSS3, но в итоге – потерялся и не вошел в спецификацию.

Да, преимущество XPath в том, что на нем однозначно можно идентифицировать любой элемент, тем не менее, можно и совмещать CSS селекторы для простых вещей и XPath для более сложных. Я предпочитаю такой вариант

2 лайка

Тут дело даже на в contains, а в /parent::, /ancestor::

Да ладно… скоро будет :blush:

E! > F - an E element parent of an F element

… в CSS4 Selectors Level 4

Я не спорю, на xpath есть много фишек, которые помогают выйти из любой ситуации. Много этого нет в CSS.

Но, есть еще один выход: попросить/заставить добавить ID или name к интересующему элементу.

Ведь был бы HTML таким – и проблемы бы не было:

"
< div>
    <label for="userName">Some Text Label</label>
    <input type="text" name="userName"/>
< /div>
"

Ребят, что думаете по поводу валидации элементов на странице во время тестирования используя xpath?

Вот так тест завалиться (на этой страничке кнопочка Обучение с шапочкой):

//a[@target="_blank"][@href='http://lessons2.ru/?utm_source=atinfo&utm_medium=top_menu&utm_term=link&utm_campaign=reference']/li[text()='Обучение']/i[@class='fa fa-graduation-cap']

А вот так не завалиться:

//a[@target="_blank"][@href='http://lessons2.ru/?utm_source=atinfo&utm_medium=top_menu&utm_term=link&utm_campaign=reference']/li[text()=' Обучение']/i[@class='fa fa-graduation-cap']

Как бы пишем локатор для теста, но еще и валидируем для нас важные вещи в этом локаторе…

Вся разница между двумя приведенными xpath в одном пробеле перед “Обучение”. В чем тут валидация заключается?

Ну да, о том то и речь, мол и локатор пишешь и сразу валидируешь необходимые элементы. Использовал ли кто-то такое?

Я наверное не до конца понимаю твою идею.
Ты хочешь валидировать наличие текста " Обучение"?

Идея не совсем моя… Я имею ввиду для теста, в котором надо нажать на кнопку “Обучение” вверху страницы и проверить работает она или нет - понадобиться локатор этой кнопки. Можно написать простой локатор, который будет хвататься за кнопку. А можно сделать в локатеоре валидацию:

xpath:

//a[@target="_blank"][@href='http://lessons2.ru/?utm_source=atinfo&utm_medium=top_menu&utm_term=link&utm_campaign=reference']/li[text()=' Обучение']/i[@class='fa fa-graduation-cap']

кнопка:

<a href="http://lessons2.ru/?utm_source=atinfo&amp;utm_medium=top_menu&amp;utm_term=link&amp;utm_campaign=reference" target="_blank">
  <li>
    <i class="fa fa-graduation-cap"></i> 
    Обучение
  </li>
</a>

части xpath, для более понятного представления:

Теперь ясно. Ну, мне кажется, такой подход имеет право на существование, если есть уверенность, что xpath не будет сильно меняться со временем. Иначе тесты будут часто падать от любого чиха, а вместо простого обновления локаторов, нужно будет заново все взаимосвязи учитывать.