Локаторы являются одним из ключевых элементов UI‑автоматизации. От того, насколько устойчиво тест находит нужный элемент, зависит стабильность всего тестового набора. Несмотря на кажущуюся простоту, выбор правильного локатора часто становится самым критичным и самым недооценённым аспектом автоматизации.
В этой статье мы разберём общую концепцию локаторов, критерии их качества и ограничения классических подходов. Затем рассмотрим, как Playwright переосмыслил эту философию.
Что такое локатор?
Локатор — это способ, с помощью которого инструмент UI‑автоматизации находит элемент на странице. Проще говоря, локатор описывает как определить, к какому именно элементу должен обратиться тест.
С технической точки зрения локатор представляет собой селектор, который связывает тест с конкретным элементом DOM. Однако сам по себе локатор не является просто строкой или условием поиска. Это часть контракта между тестом и интерфейсом. Если локатор выбран корректно, тест остаётся стабильным даже при изменениях вёрстки. Если нет, то тест начинает падать из‑за малейших изменений на странице.
В разных инструментах локаторы строятся по‑разному. Есть привычные нам CSS и XPath, а так же более высокоуровневые варианты, ориентированные на реальные пользовательские взаимодействия. Именно разница в этом подходе определяет, насколько удобными и надёжными будут тесты.
Критерии хорошего локатора
Хороший локатор должен оставаться стабильным, понятным и предсказуемым в долгосрочной перспективе. Есть несколько критериев, по которым можно определить, насколько хорош выбор локатора. И если он им соответствует, значит вероятность того, что тесты не будут ломаться при малейших изменениях интерфейса гораздо выше.
Вот эти критерии, давайте рассмотрим их подробнее:
1. Стабильность. Локатор не должен зависеть от деталей верстки, которые часто меняются. Старайтесь выбирать те локаторы, которые меньше всего будут привязаны к структуре DOM. То есть не используйте всякие порядковые индексы, технические классы и тому подобное.
2. Читаемость. Локатор должен быть понятен человеку, который читает тест. Простые, самодокументируемые локаторы проще ревьюить и гораздо легче поддерживать.
3. Однозначность. Базовая штука. Хороший локатор должен находить ровно один конкретный элемент, иначе сами понимаете, обратная ситуация приведет к нестабильным тестам и непредсказуемому поведению.
4. Устойчивость к изменениям в UI. Тест не должен ломаться (в идеальном мире), когда ваш фронт поменяет классы, порядок элементов или вложенность. Особенно не рекомендуется использовать локаторы, которые основаны на позициях (типа nth‑child) или сложных XPath.
5. Приближенность к пользовательскому поведению. Лучшие локаторы опираются на то, как интерфейс воспринимает пользователь (текст, подписи, роли, id и так далее).
Понятное дело, что не получится использовать эти критерии, если у вас плохо выстроен фронт и кроме технических классов то и привязаться не к чему. Однако когда есть возможность сделать хорошо, лучше ей воспользоваться.
Критерии, приведенные выше, универсальны и применимы к любому инструменту. Однако в случае Playwright многие из них становятся стандартом за счет особенного подхода к работе с локаторами в этом инструменте.
Классические виды локаторов и проблемы классического подхода
Перед тем как рассматривать особенности философии Playwright, давайте вспомним и кратко пробежимся по списку классических локаторов, а также по проблемам, которые мы встречаем при их использовании.
В традиционных инструментах UI‑автоматизации типа Selenium, WebdriverIO, Cypress и так далее локаторы в основном строятся вокруг структуры DOM.
Наиболее распространённые типы выглядят следующим образом:
1. CSS‑селекторы. Это, пожалуй, самый гибкий и самый популярный способ поиска элементов. Позволяет обращаться к элементам по тегам, классам, атрибутам, вложенности. Однако такой селектор легко ломается, если меняется структура страницы или классы, которые не были предназначены для тестирования.
driver.findElement(By.cssSelector(".btn-primary"));
driver.findElement(By.cssSelector("input[name='email']"));
driver.findElement(By.cssSelector("div.card > button.action"));
2. XPath. Очень мощный язык поиска элементов, позволяющий двигаться по DOM‑дереву в любом направлении. При этом очень часто мы встречаем ситуации, когда они оказываются слишком длинными, слишком хрупкими и плохо читаемыми. Опять же, даже небольшие изменения верстки могут сделать их невалидными.
driver.findElement(By.xpath("//button[text()='Submit']"));
driver.findElement(By.xpath("//div[@class='card']//a[contains(@href,'details')]"));
driver.findElement(By.xpath("//ul/li[3]/span"));
3. Частные случаи CSS‑селекторов, типа ID, name, class, а также data‑атрибуты. ID, name, class обычно самые простые и надежные варианты, если они конечно есть. Но в реальных проектах с уникальными ID могут быть проблемы, а классы часто генерируются автоматически.
driver.findElement(By.id("login-button"));
driver.findElement(By.name("username"));
driver.findElement(By.className("input-error"));
Если же говорить про data‑атрибуты, то это, конечно, самый современный и самый рекомендуемый подход. Они добавляются специально для тестов и практически не меняются при редизайнах, что сразу дает им +100 к надежности. Однако это работает хорошо только в том случае, когда команда действительно дисциплинированно их добавляет:)
driver.findElement(By.cssSelector("[data-testid='user-avatar']"));
driver.findElement(By.cssSelector("[data-qa='submit']"));
Давайте теперь обобщим собранные нами проблемы. Что нам мешает в классическом подходе? Сильная зависимость от DOM, нестабильность локаторов, их плохая читаемость и неоднозначность, а еще… Сюда же относятся ручные ожидания. Потому что пусть локатор и нашел элемент, но он нашел его как узел DOM и никак не учитывает его состояние. Ручные ожидания в таком случае становятся единственным способом стабилизировать локатор.
Философия локаторов в плейрайт
Playwright предлагает иной взгляд на работу с локаторами по сравнению с классическими инструментами.
Если Selenium и аналогичные фреймворки рассматривают локатор как способ найти узел в DOM, то Playwright решает эти проблемы фундаментально иначе. Локатор здесь является полноценным объектом, который сам отслеживает состояние элемента и гарантирует, что взаимодействие произойдёт только когда элемент доступен. Локатор автоматически ждёт появления, видимости и стабильности элемента, а также корректно работает при динамическом изменении DOM, например, в реактивных фреймворках вроде React или Vue.
Таким образом отпадает необходимость в явных wait и дополнительных проверках состояния. Кроме того, Playwright предлагает семантические локаторы, ориентированные на поведение пользователя. Вместо привязки к структуре DOM или классам можно использовать роли, видимый текст или ARIA‑атрибуты. Это делает локаторы более устойчивыми к изменениям интерфейса и позволяет писать тесты, которые отражают реальные сценарии взаимодействия пользователя, а не внутреннюю структуру страницы.
Типы локаторов
После того как мы обсудили философию локаторов в Playwright и их отличие от классических инструментов, перейдём к конкретным типам и тому, как их использовать на практике. Здесь мы рассматриваем те локаторы, которые чаще всего применяются в реальных тестах, с кратким пояснением и примером на Java.
1. getByRole()
Идеален для интерактивных элементов — кнопок, ссылок, чекбоксов — и ориентирован на ARIA‑роли и видимое имя элемента. Позволяет создавать устойчивые и семантически корректные тесты.
//находим кнопку логина и выполняем клик
Locator loginButton = page.getByRole(AriaRole.BUTTON, new GetByRoleOptions().setName("Login"));
loginButton.click();
2. getByText()
Используется для поиска элементов по видимому тексту. Удобно для заголовков, сообщений и ссылок, где текст является ключевым идентификатором.
//кликаем по элементу с искомым текстом
Locator welcomeText = page.getByText("Welcome back!");
welcomeText.click();
3. getByLabel()
Связывает поле формы с его <label>, что упрощает работу с input‑полями и textarea без привязки к структуре DOM.</label>
//вводим текст в поле, связаннное с соответствующим лейблом
Locator emailInput = page.getByLabel("Email");
emailInput.fill("user@example.com");
4. getByPlaceholder()
Поиск по placeholder в input‑полях. Полезно, когда <label> отсутствует или placeholder достаточно информативен для идентификации поля.</label>
//вводим текст в поле с соответствующим плейсхолдером
Locator searchInput = page.getByPlaceholder("Search products");
searchInput.fill("Laptop");
5. getByTestId()
Поиск по кастомным тестовым атрибутам (data‑testid). Считается самым стабильным вариантом для автоматизации, так как не зависит от классов, структуры или других визуальных атрибутов.
//кликаем по кнопке с нужным data-testid
Locator submitButton = page.getByTestId("submit-button");
submitButton.click();
6. Ну и, понятное дело, CSS и XPath
Playwright также поддерживает классические селекторы, полезные для специфических случаев, когда user‑facing локаторы недоступны.
//находим кнопку внутри карточки с помощью CSS и ссылку по XPath
Locator cardButton = page.locator("div.card > button.primary"); // CSS
Locator detailsLink = page.locator("xpath=//a[contains(@href,'details')]"); // XPath
Расширенные возможности локаторов
Playwright не ограничивается простым поиском элементов — локаторы здесь ведут себя как объекты, которые можно фильтровать, комбинировать и переиспользовать. Это позволяет писать более выразительные и устойчивые тесты, а также избегать хрупкости, характерной для классических инструментов. Основная идея в том, что локатор не привязан к моменту поиска: он «живой», и состояние элемента проверяется динамически в момент взаимодействия.
Цепочка локаторов
Позволяет искать вложенные элементы относительно уже найденного родителя. Это улучшает читаемость и стабильность кода, так как поиск привязан к более локальному контексту, а не ко всей странице.
//находим заголовок внутри карточки
Locator cardTitle = page.locator("div.card").locator("h2.title");
System.out.println(cardTitle.textContent());
Фильтрация по тексту и другим критериям
Playwright позволяет добавлять условия к локатору, чтобы сузить поиск и сделать его семантически значимым. Это снижает вероятность случайных совпадений и делает тесты более понятными.
//кликаем по карточке товара с нужным текстом
Locator selectedItem = page.locator("div.item").filter(new Locator.FilterOptions().setHasText("MacBook"));
selectedItem.click();
Выбор конкретного элемента из коллекции
Иногда на странице несколько элементов, подходящих под локатор. Playwright позволяет явно выбрать первый, последний или элемент по индексу, что уменьшает вероятность ошибок и повышает предсказуемость теста.
//выбираем первый и последний элемент из списка кнопок
Locator firstButton = page.locator("button").first();
Locator lastButton = page.locator("button").last();
Работа с iframe
В классических инструментах работа с iframe часто требует переключения контекста вручную. В Playwright для этого есть frameLocator, который позволяет напрямую работать с элементами внутри iframe, сохраняя преимущества «живого» локатора.
//кликаем по кнопке внутри iframe
Locator frameButton = page.frameLocator("#payment-frame").getByRole(AriaRole.BUTTON, new GetByRoleOptions().setName("Pay"));
frameButton.click();
Заключение
На этом моя статья подходит к концу, надеюсь, она была полезной и интересной для вас.
Локаторы являются фундаментом UI‑автоматизации, и понимание их принципов работы помогает писать тесты более стабильными, читаемыми и близкими к реальному пользовательскому взаимодействию. Playwright с его «умными» локаторами существенно упрощает работу с динамическим интерфейсом и снижает количество ошибок, связанных с синхронизацией и изменением DOM.
Если после этой статьи у вас появилось понимание, как правильно использовать локаторы и какие преимущества они дают в современных UI‑тестах, значит, я достигла своей цели. Если же чего‑то не хватило, пожалуйста, напишите об этом в комментариях!
Если вы хотите глубже разобраться в том, как проектируются устойчивые автотесты — от синтаксиса Java до UI- и API-автоматизации — это как раз та база, которую даёт программа Java QA Engineer. Basic. Курс помогает выстроить фундаментальные навыки автоматизации и понять практическую работу с фреймворками, которые лежат в основе современных QA-подходов.
Чтобы узнать больше о формате обучения и познакомиться с преподавателями, приходите на бесплатные демо-уроки:
27 ноября: «SQL для QA без страха: как тестировщик перестал бояться и полюбил SQL?». Записаться
4 декабря: «Как Java-тестировщику работать с Git и GitHub?». Записаться
17 декабря: «От Postman до Jenkins: автоматизация API-тестов и отчётность в TestIT». Записаться