В CSS есть псевдокласс :nth-child() — он находит один или более элементов, основываясь на их позиции среди группы соседних элементов. ©
Но у него есть ряд минусов:
- не срабатывает в firefox (даже когда в хроме всё нормально);
- срабатывает с оговорками — и поэтому xpath выражение для поиска будет лучше.
<html><body><div attr='1'>Блок 1</div><p>Блок 1</div><div attr='2'>Блок 2</div><div attr='3'>Блок 3</div></body></html>
Открываем файлик в хроме (это важно!).
А теперь попробуем найти второй div. Попробуем через XPath:
//div[2]
Всё работает! Найдет один элемент, второй по счету div:
Теперь попробуем через CSS:
div:nth-child(2)
Увы, ничего не найдено:
Может быть, мы неправильно составили запрос? Хотя он сейчас несложный, это даже не «div[attr]», но проверим, уберем псевдокласс. И да, найдено 3 div элемента, второй тот, что нам и нужен:
То есть само условие верное, вот только псевдокласс почему-то не сработал. А смущает его тот факт, что между div-ами затесался элемент другого типа — <p>. Давайте сделаем html-файлик без этого "лишнего" элемента:
<html><body><div attr='1'>Блок 1</div><div attr='2'>Блок 2</div><div attr='3'>Блок 3</div></body></html>
И снова поищем. XPath всё ещё отлично работает:
//div[2]
Элемент найден:
Пробуем CSS
div:nth-child(2)
Вот, теперь сработало!
Если у вас не сработало, то вы, видимо, использовали другой браузер. Если открыть ту же страничку в Firefox и вставить CSS селектор, он подсветит нам подсказку уже без слова child
А если нажать Enter, активировав поиск — браузер вообще удалит псевдокласс и будет искать по селектору «div», хотя это не то, что нам нужно...
Так, ну с лисой (firefox) всё понятно, но почему в chrome так происходит? Ведь по сути своей селекторы css и xpath должны быть одинаковы, находить второй элемент среди соседей (под одним родителем).
Но хром ищет четко среди соседей. Если между соседями есть другой элемент (<p> в нашем случае) — всё, поиск не срабатывает. Более того, после <p> идет 2 div-элемента, они соседние, но среди них он тоже никого не находит.
А ведь если взглянуть на реальные HTML-страницы, то там целая толпа разных элементов! И далеко не всегда несколько одинаковых элементов будут идти подряд, без "чужеродных" соседей.
Поэтому, если вам вдруг нужно обратиться к элементу по его номеру, лучше использовать XPath, он в этом плане понадежнее будет. Хотя глобально это плохая практика, особенно в автотестах — завязываться на дерево элементов, слишком уж оно ненадежно. Чуть изменили HTML, и вот уже куча упавших тестов!
Намного лучше привязываться к элементам по их атрибутам, желательно уникальным. Крайне желательно по id, он точно уникален... Но если такой возможности нет, то помните про эти особенности поиска child-ов =)
PS — статья написана в помощь студентам моего курса «CSS и Xpath: инструменты тестировщика».
Комментариев нет:
Отправить комментарий