Как работать с селекторами в Playwright?

При выполнении сквозного тестирования и мониторинге веб-сайтов с помощью Playwright важное значение имеет выбор правильных локаторов, т.к. они помогают создавать более стабильные и надёжные тесты.

Давайте рассмотрим локаторы, ориентированные на взаимодействие с пользователем (так называемые user-first локаторы), а также способы фильтрации локаторов для повышения стабильности тестов.

🔥 Важное для QA-специалистов! 🔥
В QaRocks ты найдешь туториалы, задачи и полезные книги, которых нет в открытом доступе. Уже более 15.000 подписчиков – будь среди нас! Заходи к нам в телеграм канал QaRocks

Пример сценария

Рассмотрим простую веб-страницу с заголовком, кнопкой “Click me” и полем обновления статуса. Представим, что при нажатии на кнопку статус обновляется и появляется конфетти. Давайте найдем элементы на этой странице.

confetti страница

Почему не стоит использовать CSS-селекторы для поиска элементов на странице?

Если вы привыкли к старым инструментам автоматизации и работы с веб-страницами, такими как jQuery, может возникнуть соблазн использовать CSS-селекторы.

Если мы взглянем на структуру HTML-кода страницы, то обнаружим, что к кнопке “Click me” применен CSS-класс, с помощью которого ее можно было бы найти на странице.

Мы могли бы нажать на эту кнопку в нашем тесте с помощью строки вроде await page.locator("button.button-frontpage-style").click(), и это сработало бы, но такой способ не рекомендуется.

В чем проблема такого подхода?

Во-первых, наши пользователи, когда просматривают страницу, хотят найти кнопку по ее тексту, а не по CSS-классу. Выбирая кнопку по классу, наш тест не имитирует реальное взаимодействие пользователя со страницей.

Во-вторых, если фронтенд-разработчик с целью изменения стиля элемента переименует класс на button-hero-panel-style, то наш тест выдаст ложное срабатывание: сообщит об ошибке, которой на самом деле нет.

В-третьих, если текст нашей кнопки поступает из CMS (Content Management System – система управления контентом), и он по какой-то причине меняется на технический идентификатор (например “HEROBUTTON_TXT”), наш тест все равно пройдет, т.к. использует CSS-класс в качестве локатора. Однако, пользователь увидит некорректный интерфейс. То есть мы получим ложноотрицательный результат выполнения нашего теста.

Вместо CSS-селекторов используйте user-first локаторы

Playwright предлагает ряд локаторов, основанных на роли элемента на странице. Используйте такие встроенные локаторы, как getByRole, getByText и getByLabel, которые будут искать элементы так же, как их “видит” пользователь – даже если он использует нестандартную сборку браузера, мобильное устройство или даже скринридер.

User-first локаторы в действии

Давайте заменим page.locator на getByRole, чтобы найти кнопку по ее роли и доступному имени:

await page.getByRole('button', { name: 'click me' }).click();

Чтобы определить доступные роли и имена элементов используйте инструменты разработчика (DevTools).

Этот метод повышает стабильность тестов даже при изменении имен классов или HTML-структуры.

Дополнительным бонусом является то, что при поиске имен Playwright нечувствителен к регистру и находит элементы по частичному совпадению. Поэтому вы можете изменить селектор на { name: 'click' }, и тест пройдет без проблем, даже если маркетологи переименуют кнопку на “Click me now!”.

Однако, если текст кнопки изменится на что-то вроде “HEROBUTTON_TXT”, тест упадет, как и ожидается.

Если getByRole и getByLabel не работают на вашей странице

Одна из причин, почему рекомендуется использовать user-first локаторы – это раннее выявление проблем с доступностью сайта. Ведь если вы заметили, что такие селекторы не работают на вашей странице – значит для многих элементов не заданы роли и метки, либо они одинаковые у всех элементов.

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

Безусловно, это должно положить начало обсуждению между разработчиками и тестировщиками об улучшении структуры страниц, что позволит наладить тестирование и улучшить качество для всех пользователей.

Работа с несколькими совпадающими элементами

Если локатор находит сразу несколько элементов, например, getByRole('button') нашел две кнопки, то вы получите ошибку, которая будет выглядеть примерно так:

Error: locator.click: Error: strict mode violation: getByRole('button', { name: 'click' }) resolved to 2 elements:

Чтобы решить эту проблему можно указать позицию элемента или применить фильтрацию.

Выбор элемента по позиции

Когда мы впервые сталкиваемся с этой ошибкой, самым простым решением будет просто указать позицию в списке. Проще всего выбрать первый результат, используя функцию .first() :

await page.getByRole('button').first().click();

Если вы хотите указать точную позицию в списке, используйте функцию .nth():

await page.getByRole('button').nth(3).click();

Функция .nth() использует нумерацию с нуля, поэтому .nth(3) выберет четвертый элемент в результатах.

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

Чтобы действительно быть уверенным, что вы указываете на правильный элемент в динамическом списке, выполните небольшую фильтрацию элементов.

Фильтрация элементов в Playwright

Если мы представим себе интерфейс интернет-магазина со множеством товаров, из которых доступны только некоторые, то станет понятно, что выбор элемента по позиции может быть ненадежным.

Если посмотреть на структуру HTML-кода страницы, то мы увидим, что товары – это элементы списка. В этом случае селектор, который сначала отфильтрует доступные товары, а затем уже найдет кнопку и нажмет ее, будет выглядеть следующим образом:

const button = page.getByRole('listitem')
.filter({ hasText: 'available' })
.getByRole('button', { name: 'buy' });
await button.click();

Теперь этот тест упадет только тогда, когда все товары будут распроданы, т.е. на странице не будет ни одного доступного товара с кнопкой “Buy Now”.

Лучшие практики для работы с локаторами

Для локаторов не существует универсальных правил, но есть несколько рекомендации:

  • Избегайте деталей реализации: Используйте локаторы, которые отражают действия пользователя, а не HTML-структуру.
  • Используйте встроенные локаторы: Такие как getByRole, getByText и подобные для повышения стабильности и поддержки тестов.
  • Используйте тестовые идентификаторы: В сложных сценариях это упрощает поиск элементов и повышает надежность тестов.

Выбор правильных локаторов – ключ к созданию стабильных и поддерживаемых тестов в Playwright. Использование user-first локаторов повышает надежность тестов и соответствует хорошим практикам разработки.

Перевод статьи «How to Work with Selectors in Playwright».

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *