Выбор опций из dropdown

Dropdown (выпадающие списки) — один из наиболее часто встречающихся элементов веб-приложений. В автоматизированном тестировании с помощью Protractor важно уметь корректно взаимодействовать с ними, включая выбор опций, проверку выбранного значения и обработку динамических списков.

Определение элементов dropdown

В Protractor элементы dropdown обычно представлены HTML-тегом <select> с набором <option> внутри. Первый шаг — корректное определение элементов:

const dropdown = element(by.id('dropdownId'));
const options = dropdown.all(by.tagName('option'));
  • element(by.id('dropdownId')) — поиск контейнера dropdown по уникальному идентификатору.
  • all(by.tagName('option')) — получение всех опций внутри выпадающего списка.

Альтернативные локаторы могут использовать by.css или by.model, если используется Angular:

const dropdown = element(by.model('selectedValue'));

Выбор опции по тексту

Для выбора опции по видимому тексту применяют метод element.all().filter() или element(by.cssContainingText()).

dropdown.element(by.cssContainingText('option', 'Опция 2')).click();

Здесь:

  • by.cssContainingText('option', 'Опция 2') — ищет <option> с текстом «Опция 2».
  • click() — выбирает данную опцию.

Для динамических списков, где текст может меняться, можно использовать фильтрацию:

options.filter(async (option) => {
    const text = await option.getText();
    return text === 'Опция 2';
}).first().click();
  • filter возвращает массив всех элементов, соответствующих условию.
  • first() берёт первый совпавший элемент, после чего вызывается click().

Выбор опции по значению атрибута

Иногда необходимо выбрать элемент по значению атрибута value, а не по тексту:

dropdown.element(by.css('option[value="2"]')).click();
  • Подходит для случаев, когда текст может отображаться по-разному, но атрибут value фиксирован.

Получение выбранной опции

Чтобы проверить, какая опция была выбрана:

const selectedOption = dropdown.element(by.css('option:checked'));
selectedOption.getText().then(text => {
    console.log('Выбрана опция:', text);
});
  • option:checked — CSS-селектор для текущей выбранной опции.
  • getText() возвращает видимый текст опции.

Работа с нестандартными dropdown

Некоторые веб-приложения используют кастомные dropdown, которые не являются <select> элементами, а представляют собой <div> или <ul> с пунктами <li>. В таких случаях необходимо использовать клики на контейнер и элементы списка:

const dropdown = element(by.css('.custom-dropdown'));
dropdown.click(); // открытие списка
const optionToSelect = element(by.cssContainingText('.dropdown-item', 'Опция 2'));
optionToSelect.click();

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

  • Сначала нужно открыть dropdown через click().
  • Опции могут подгружаться динамически, поэтому иногда требуется ожидание появления элемента с ExpectedConditions:
const EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(optionToSelect), 5000);
optionToSelect.click();

Выбор случайной опции

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

options.count().then(async count => {
    const randomIndex = Math.floor(Math.random() * count);
    await options.get(randomIndex).click();
});
  • count() возвращает количество опций.
  • Math.floor(Math.random() * count) генерирует индекс случайной опции.

Советы по стабильности тестов с dropdown

  1. Ожидание элементов: использовать browser.wait() для появления dropdown и опций.
  2. Использование уникальных локаторов: id, model, data-атрибуты предпочтительнее сложных CSS-селекторов.
  3. Асинхронность: методы Protractor возвращают промисы, поэтому важно использовать await или then.
  4. Проверка выбранного значения: всегда полезно сверять, что выбранная опция совпадает с ожидаемой, чтобы тесты были надёжными.

Примеры комплексного сценария

Выбор опции по тексту с проверкой результата:

const dropdown = element(by.id('dropdownId'));
const desiredText = 'Опция 3';
const option = dropdown.element(by.cssContainingText('option', desiredText));

option.click();

const selectedOption = dropdown.element(by.css('option:checked'));
expect(selectedOption.getText()).toEqual(desiredText);

Выбор опции по значению с ожиданием:

const dropdown = element(by.id('dropdownId'));
const option = dropdown.element(by.css('option[value="3"]'));

const EC = protractor.ExpectedConditions;
browser.wait(EC.elementToBeClickable(option), 5000);
option.click();

const selectedOption = dropdown.element(by.css('option:checked'));
expect(selectedOption.getAttribute('value')).toEqual('3');

Эти подходы покрывают большинство сценариев работы с dropdown в Protractor, обеспечивая стабильность тестов и корректное взаимодействие с элементами интерфейса.