Как написать способ isElementPresent?qa-56

Основные подходы к проверке наличия элемента

1. Стандартная реализация с try-catch

public boolean isElementPresent(By locator) {
    try {
        driver.findElement(locator);
        return true;
    } catch (NoSuchElementException e) {
        return false;
    }
}

Преимущества:

  • Простота реализации
  • Не требует явных ожиданий
  • Работает в любых условиях

Недостатки:

  • Нет встроенного ожидания
  • Может давать ложные отрицательные результаты для динамических элементов

2. Реализация с явным ожиданием

public boolean isElementPresent(By locator, long timeoutSeconds) {
    try {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(timeoutSeconds));
        wait.until(ExpectedConditions.presenceOfElementLocated(locator));
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

Преимущества:

  • Учитывает время загрузки элементов
  • Более надежна для динамического контента
  • Гибкость в настройке таймаута

Недостатки:

  • Дольше выполняется при отсутствии элемента
  • Требует обработки дополнительного исключения

3. Проверка через список элементов

public boolean isElementPresent(By locator) {
    return !driver.findElements(locator).isEmpty();
}

Особенности:

  • Не бросает исключение при отсутствии элемента
  • Возвращает false если элементов нет
  • Быстрее чем try-catch подход

4. Универсальный метод с параметрами

public boolean isElementPresent(By locator, boolean checkVisibility, long timeout) {
    try {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(timeout));

        if (checkVisibility) {
            wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
        } else {
            wait.until(ExpectedConditions.presenceOfElementLocated(locator));
        }

        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

Лучшие практики реализации

  1. Выбор подходящего условия:

    • presenceOfElementLocated - элемент в DOM
    • visibilityOfElementLocated - элемент видимый
    • elementToBeClickable - элемент кликабельный
  2. Оптимальный таймаут:

    // Хорошая практика - выносить в конфигурацию
    long defaultTimeout = Long.parseLong(Config.getProperty("element.timeout.seconds"));
    
  3. Логирование:

    public boolean isElementPresent(By locator) {
        try {
            driver.findElement(locator);
            log.debug("Element found: " + locator);
            return true;
        } catch (NoSuchElementException e) {
            log.debug("Element not found: " + locator);
            return false;
        }
    }
    

Расширенные варианты

Проверка с JavaScript

public boolean isElementPresentJS(By locator) {
    JavascriptExecutor js = (JavascriptExecutor)driver;
    return (Boolean)js.executeScript(
        "return document.querySelector(arguments[0]) !== null",
        locator.toString().replace("By.cssSelector: ", ""));
}

Проверка с учетом iframe

public boolean isElementPresentInFrames(By locator) {
    try {
        driver.findElement(locator);
        return true;
    } catch (NoSuchElementException e) {
        // Поиск во всех iframe
        for (WebElement frame : driver.findElements(By.tagName("iframe"))) {
            driver.switchTo().frame(frame);
            boolean present = isElementPresent(locator);
            driver.switchTo().defaultContent();
            if (present) return true;
        }
        return false;
    }
}

Ошибки при реализации

  1. Смешение presence и visibility:

    • Элемент может быть в DOM, но не виден
    • Видимый элемент всегда присутствует в DOM
  2. Игнорирование StaleElementReferenceException:

    // Нужно учитывать
    catch (StaleElementReferenceException e) {
        return false;
    }
    
  3. Использование Thread.sleep():

    • Вместо явных ожиданий
    • Снижает производительность тестов

Резюмируем

  • Базовый вариант - findElements().isEmpty() для простых случаев
  • Надежный вариант - с WebDriverWait и ExpectedConditions
  • Оптимальный подход - комбинировать методы под конкретные нужды
  • Дополнительные проверки - видимость, кликабельность, доступность
  • Универсальное решение - параметризованный метод с настройками

Профессиональный совет: Создайте класс ElementUtils с набором статических методов для разных сценариев проверки элементов (isPresent, isVisible, isClickable и т.д.) для удобного повторного использования в проекте.