Какие знаешь селекторы?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Основные типы селекторов в веб-автоматизации
В контексте автоматизации тестирования веб-приложений, селекторы — это механизмы для точного нахождения и взаимодействия с элементами DOM (Document Object Model). Я классифицирую их по приоритету использования, надежности и производительности.
1. Селекторы по ID (#elementId)
Наиболее предпочтительный и надежный вариант, так как id должен быть уникальным в рамках страницы.
<input type="text" id="username">
# Selenium WebDriver (Python)
element = driver.find_element(By.ID, "username")
2. Селекторы по CSS-классам (.className)
Эффективны для элементов с общим стилем или поведением. Часто используются, но могут быть неуникальными.
<button class="btn btn-primary submit">
# По одному классу
element = driver.find_element(By.CLASS_NAME, "btn-primary")
# По комбинации классов (CSS Selector)
element = driver.find_element(By.CSS_SELECTOR, ".btn.btn-primary.submit")
3. Селекторы по имени тега (tagName)
Полезны для общих операций (например, сбор всех ссылок или полей ввода).
links = driver.find_elements(By.TAG_NAME, "a")
4. Селекторы по атрибуту ([attribute='value'])
Гибкий метод, особенно когда у элемента нет id или уникального класса.
<input name="email" data-qa="login-email">
# Использование CSS Selector
element = driver.find_element(By.CSS_SELECTOR, "[name='email']")
# Или поиск по XPath
element = driver.find_element(By.XPATH, "//input[@data-qa='login-email']")
5. XPath (XML Path Language)
Мощный язык запросов для навигации по DOM. Я разделяю его на два типа:
Абсолютный XPath (начинается с /html)
Хрупкий, сильно зависит от структуры страницы. Не рекомендуется к использованию.
/html/body/div[2]/form/input[1]
Относительный XPath (начинается с //)
Гораздо устойчивее. Позволяет искать элементы по любому атрибуту, тексту или позиции.
# По атрибуту
driver.find_element(By.XPATH, "//input[@type='submit']")
# По тексту (для ссылок, кнопок)
driver.find_element(By.XPATH, "//button[text()='Войти']")
# По частичному совпадению текста
driver.find_element(By.XPATH, "//a[contains(text(), 'Выход')]")
# Сложные условия
driver.find_element(By.XPATH, "//div[@class='container']//input[starts-with(@id, 'user_')]")
6. CSS Selectors (как язык)
Более производительный и читаемый, чем XPath, в большинстве современных браузеров. Поддерживает сложные запросы.
# Дочерний элемент
driver.find_element(By.CSS_SELECTOR, "div.form > input")
# Элемент с несколькими атрибутами
driver.find_element(By.CSS_SELECTOR, "input[type='text'][required]")
# Псевдоклассы (например, первый дочерний)
driver.find_element(By.CSS_SELECTOR, "ul.menu > li:first-child")
7. Специализированные селекторы для Selenium/Playwright
By.LINK_TEXT/By.PARTIAL_LINK_TEXT: Только для гиперссылок (<a>).driver.find_element(By.LINK_TEXT, "Точный текст ссылки") driver.find_element(By.PARTIAL_LINK_TEXT, "часть текста")By.NAME: Для атрибутаname(часто используется в формах).driver.find_element(By.NAME, "password")
Критерии выбора "хорошего" селектора
При выборе селектора я руководствуюсь следующими принципами, которые выработал за годы практики:
- Уникальность и стабильность: Селектор должен однозначно идентифицировать элемент даже после незначительных правок вёрстки. Предпочтение отдаю
idи data-атрибутам (например,data-qa,data-testid), которые добавляют специально для тестов. - Производительность: В современных браузерах CSS Selectors обычно работают быстрее, чем сложные XPath. Простые селекторы по
idилиclass— самые быстрые. - Читаемость и поддерживаемость: Селектор должен быть понятен коллегам.
//div[1]/section[2]/div/div[3]/button— это антипаттерн. - Защита от изменений: Стараюсь избегать селекторов, зависящих от:
* Абсолютных позиций в DOM (`div[3]`, `:nth-child(4)`).
* Изменчивых текстов (особенно на мультиязычных сайтах).
* Классов, используемых только для стилизации (`.col-md-4`, `.text-red-500`), так как они часто меняются.
Практический совет
В реальных проектах я настоятельно рекомендую использовать Page Object Model (POM). Все селекторы должны быть вынесены в классы Page Objects в виде констант или методов, что позволяет централизованно править их при изменении UI.
class LoginPage:
# Локаторы хранятся отдельно
USERNAME_FIELD = (By.ID, "username")
PASSWORD_FIELD = (By.CSS_SELECTOR, "[data-test='password-input']")
SUBMIT_BUTTON = (By.XPATH, "//button[@type='submit']")
def __init__(self, driver):
self.driver = driver
def login(self, username, password):
self.driver.find_element(*self.USERNAME_FIELD).send_keys(username)
self.driver.find_element(*self.PASSWORD_FIELD).send_keys(password)
self.driver.find_element(*self.SUBMIT_BUTTON).click()
Итог: Идеального селектора на все случаи нет. Выбор зависит от конкретного элемента и контекста. Моя иерархия предпочтений: ID > data-атрибуты (через CSS/XPath) > уникальные классы (CSS) > относительный XPath > всё остальное. Ключ — найти баланс между устойчивостью, скоростью и простотой поддержки.