← Назад к вопросам

Какие знаешь селекторы?

2.0 Middle🔥 271 комментариев
#Selenium и UI автоматизация#Фреймворки тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные типы селекторов в веб-автоматизации

В контексте автоматизации тестирования веб-приложений, селекторы — это механизмы для точного нахождения и взаимодействия с элементами 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")
    

Критерии выбора "хорошего" селектора

При выборе селектора я руководствуюсь следующими принципами, которые выработал за годы практики:

  1. Уникальность и стабильность: Селектор должен однозначно идентифицировать элемент даже после незначительных правок вёрстки. Предпочтение отдаю id и data-атрибутам (например, data-qa, data-testid), которые добавляют специально для тестов.
  2. Производительность: В современных браузерах CSS Selectors обычно работают быстрее, чем сложные XPath. Простые селекторы по id или class — самые быстрые.
  3. Читаемость и поддерживаемость: Селектор должен быть понятен коллегам. //div[1]/section[2]/div/div[3]/button — это антипаттерн.
  4. Защита от изменений: Стараюсь избегать селекторов, зависящих от:
    *   Абсолютных позиций в 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 > всё остальное. Ключ — найти баланс между устойчивостью, скоростью и простотой поддержки.