Spec-Zone.ru › Playwright

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

Введение​

примечание

Обратитесь к основному руководству по локаторам для наиболее распространенных и рекомендуемых локаторов.

Помимо рекомендуемых локаторов, таких как 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 поддерживает сокращенную запись для выбора элементов с использованием определенных атрибутов. В настоящее время поддерживаются только следующие атрибуты:

  • 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.

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

Spec-Zone.ru

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