Для написания автотестов используются XPath и CSS-селекторы. Они помогают найти элемент на странице, чтобы потом с ним как-то взаимодействовать (кликнуть, ввести текст, или что-то другое).
Я видела много статей о том, что это вообще такое, но мне очень не хватало шпаргалки по разным селекторам, причем в разрезе «Вот он в CSS и он же в XPath» для сравнения.
А мне такое для студентов надо. Поэтому решила сделать сама. Вдохновлялась страничкой «Xpath cheatsheet», но сделала на свой вкус — под автоматизацию, а не XPath вообще. И с комментариями, с ними удобнее.
Пишите, если где-то накосячила. Хотя я все селекторы проверяла на тестовых страницах, но мало ли… И надеюсь, вам такая шпаргалка тоже пригодится! =)
Содержание
Поиск конкретного элемента
|
CSS |
XPath |
Комментарий |
|
* |
//* |
Найти любой элемент (используется обычно как часть более сложного запроса) |
|
div |
//div |
Найти элемент div |
|
div:nth-child(2) |
//div[2] |
Найти 2-ой элемент div под общим родителем (вместо 2 может быть любая цифра) В CSS используется псевдокласс, в firefox он не срабатывает, в хроме тоже может глючить. В этом сценарии xpath лучше |
Поиск по атрибутам
|
CSS |
XPath |
Комментарий |
|
Любой элемент |
||
|
.form-control |
//*[@class=»form-control»] |
Элемент с классом form-control |
|
#sample_1 |
//*[@id=»sample_1″] |
Элемент с атрибутом id = sample_1 |
|
[id] |
//*[@id] |
Элемент с атрибутом id, значение у атрибута любое |
|
|
|
|
|
Конкретный элемент (в примере это div, но искать можно любой) |
||
|
div.form-control |
//div[@class=»form-control»] |
Именно div элемент с атрибутом class=form-control |
|
div#sample_1 |
//div[@id=»sample_1″] |
Именно div элемент с атрибутом id = sample_1 |
|
div[id] |
//div[@id] |
Именно div элемент с атрибутом id |
|
div[attr]:nth-child(2) |
//div[2][@attr] |
2-ой элемент div с атрибутом attr под общим родителем XPath найдет такой div, даже если между 2-мя div-ами будет что-то ещё. А вот CSS нет (см тут подробнее), только если подряд идут. Поэтому с потомками лучше через XPath |
|
h1:not([id]) |
//h1[not(@id)] |
Элемент h1, у которого нет атрибута id |
|
— |
//a[@name or @href] |
Элемент а, у которого есть или атрибут name, или href, или оба |
|
|
|
|
|
Сравнения по тексту атрибута (в примере это class, но атрибут может быть любым) |
||
|
Есть атрибут class, проверяем текст в нем. Допустим, у нас есть такие элементы: 1. class = “test-1 test-3 test-2” 2. class = “test-1” |
||
|
[class=»test-1″] [class=’test-1′] |
//*[@class=»test-1″] //*[@class=’test-1′] |
Текст четко равен «test-1» (тип кавычек не важен) Найдет элемент 2, но не найдет элемент 1. |
|
[class~=»test-3″] |
//*[contains(@class, ‘test-3’)] |
Текст атрибута состоит из нескольких слов, разделенных пробелами, одно из них — искомое. В XPath такого нет, поэтому там просто contains — в тексте есть искомое значение Найдет элемент 1 |
|
[class|=»test»] |
//*[contains(@class, ‘test’)] |
Полное соответствие или атрибут начинается как указано и потом идет «-» (U+002D) Найдет и элемент 1, и элемент 2 |
|
[class^=»te»] |
//*[starts-with(@class, ‘te’)] //*[substring-after(@class, ‘te’)] |
Начинается на … Найдет и элемент 1, и элемент 2. В Xpath 2 варианта записи, substring-after ищет текст, который идет после указанного, то есть указанный должен быть. В CSS запись как в регулярных выражениях |
|
[class$=»2″] |
//*[substring-before(@class, ‘2’)] |
Заканчивается на … Найдет только элемент 1 В Xpath ещё должно быть выражение «ends-with», но оно не работает ? |
|
[class*=»st»] |
//*[contains(@class, ‘st’)] |
Содержит искомый текст (хотя бы 1 вхождение, неважно где, начало, конец или середина строки) Найдет и элемент 1, и элемент 2. |
Поиск по тексту элемента
|
CSS |
XPath |
Комментарий |
|
— |
//a/text()[. =»Ссылка»] |
Текст внутри тегов <a> равен «Ссылка» |
|
— |
//a[contains(text(),’Ссылка’)] |
Текст cодержит «Ссылка» (может быть частью слова) |
|
— |
//*[starts-with(text(), ‘Ссы’)] //*[substring-after(text(), ‘Ссы’)] |
Начинается на … |
|
— |
//*[substring-before(text(), ‘ка’)] |
Заканчивается на … (одно из слов, «Ссылка 1» тоже найдет) |
|
— |
//a[string-length(text()) > 6] |
Длина текста тега <a> больше 6 символов (оператор может быть любым) |
Поиск по позиции элемента
|
CSS |
XPath |
Комментарий |
|
div:first-child |
//*[1][name()=»div»] |
Первый div |
|
div:last-child |
//*[last()][name()=»div»] |
Последний div |
|
|
|
|
|
body div:last-child |
//body/div[last()] |
Последний div внутри body |
|
— |
//body/div[last()-1] |
Предпоследний div |
|
— |
//body/div[position()<3] |
Все div от 1 до 3 (не включительно, оператор может быть любым) |
|
div:nth-of-type(2) |
//body/div[position()=2] |
Конкретная позиция (2-ая, но цифра может быть любой) CSS работает с оговорками (см тут подробнее) |
|
|
|
|
|
div:first-of-type |
//div[1] |
Первый элемент div |
|
div#id:first-of-type |
//div[1][@id] |
Первый элемент div с атрибутом id |
|
div[attr]:first-of-type |
//div[1][@attr] |
Первый элемент div с атрибутом attr |
|
|
|
|
|
div:last-of-type |
//div[last()] |
Последний элемент div |
Поиск потомков (обход дерева вниз)
|
CSS |
XPath |
Комментарий |
|
div h2 |
//div//h2 |
h2, дочерний к div (на любом уровне вложенности, div — test — h2 найдет) |
|
div > h2 |
//div/h2 |
Прямой потомок (1 уровень вложенности, div — test — h2 уже не найдет) |
|
div > div > h2 |
//div/div/h2 |
Спускаемся по дереву, ищем div, внутри ещё div, внутри h2 (прямые потомки везде) |
|
|
|
|
|
body > * |
//body/child::* |
Дети (1 уровень вложенности) любые |
|
body > div |
//body/child::* |
Дети с типом div |
|
|
|
|
|
body * |
//body/descendant::* |
Все потомки с типом div (любой уровень вложенности: дети, внуки…) |
|
body div |
//body/descendant::a |
Только потомки div |
|
— |
//body/descendant-or-self::* |
Сам body и все потомки |
|
|
|
|
|
— |
//head/following::* |
Все, что после head идет |
|
— |
//head/following::a |
Все элементы a, которые идут после head |
Поиск предков (обход дерева вверх)
CSS не умеет идти по дереву наверх, тут только XPath сработает
|
CSS |
XPath |
Комментарий |
|
— |
//a/ancestor::* |
Все предки ссылки — родитель, дед, прадед, на все уровни вверх смотрим (<a> — это ссылка в HTML) |
|
— |
//a/ancestor::div |
Только предок div |
|
|
|
|
|
— |
//a/ancestor-or-self::* |
Сама ссылка + предки |
|
— |
//a/ancestor-or-self::div |
Сама ссылка + предки div |
|
— |
//a/ancestor-or-self::a |
Сама ссылка + предки такого же типа (a) |
|
|
|
|
|
— |
//a/parent::* |
Родитель ссылки (строго 1 уровень наверх) |
|
|
|
|
|
— |
//p/preceding::* |
Все узлы до текущего, кроме непосредственного родителя (но зато есть те, кто идет до родителя + предки) |
|
— |
//p/preceding-sibling::* |
Все узлы-соседи до текущего узла (под одним родителем) |
Поиск соседей
|
CSS |
XPath |
Комментарий |
|
h1 ~ h2 |
//h1/following-sibling::h2 |
Все элементы h2, которые находятся после элемента h1 внутри одного родителя |
|
h1 + h2 |
//h1/following-sibling::h2[1] |
Только первый элемент h2, соседний к h1 справа (находится после) В XPath можно выбрать не только первый, но и второй, третий, даже last() |
|
— |
//h1/following-sibling::h2[last()] |
Последний элемент, который находится после элемента h1 внутри одного родителя |
Поиск по комментариям
|
CSS |
XPath |
Комментарий |
|
— |
//comment() |
Все комментарии |
|
— |
//comment()[. = ‘comment’] |
Комментарий с конкретным текстом |
|
— |
//comment()[. = ‘ comment ‘]/parent::* |
Родительский элемент комментария |
PS — больше полезных статей ищите в моем блоге по метке «полезное». А полезные видео — на моем youtube-канале
ссылка на оригинал статьи https://habr.com/ru/articles/817555/
Добавить комментарий