Не можете понять, почему псевдокласс: contains () в селекторах CSS работает именно так?
-
27-10-2019 - |
Вопрос
Я использую селекторы CSS с Selenium и Cucumber. Когда локатор не работает, я тестирую его с помощью консоли Chrome Developer Tools. Я все время сталкиваюсь с поведением, которого не понимаю (например, почему он делает то, что делает, а не то, что мне нужно ...). Пожалуйста, посмотрите на эти локаторы:
div.view_header ~ div input.my_button
div:contains(My Header Title) ~ div input.my_button
div:contains(My Header Title) ~ div div div input.my_button
В моем DOM элемент, соответствующий первой части каждого из этих локаторов, одинаков ...
родовое слово Проблема в том, что только указатели №1 и №3, указанные выше, действительно могут соответствовать чему-либо. Кто-нибудь знает, почему это правда. Я понимаю, что div:contains(foo)
будет соответствовать не только div, который фактически содержит foo, но и всем родительским div, но мне кажется, что остальные элементы локатора должны сортировать его, чтобы он работал.
Я просто ищу какие-либо идеи и, возможно, предложения, как убедиться, что кнопка my_button, которую я нажимаю, находится под заголовком My Header Title, а не my_button где-то еще на странице (и единственный простой способ отличить их - по заголовку, под которым они находятся), исключив при этом кажущуюся избыточной структуру DOM в локаторе, чтобы сделать ее более пригодной для повторного использования.
родовое словоРешение
Обычно, когда я сталкиваюсь с подобными проблемами, я смотрю спецификации.
Не могли бы вы вместо этого использовать XPath ? Либо внутренними методами Selenium, либо JavaScript . Этот XPath совпадает с вашим селектором CSS номер 2:
родовое слово< sizesEDIT
После того, как ваш комментарий показал мне, что мы говорим о Selenium RC и, следовательно, о Sizzle, я копнул глубже.
Я взял ваш пример HTML, удалил из него скрытые и (казалось бы) ненужные элементы и остался с таким:
родовое словоЯ загрузил последнюю версию Sizzle и получил версия Sizzle, которая фактически используется Selenium в текущем выпуск .
Оказывается, это очень разные вещи.
Например, реализация текущего кода кода Sizzle:
родовое словои реализация Selenium использует:
родовое словоЯ пробовал обе реализации в своем тестовом документе, результаты можно увидеть здесь (нажмите, чтобы увеличить):
Current Sizzle - идеально соответствует всем
Selenium's Sizzle - соответствует 1 из 4
Результаты говорят сами за себя. Selenium использует старую версию Sizzle, которая каким-то образом несовершена в обработке псевдокласса :contains()
. Текущая версия Sizzle не страдает этой ошибкой и может хорошо находить все элементы.
Теперь вы можете сделать любое из этих действий:
- Сообщите об ошибке Selenium.
- Используйте XPath как обходной путь.
- Переключите файл
contains
в вашем пакете Selenium.
Другие советы