Как найти элемент по селектору в Selenium?

«Как найти элемент по селектору в Selenium?» — вопрос из категории Selenium и Selenide, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В автоматизации UI-тестов на Selenium WebDriver поиск элементов — фундаментальная операция. Я всегда стараюсь использовать стабильные и читаемые селекторы.

Основные методы поиска в Selenium WebDriver (Java):

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

WebDriver driver = new ChromeDriver();

// Найти первый элемент
WebElement element = driver.findElement(By.cssSelector("button.submit"));

// Найти список всех элементов
List<WebElement> elements = driver.findElements(By.cssSelector(".product-item"));

Практика использования CSS-селекторов:

  • По ID: By.cssSelector("#login-button")
  • По классу: By.cssSelector(".btn-primary")
  • По атрибуту: By.cssSelector("input[data-testid='username-field']")
  • Комбинации: By.cssSelector("form#auth > input[type='text']")

Явные ожидания (обязательная практика): Перед поиском элемента нужно дождаться его готовности. Использую WebDriverWait.

import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

// Ждем появления элемента и сразу находим его
WebElement dynamicElement = wait.until(
    ExpectedConditions.presenceOfElementLocated(By.cssSelector(".ajax-loaded-content"))
);

// Или ждем кликабельности
WebElement clickableButton = wait.until(
    ExpectedConditions.elementToBeClickable(By.cssSelector("button:enabled"))
);
clickableButton.click();

Стратегии для сложных случаев:

  1. Динамические ID: Избегаю селекторов вида div[id^='generated']. Вместо этого ищу по стабильным data-атрибутам, которые прошу добавлять разработчиков (например, data-qa="user-profile").
  2. Тенистый DOM (Shadow DOM): Для работы с веб-компонентами нужно проникать внутрь shadow root.
  3. Фреймы: Перед поиском элемента внутри фрейма необходимо переключить контекст драйвера: driver.switchTo().frame("frame-name");.