Блог
Автотесты/Playwright
Локаторы в Playwright подробно: все способы найти элемент

Локаторы в Playwright подробно: все способы найти элемент

Локаторы в Playwright — это то, с чего начинается любой тест: прежде чем кликнуть или проверить элемент, его нужно найти на странице. Playwright предлагает сразу несколько способов поиска, и выбор правильного — не мелочь, а решение, которое определяет, насколько стабильными будут тесты при изменении вёрстки.

getByRole — приоритетный способ

await page.getByRole('button', { name: 'Отправить' }).click();
await page.getByRole('link', { name: 'На главную' }).click();
await page.getByRole('checkbox', { name: 'Согласен с условиями' }).check();
await page.getByRole('heading', { name: 'Добро пожаловать', level: 1 });

Поиск кнопки через getByRole
getByRole ищет элемент по его роли в дереве доступности (accessibility tree) — той же модели, которой пользуются скринридеры для незрячих пользователей. Это делает getByRole устойчивым к изменениям CSS-классов, порядка атрибутов и внутренней структуры HTML: пока элемент остаётся кнопкой с текстом «Отправить», локатор будет находить его независимо от того, как именно вёрстка реализована внутри.

getByText, getByLabel, getByPlaceholder

await page.getByText('Заказ оформлен').isVisible();
await page.getByLabel('Email').fill('user@example.com');
await page.getByPlaceholder('Введите пароль').fill('secret123');

Локаторы getByText, getByLabel и getByPlaceholder
getByText ищет по видимому тексту элемента — удобно для проверки сообщений, уведомлений, статусов. getByLabel находит поле формы по связанной с ним подписи (<label>) — предпочтительный способ для полей ввода, потому что отражает то, как пользователь реально ориентируется в форме. getByPlaceholder — по подсказке внутри пустого поля, полезно, когда у поля нет явного <label>.

getByTestId — запасной вариант

await page.getByTestId('submit-button').click();

Поиск элемента через getByTestId
getByTestId ищет элемент по специальному атрибуту (по умолчанию data-testid), который разработчики добавляют в разметку специально для тестов. Это надёжный, но не самый «естественный» способ — он требует, чтобы фронтенд-разработчики заранее проставили такие атрибуты. Используется, когда у элемента нет подходящей роли, текста или подписи, по которым его можно было бы найти иначе.

Попробуйте автотесты бесплатно
Playwright Arena — 30 задач от основ JavaScript до первых тестов на Playwright. Без оплаты, без карты и без ограничения попыток.
Открыть Playwright Arena

Фильтрация и уточнение локаторов

Если по одному запросу находится несколько элементов, локатор можно сузить:
// первый элемент из нескольких подходящих
await page.getByRole('button', { name: 'Удалить' }).first().click();

// элемент по индексу
await page.getByRole('listitem').nth(2).click();

// фильтрация по вложенному тексту
await page.getByRole('listitem').filter({ hasText: 'Молоко' }).click();

// комбинация: локатор внутри локатора
const row = page.getByRole('row', { name: 'Заказ №105' });
await row.getByRole('button', { name: 'Отменить' }).click();

Фильтрация и вложенные локаторы: поиск внутри строки таблицы
Вложенные локаторы (row.getByRole(...)) — частый и полезный паттерн: сначала находится контейнер (строка таблицы, карточка товара), а затем внутри него ищется конкретный элемент. Это точнее, чем искать кнопку «Отменить» по всей странице, если таких кнопок несколько в разных строках.

Почему CSS-селекторы и XPath — не первый выбор

// Работает, но хрупко: привязан к структуре и классам вёрстки
await page.locator('.btn.btn-primary.submit-form > span').click();

Хрупкий CSS-селектор, который ломается при смене вёрстки
Такой локатор сломается при любом изменении CSS-классов или структуры вложенности, даже если сама кнопка на странице никуда не делась и выглядит так же. getByRole, getByText, getByLabel устойчивее, потому что опираются на то, что видит и понимает пользователь, а не на детали реализации вёрстки. CSS-локаторы остаются рабочим инструментом, но как последний вариант, когда более «человеческие» локаторы не подходят.

Частые вопросы про локаторы в Playwright

Какой локатор использовать в первую очередь? getByRole — он рекомендован официальной документацией Playwright как приоритетный способ, потому что устойчив к изменениям вёрстки и отражает то, как реально взаимодействует с элементом пользователь.
Когда стоит использовать getByTestId? Когда у элемента нет подходящей роли, текста или подписи для поиска другим способом — например, у декоративного элемента без видимого текста. Требует, чтобы атрибут data-testid был заранее добавлен в разметку.
Что делать, если локатор находит несколько элементов? Сузить его: через .first(), .nth(index), фильтрацию по тексту (.filter({ hasText: '...' })) или через поиск внутри более конкретного родительского локатора.
Почему не стоит использовать CSS-селекторы по умолчанию? CSS-классы и структура HTML часто меняются при рефакторинге вёрстки, даже если поведение элемента остаётся прежним — из-за этого CSS-локаторы чаще ломаются и требуют переписывания, чем локаторы по роли или тексту.

Закрепить локаторы на практике

Разница между .filter(), .first() и вложенными локаторами лучше укладывается в голове на реальных задачах. Бесплатный тренажёр Playwright Arena от Quality Academy — 30 задач без оплаты и ограничения попыток. Как записать первые локаторы автоматически — в статье «Playwright Codegen: автогенерация тестов».

Курс «Автотестирование на JS/TS + Playwright»
Для ручных тестировщиков: 4 месяца, персональный ментор, код-ревью каждого задания и свой проект автотестов в портфолио. От 58 000 ₽.
Узнать о курсе
Попробуйте автотесты бесплатно
Playwright Arena — 30 задач от основ JavaScript до первых тестов на Playwright. Без оплаты, без карты и без ограничения попыток.
Открыть Playwright Arena
По всем вопросам:
Quality Academy
Используя данный сайт, вы даёте согласие на использование файлов cookie.
ОК, ЗАКРЫТЬ