Не можете понять, почему псевдокласс: contains () в селекторах CSS работает именно так?

StackOverflow https://stackoverflow.com/questions/9334539

Вопрос

Я использую селекторы CSS с Selenium и Cucumber. Когда локатор не работает, я тестирую его с помощью консоли Chrome Developer Tools. Я все время сталкиваюсь с поведением, которого не понимаю (например, почему он делает то, что делает, а не то, что мне нужно ...). Пожалуйста, посмотрите на эти локаторы:

  1. div.view_header ~ div input.my_button

  2. div:contains(My Header Title) ~ div input.my_button

  3. 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 - идеально соответствует всем Текущие результаты Sizzle

Selenium's Sizzle - соответствует 1 из 4 Результаты Sizzle от Selenium


Результаты говорят сами за себя. Selenium использует старую версию Sizzle, которая каким-то образом несовершена в обработке псевдокласса :contains(). Текущая версия Sizzle не страдает этой ошибкой и может хорошо находить все элементы.

Теперь вы можете сделать любое из этих действий:

  1. Сообщите об ошибке Selenium.
  2. Используйте XPath как обходной путь.
  3. Переключите файл contains в вашем пакете Selenium.

Другие советы

родовое слово
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top