Spec-Zone.ru › Playwright

Другие локаторы

Введение​

примечание

См. основное руководство по локаторам, где описаны самые распространённые и рекомендуемые локаторы.

Помимо рекомендуемых локаторов, таких как page.getByRole() и page.getByText(), Playwright поддерживает и другие локаторы, описанные в этом руководстве.

CSS-локатор​

примечание

Мы рекомендуем отдавать предпочтение локаторам, ориентированным на пользователя, например по тексту или доступной роли, а не использовать CSS, привязанный к реализации и способный перестать работать при изменении страницы.

Playwright может находить элементы по CSS-селектору.

await page.locator('css=button').click();

Playwright расширяет стандартные CSS-селекторы двумя способами:

  • CSS-селекторы проникают в открытый Shadow DOM.
  • 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() соответствует наименьшему элементу, содержащему указанный текст. Поиск не учитывает регистр, удаляет пробелы в начале и конце и выполняет поиск подстроки.

    Например, этот селектор найдёт элемент, внутри которого где-либо содержится текст «Home», в элементе #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 — только видимым кнопкам. Это полезно, когда нужно различить очень похожие элементы, отличающиеся видимостью.

примечание

Вместо псевдокласса :visible используйте краткий вариант locator.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")) соответствует полю ввода, расположенному справа от текста «Password». Это полезно, если на странице есть несколько полей ввода, которые сложно отличить друг от друга.

Обратите внимание: псевдоклассы расположения полезны в сочетании с чем-то ещё, например с input. Если использовать только псевдокласс расположения, например :right-of(:text("Password")), скорее всего, будет найдено не нужное поле ввода, а какой-нибудь пустой элемент между текстом и целевым полем.

Псевдоклассы расположения используют прямоугольник границ элемента, чтобы вычислить расстояние и относительное положение элементов.

  • :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-пикселей от элемента с текстом «Username».

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> метки с текстом "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=..');

XPath-локатор​

предупреждение

Мы рекомендуем отдавать предпочтение локаторам, ориентированным на пользователя, например по тексту или доступной роли, а не использовать XPath, привязанный к реализации и легко ломающийся при изменении страницы.

XPath-локаторы эквивалентны вызову Document.evaluate.

await page.locator('xpath=//button').click();
примечание

Любая строка селектора, начинающаяся с // или .., считается XPath-селектором. Например, Playwright преобразует '//html/body' в 'xpath=//html/body'.

примечание

XPath не проникает в корни теневого DOM.

Объединение 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">. Метку можно выбрать по тексту «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 поддерживает сокращённую запись для выбора элементов по определённым атрибутам. В настоящее время поддерживаются только следующие атрибуты:

  • id
  • data-testid
  • data-test-id
  • data-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.

© 2026 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/other-locators

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API