Работа с раскрывающимися строками

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


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

В Protractor элементы страницы описываются через объекты ElementFinder. Для работы с select-элементами стандартного HTML чаще всего используется комбинация element и by.

Пример выбора по видимому тексту:

const dropdown = element(by.id('country'));
const option = dropdown.element(by.cssContainingText('option', 'Россия'));
option.click();
  • by.cssContainingText('option', 'Россия') ищет <option> с текстом “Россия”.
  • Метод click() активирует выбранный элемент.

Выбор по значению осуществляется через атрибут value:

dropdown.element(by.css('option[value="RU"]')).click();

Выбор по индексу требует получения списка всех опций и обращения к нужной позиции:

dropdown.all(by.tagName('option')).get(2).click(); // Третья опция

Получение текущего выбранного значения

Для проверки состояния раскрывающегося списка важно уметь извлечь текущий выбор. Используется метод getAttribute('value') или getText():

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

Работа с кастомными dropdown

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

const dropdown = element(by.css('.custom-dropdown'));
dropdown.click(); // Открыть список

const option = element(by.cssContainingText('.dropdown-item', 'Москва'));
option.click(); // Выбрать элемент
  • Сначала происходит клик по контейнеру для раскрытия списка.
  • Затем по тексту выбирается нужная опция.

Для надёжности стоит использовать ожидания (ExpectedConditions), чтобы дождаться появления элементов:

const EC = protractor.ExpectedConditions;
const option = element(by.cssContainingText('.dropdown-item', 'Москва'));
browser.wait(EC.visibilityOf(option), 5000);
option.click();
  • EC.visibilityOf(option) гарантирует, что элемент видим и доступен для клика.

Обход сложных сценариев

  1. Выбор нескольких опций в мультиселектах:
const options = dropdown.all(by.tagName('option'));
options.each((elem) => {
    elem.getText().then((text) => {
        if (text === 'Россия' || text === 'Канада') {
            elem.click();
        }
    });
});
  1. Динамическое появление опций при вводе текста (autocomplete):
const input = element(by.id('city-input'));
input.sendKeys('Мо');

const suggestion = element(by.cssContainingText('.autocomplete-item', 'Москва'));
browser.wait(EC.elementToBeClickable(suggestion), 5000);
suggestion.click();
  • Для автозаполнения важно дождаться появления подсказок и убедиться в их кликабельности.

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

  • Использовать browser.wait перед кликом на элементы, чтобы избежать ошибок из-за асинхронной загрузки.
  • Предпочтительно работать с текстом (getText()) или атрибутами (value) вместо координатных кликов.
  • Для кастомных dropdown проверять наличие скрытых контейнеров, которые могут блокировать клик.
  • В сложных случаях использовать JavaScript исполнение:
browser.executeScript("arguments[0].click();", option.getWebElement());

Это позволяет кликать на элемент, даже если стандартный click() не срабатывает.


Работа с селекторами и повторное использование кода

Для поддерживаемости тестов создаются функции-обертки:

function selectDropdownByText(dropdownElement, text) {
    return dropdownElement.element(by.cssContainingText('option', text)).click();
}

function selectCustomDropdownByText(dropdownElement, optionText) {
    dropdownElement.click();
    const option = element(by.cssContainingText('.dropdown-item', optionText));
    return browser.wait(EC.elementToBeClickable(option), 5000).then(() => option.click());
}
  • Такие функции позволяют сократить дублирование и упростить поддержку больших тестовых наборов.
  • Можно расширять функции, добавляя выбор по индексу, значению или проверку наличия опции перед выбором.

Работа с раскрывающимися списками в Protractor требует внимательности к структуре элементов и динамическому поведению страницы. Использование комбинации ElementFinder, ожиданий и вспомогательных функций обеспечивает надёжность и читаемость автотестов.