Опциональные шаги тестирования

WebdriverIO предоставляет гибкий подход к автоматизации тестирования, позволяя создавать тесты с условными и опциональными шагами, что особенно полезно при сложных сценариях, где выполнение некоторых действий зависит от состояния страницы или внешних условий.

Использование условных операторов

В JavaScript ключевую роль играют конструкции if, else и тернарный оператор. В контексте WebdriverIO это позволяет реализовать логику, где определённые действия выполняются только при выполнении условий:

const isLoginButtonVisible = await $('#login-button').isDisplayed();

if (isLoginButtonVisible) {
    await $('#login-button').click();
} else {
    console.log('Кнопка входа не видна на странице');
}

Ключевой момент: метод isDisplayed() возвращает true или false, что позволяет безопасно определять возможность взаимодействия с элементом.

Опциональные шаги через try/catch

Иногда элемент может отсутствовать на странице, и попытка взаимодействия с ним вызовет ошибку. Для таких случаев используют блок try/catch:

try {
    await $('#promo-banner').click();
} catch (error) {
    console.log('Баннер отсутствует, пропускаем шаг');
}

Преимущество: тест продолжает выполнение даже при отсутствии необязательного элемента, что повышает устойчивость сценариев.

Условные ожидания

WebdriverIO предлагает методы ожидания состояния элементов, которые можно использовать для опциональных шагов:

const banner = await $('#promo-banner');

if (await banner.isDisplayed()) {
    await banner.click();
}

Здесь метод isDisplayed() выступает фильтром, предотвращающим попытку клика по несуществующему элементу.

Для более сложных сценариев применяют ожидания с таймаутом:

const exists = await $('#optional-element').waitForExist({ timeout: 3000, reverse: false });

if (exists) {
    await $('#optional-element').click();
}

waitForExist возвращает true, если элемент появился в DOM, и false при таймауте, что идеально подходит для динамических страниц.

Использование функций-обёрток

Для повторяющихся опциональных шагов удобно создавать функции-обёртки, которые инкапсулируют логику проверки и взаимодействия:

async function clickIfVisible(selector) {
    const element = await $(selector);
    if (await element.isDisplayed()) {
        await element.click();
        return true;
    }
    return false;
}

// Применение
await clickIfVisible('#optional-button');

Преимущество: повышается читаемость тестов и уменьшается дублирование кода.

Асинхронные цепочки с опциональными действиями

WebdriverIO работает на основе асинхронных операций, поэтому можно комбинировать несколько опциональных шагов в цепочку:

if (await $('#step1').isDisplayed()) {
    await $('#step1').click();
    if (await $('#step2').isDisplayed()) {
        await $('#step2').click();
    }
}

Такой подход позволяет строить сложные сценарии с вложенными условиями без прерывания теста.

Логирование и контроль выполнения

При опциональных шагах важно логировать пропущенные действия, чтобы понимать, почему шаг не был выполнен:

if (await $('#newsletter-popup').isDisplayed()) {
    await $('#newsletter-popup .close').click();
} else {
    console.log('Попап отсутствует — пропуск шага');
}

Это облегчает диагностику при анализе результатов тестов.

Интеграция с Page Object

В паттерне Page Object опциональные шаги удобно реализовать внутри методов страницы:

class HomePage {
    get promoBanner() { return $('#promo-banner'); }

    async closePromoIfExists() {
        if (await this.promoBanner.isDisplayed()) {
            await this.promoBanner.click();
        }
    }
}

// Использование в тесте
const homePage = new HomePage();
await homePage.closePromoIfExists();

Такой подход позволяет сократить дублирование логики и сделать тесты более читаемыми и поддерживаемыми.

Опциональные проверки состояния

Помимо кликов, можно реализовать проверки состояния элементов как опциональные шаги:

const isErrorVisible = await $('#error-message').isDisplayed();

if (isErrorVisible) {
    const text = await $('#error-message').getText();
    console.log(`Сообщение об ошибке: ${text}`);
}

Такой подход помогает собирать данные о состоянии интерфейса без прерывания выполнения теста.

Итоговая структура опциональных шагов

  1. Проверка состояния элемента (isDisplayed, isExisting).
  2. Выполнение действия при положительном результате (click, setValue).
  3. Логирование или пропуск шага при отрицательном результате.
  4. Использование функций-обёрток или Page Object для повторяющихся действий.
  5. Обработка ошибок через try/catch для динамических элементов.

Опциональные шаги делают тесты гибкими и устойчивыми к изменяющемуся UI, обеспечивая корректное выполнение сценариев даже в нестабильных условиях.