Другие локали
Введение
примечаниеОбратитесь к основному руководству по локаторам для наиболее распространенных и рекомендуемых локаторов.
Помимо рекомендуемых локаторов, таких как page.getByRole() и page.getByText(), Playwright поддерживает множество других локаторов, описанных в этом руководстве.
Локатор CSS
примечаниеМы рекомендуем отдавать предпочтение локаторам, видимым для пользователя, таким как текст или доступная роль, вместо использования CSS, связанного с реализацией, что может привести к ошибкам при изменении страницы.
Playwright может находить элемент по CSS-селектору.
await page.locator('css=button').click(); Playwright расширяет стандартные CSS-селекторы двумя способами:
- CSS-селекторы проникают в открытый домен тени.
- Playwright добавляет пользовательские псевдоклассы, такие как
:visible,:has-text(),:has(),:is(),:nth-match()и многие другие.
CSS: сопоставление по тексту
Playwright включает ряд CSS-псевдоклассов для сопоставления элементов по их текстовому содержимому.
-
article:has-text("Playwright")- псевдокласс:has-text()соответствует любому элементу, содержащему указанный текст где-либо внутри, возможно, в дочернем или потомке. Сопоставление не учитывает регистр, обрезает пробелы и ищет подстроку.Например,
article:has-text("Playwright")соответствует<article><div>Playwright</div></article>.Обратите внимание, что
:has-text()следует использовать вместе с другими CSS-спецификаторами, иначе он будет соответствовать всем элементам, содержащим указанный текст, включая<body>.// Wrong, will match many elements including <body> await page.locator(':has-text("Playwright")').click(); // Correct, only matches the <article> element await page.locator('article:has-text("Playwright")').click(); -
#nav-bar :text("Home")- псевдокласс:text()соответствует наименьшему элементу, содержащему указанный текст. Сопоставление не учитывает регистр, обрезает пробелы и ищет подстроку.Например, это найдет элемент с текстом "Домой" где-то внутри элемента
#nav-bar:await page.locator('#nav-bar :text("Home")').click(); -
#nav-bar :text-is("Home")- псевдокласс:text-is()соответствует наименьшему элементу с точным текстом. Точное соответствие учитывает регистр, обрезает пробелы и ищет всю строку.Например,
:text-is("Log")не соответствует<button>Log in</button>потому что<button>содержит единственный узел текста"Log in", который не равен"Log". Однако,:text-is("Log")соответствует<button> Log <span>in</span></button>, потому что<button>содержит узел текста" Log ".Аналогично,
:text-is("Download")не будет соответствовать<button>download</button>потому что это чувствительно к регистру.
-
#nav-bar :text-matches("reg?ex", "i")- псевдокласс:text-matches()соответствует наименьшему элементу с текстовым содержимым, соответствующим регулярному выражению, похожему на JavaScript.Например,
:text-matches("Log\s*in", "i")соответствует<button>Login</button>и<button>log IN</button>.
примечаниеСопоставление текста всегда нормализует пробелы. Например, он преобразует несколько пробелов в один, преобразует символы новой строки в пробелы и игнорирует начальные и конечные пробелы.
примечаниеЭлементы ввода типа
buttonиsubmitсопоставляются по ихvalueвместо текстового содержимого. Например,:text("Log in")соответствует<input type=button value="Log in">.
CSS: сопоставление только видимых элементов
Playwright поддерживает псевдокласс :visible в CSS-селекторах. Например, css=button соответствует всем кнопкам на странице, а css=button:visible соответствует только видимым кнопкам. Это полезно для различения очень похожих элементов, которые различаются по видимости.
Рассмотрим страницу с двумя кнопками, первая невидимая, а вторая видимая.
<button style='display: none'>Invisible</button> <button>Visible</button>
-
Это найдет обе кнопки и вызовет ошибку нарушения строгости:
await page.locator('button').click(); -
Это найдет только вторую кнопку, потому что она видна, и затем нажмет ее.
await page.locator('button:visible').click();
CSS: элементы, содержащие другие элементы
Псевдокласс :has() является экспериментальным CSS-псевдоклассом. Он возвращает элемент, если какой-либо из селекторов, переданных в качестве параметров относительно :scope данного элемента, соответствует хотя бы одному элементу.
Следующий фрагмент возвращает текстовое содержимое элемента <article> который содержит <div class=promo>.
await page.locator('article:has(div.promo)').textContent(); CSS: элементы, соответствующие одному из условий
Список CSS-селекторов, разделенных запятыми, будет соответствовать всем элементам, которые могут быть выбраны одним из селекторов в этом списке.
// Clicks a <button> that has either a "Log in" or "Sign in" text.
await page.locator('button:has-text("Log in"), button:has-text("Sign in")').click(); Псевдокласс :is() является экспериментальным CSS-псевдоклассом, который может быть полезен для указания списка дополнительных условий для элемента.
CSS: Сопоставление элементов на основе макета
примечаниеСопоставление на основе макета может привести к неожиданным результатам. Например, может быть выбран другой элемент, когда макет изменится на один пиксель.
Иногда сложно придумать хороший селектор для целевого элемента, если у него нет отличительных особенностей. В этом случае использование CSS-псевдоклассов Playwright для макета может помочь. Их можно комбинировать с обычным CSS, чтобы точно определить один из нескольких вариантов.
Например, input:right-of(:text("Password")) соответствует полю ввода, которое находится справа от текста "Пароль" — полезно, когда на странице есть несколько полей ввода, которые трудно отличить друг от друга.
Обратите внимание, что псевдоклассы макета полезны в дополнение к чему-то еще, например, к input. Если вы используете псевдокласс макета в одиночку, например, :right-of(:text("Password")), скорее всего, вы получите не нужное поле ввода, а какой-нибудь пустой элемент между текстом и целевым полем ввода.
Псевдоклассы макета используют bounding client rect для вычисления расстояния и относительного положения элементов.
-
:right-of(div > button)- Сопоставляет элементы, которые находятся справа от любого элемента, соответствующего внутреннему селектору, на любой вертикальной позиции. -
:left-of(div > button)- Сопоставляет элементы, которые находятся слева от любого элемента, соответствующего внутреннему селектору, на любой вертикальной позиции. -
:above(div > button)- Сопоставляет элементы, которые находятся над любым из элементов, соответствующих внутреннему селектору, на любой горизонтальной позиции. -
:below(div > button)- Сопоставляет элементы, которые находятся под любым из элементов, соответствующих внутреннему селектору, на любой горизонтальной позиции. -
:near(div > button)- Сопоставляет элементы, которые находятся рядом (в пределах 50 пикселей CSS) с любым из элементов, соответствующих внутреннему селектору.
Обратите внимание, что полученные соответствия сортируются по расстоянию до якоря, поэтому вы можете использовать locator.first() для выбора ближайшего. Это полезно только если у вас есть список похожих элементов, где ближайший очевидно правильный. Однако использование locator.first() в других случаях, скорее всего, не сработает так, как ожидается — он не выберет нужный элемент, а какой-нибудь другой элемент, который оказался ближайшим, например, случайный пустой <div>, или элемент, который прокручен и не отображается в данный момент.
// Fill an input to the right of "Username".
await page.locator('input:right-of(:text("Username"))').fill('value');
// Click a button near the promo card.
await page.locator('button:near(.promo-card)').click();
// Click the radio input in the list closest to the "Label 3".
await page.locator('[type=radio]:left-of(:text("Label 3"))').first().click(); Все псевдоклассы макета поддерживают необязательное максимальное расстояние в пикселях в качестве последнего аргумента. Например, button:near(:text("Username"), 120) соответствует кнопке, которая находится не более чем на 120 пикселях CSS от элемента с текстом "Имя пользователя".
CSS: выбрать n-е соответствие из результата запроса
примечаниеОбычно можно отличить элементы по какому-либо атрибуту или текстовому содержимому, что более устойчиво к изменениям на странице.
Иногда страница содержит ряд похожих элементов, и сложно выбрать конкретный. Например:
<section> <button>Buy</button> </section> <article><div> <button>Buy</button> </div></article> <div><div> <button>Buy</button> </div></div>
В этом случае :nth-match(:text("Buy"), 3) выберет третью кнопку из приведенного выше фрагмента. Обратите внимание, что индекс является однозначным.
// Click the third "Buy" button
await page.locator(':nth-match(:text("Buy"), 3)').click(); :nth-match() также полезно для ожидания появления указанного количества элементов, используя locator.waitFor().
// Wait until all three buttons are visible
await page.locator(':nth-match(:text("Buy"), 3)').waitFor(); примечаниеВ отличие от
:nth-child(), элементы не должны быть братьями, они могут быть где угодно на странице. В приведенном выше фрагменте все три кнопки соответствуют селектору:text("Buy"), а:nth-match()выбирает третью кнопку.
Локатор n-го элемента
Вы можете сузить запрос до n-го соответствия, используя локатор nth= и передавая индекс с нуля.
// Click first button
await page.locator('button').locator('nth=0').click();
// Click last button
await page.locator('button').locator('nth=-1').click(); Локатор родительского элемента
Когда вам нужно выбрать родительский элемент другого элемента, в большинстве случаев следует использовать locator.filter() по локатору дочернего элемента. Например, рассмотрим следующую структуру DOM:
<li><label>Hello</label></li> <li><label>World</label></li>
Если вы хотите выбрать родительский <li> элемента label с текстом "Hello", лучше всего использовать locator.filter():
const child = page.getByText('Hello');
const parent = page.getByRole('listitem').filter({ has: child }); В качестве альтернативы, если вы не можете найти подходящий локатор для родительского элемента, используйте xpath=... Обратите внимание, что этот метод не является таким надёжным, потому что любые изменения в структуре DOM могут сломать ваши тесты. По возможности отдавайте предпочтение locator.filter().
const parent = page.getByText('Hello').locator('xpath=..'); Локатор React
примечаниеЛокатор React является экспериментальным и имеет префикс
_. Функциональность может измениться в будущем.
Локатор React позволяет находить элементы по имени компонента и значениям свойств. Синтаксис очень похож на CSS-селекторы атрибутов и поддерживает все операторы CSS-селекторов атрибутов.
В локаторе React имена компонентов записываются с использованием CamelCase.
await page.locator('_react=BookItem').click(); Дополнительные примеры:
- сопоставление по компоненту:
_react=BookItem - сопоставление по компоненту и точному значению свойства, чувствительному к регистру:
_react=BookItem[author = "Steven King"] - сопоставление только по значению свойства, нечувствительному к регистру:
_react=[author = "steven king" i] - сопоставление по компоненту и значению свойства с истинным значением:
_react=MyButton[enabled] - сопоставление по компоненту и логическому значению:
_react=MyButton[enabled = false] - сопоставление по подстроке значения свойства:
_react=[author *= "King"] - сопоставление по компоненту и нескольким свойствам:
_react=BookItem[author *= "king" i][year = 1990] - сопоставление по вложенному значению свойства:
_react=[some.nested.value = 12] - сопоставление по компоненту и значению свойства префикс:
_react=BookItem[author ^= "Steven"] - сопоставление по компоненту и значению свойства суффикс:
_react=BookItem[author $= "Steven"] - сопоставление по компоненту и ключу:
_react=BookItem[key = '2'] - сопоставление по значению свойства с регулярным выражением:
_react=[author = /Steven(\\s+King)?/i]
Для поиска имён элементов React в дереве используйте React DevTools.
примечаниеЛокатор React поддерживает React 15 и выше.
примечаниеЛокатор React, а также React DevTools, работают только с нескомпилированными сборками приложений.
Локатор Vue
примечаниеЛокатор Vue является экспериментальным и имеет префикс
_. Функциональность может измениться в будущем.
Локатор Vue позволяет находить элементы по имени компонента и значениям свойств. Синтаксис очень похож на CSS-селекторы атрибутов и поддерживает все операторы CSS-селекторов атрибутов.
В локаторе Vue имена компонентов записываются с использованием kebab-case.
await page.locator('_vue=book-item').click(); Дополнительные примеры:
- сопоставление по компоненту:
_vue=book-item - сопоставление по компоненту и точному значению свойства, чувствительному к регистру:
_vue=book-item[author = "Steven King"] - сопоставление только по значению свойства, нечувствительному к регистру:
_vue=[author = "steven king" i] - сопоставление по компоненту и значению свойства с истинным значением:
_vue=my-button[enabled] - сопоставление по компоненту и логическому значению:
_vue=my-button[enabled = false] - сопоставление по подстроке значения свойства:
_vue=[author *= "King"] - сопоставление по компоненту и нескольким свойствам:
_vue=book-item[author *= "king" i][year = 1990] - сопоставление по вложенному значению свойства:
_vue=[some.nested.value = 12] - сопоставление по компоненту и значению свойства префикс:
_vue=book-item[author ^= "Steven"] - сопоставление по компоненту и значению свойства суффикс:
_vue=book-item[author $= "Steven"] - сопоставление по значению свойства с регулярным выражением:
_vue=[author = /Steven(\\s+King)?/i]
Для поиска имён элементов Vue в дереве используйте Vue DevTools.
примечаниеЛокатор Vue поддерживает Vue2 и выше.
примечаниеЛокатор Vue, а также Vue DevTools, работают только с нескомпилированными сборками приложений.
Локатор XPath
предупреждениеРекомендуется отдавать приоритет локаторам, видимым для пользователя, таким как текст или доступная роль, вместо использования XPath, который привязан к реализации и легко ломается при изменении страницы.
Локаторы XPath эквивалентны вызову Document.evaluate.
await page.locator('xpath=//button').click(); примечаниеЛюбой строковый селектор, начинающийся с
//или.., предполагается, что является XPath-селектором. Например, Playwright преобразует'//html/body'в'xpath=//html/body'.
примечаниеXPath не проникает в теневые корни.
Объединение XPath
Оператор '|' (|) может использоваться для указания нескольких селекторов в XPath. Он будет соответствовать всем элементам, которые можно выбрать с помощью одного из селекторов в этом списке.
// Waits for either confirmation dialog or load spinner.
await page.locator(
`//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']`
).waitFor(); Перенаправление метки на элемент управления формой
предупреждениеМы рекомендуем находить по текстовой метке вместо использования перенаправления метки на элемент управления.
Направленные действия ввода в Playwright автоматически различает метки и элементы управления, поэтому вы можете нацеливаться на метку для выполнения действия над связанным элементом управления.
Например, рассмотрим следующую структуру DOM: <label for="password">Password:</label><input id="password" type="password">. Вы можете нацеливаться на метку по её тексту «Пароль» с помощью page.getByText(). Однако следующие действия будут выполняться над полем ввода, а не над меткой:
- locator.click() кликнет по метке и автоматически сфокусирует поле ввода;
- locator.fill() заполнит поле ввода;
- locator.inputValue() вернёт значение поля ввода;
- locator.selectText() выделит текст в поле ввода;
-
locator.setInputFiles() установит файлы для поля ввода с
type=file; - locator.selectOption() выберет вариант из выпадающего списка.
// Fill the input by targeting the label.
await page.getByText('Password').fill('secret'); Однако другие методы будут нацелены на саму метку, например expect(locator).toHaveText() проверит текстовое содержимое метки, а не поля ввода.
// Fill the input by targeting the label.
await expect(page.locator('label')).toHaveText('Password'); Локатор устаревшего текста
предупреждениеМы рекомендуем современный локатор текста вместо него.
Локатор устаревшего текста соответствует элементам, содержащим переданный текст.
await page.locator('text=Log in').click(); Устаревший локатор текста имеет несколько вариантов:
-
text=Log in— по умолчанию соответствие не учитывает регистр, обрезает пробелы и ищет подстроку. Например,text=Logсоответствует<button>Log in</button>.await page.locator('text=Log in').click(); -
text="Log in"— текстовое содержимое можно экранировать одинарными или двойными кавычками, чтобы искать узел текста с точным содержимым после обрезки пробелов.Например,
text="Log"не соответствует<button>Log in</button>, потому что<button>содержит узел текста"Log in", который не равен"Log". Однакоtext="Log"соответствует<button> Log <span>in</span></button>, потому что<button>содержит узел текста" Log ". Этот точный режим подразумевает чувствительное к регистру соответствие, поэтомуtext="Download"не будет соответствовать<button>download</button>.Экранирование содержимого в кавычках подчиняется обычным правилам экранирования, например, используйте
\"для экранирования двойной кавычки в строке с двойными кавычками:text="foo\"bar".await page.locator('text="Log in"').click(); -
/Log\s*in/i— содержимое может быть регулярным выражением JavaScript, заключённым в/символы. Например,text=/Log\s*in/iсоответствует<button>Login</button>и<button>log IN</button>.await page.locator('text=/Log\\s*in/i').click();
примечаниеСтроковые селекторы, начинающиеся и заканчивающиеся кавычками (
"или'предполагаются устаревшими локаторами текста. Например,"Log in"преобразуется во внутреннееtext="Log in".
примечаниеСопоставление всегда нормализует пробелы. Например, он преобразует несколько пробелов в один, переводы строк в пробелы и игнорирует начальные и конечные пробелы.
примечаниеЭлементы ввода типа
buttonиsubmitсопоставляются по ихvalueвместо текстового содержимого. Например,text=Log inсоответствует<input type=button value="Log in">.
id, data-testid, data-test-id, data-test селекторы
предупреждениеРекомендуется использовать поиск по идентификатору теста вместо этого.
Playwright поддерживает сокращенную запись для выбора элементов с использованием определенных атрибутов. В настоящее время поддерживаются только следующие атрибуты:
iddata-testiddata-test-iddata-test
// Fill an input with the id "username"
await page.locator('id=username').fill('value');
// Click an element with data-test-id "submit"
await page.locator('data-test-id=submit').click(); примечаниеСелекторы атрибутов не являются CSS-селекторами, поэтому все специфичные для CSS элементы, такие как
:enabledне поддерживаются. Для более широких возможностей используйте корректный селектор css, напримерcss=[data-test="login"]:enabled.
Цепочки селекторов
предупреждениеРекомендуется использовать цепочку локаторов вместо этого.
Селекторы, определённые как engine=body или в краткой форме, могут быть объединены с маркером >>, например selector1 >> selector2 >> selectors3. При объединении селекторов следующий селектор будет запрошен относительно результата предыдущего.
Например,
css=article >> css=.bar > .baz >> css=span[attr=value]
эквивалентно
document
.querySelector('article')
.querySelector('.bar > .baz')
.querySelector('span[attr=value]'); Если селектор должен содержать >> в теле, он должен быть экранирован внутри строки, чтобы не быть перепутано с разделителем цепочки, например text="some >> text".
Промежуточные совпадения
предупреждениеРекомендуется фильтровать по другому локатору, чтобы находить элементы, которые содержат другие элементы.
По умолчанию, цепочка селекторов приводит к элементу, запрошенному последним селектором. Селектор может быть префиксами * для захвата элементов, которые запрашиваются промежуточным селектором.
Например, css=article >> text=Hello захватывает элемент с текстом Hello, а *css=article >> text=Hello (обратите внимание на *) захватывает элемент article, который содержит элемент с текстом Hello.
© 2024 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/other-locators