В веб-тестировании работа с элементами выбора даты (date pickers)
требует особого подхода, так как эти компоненты часто реализуются
нестандартно через JavaScript, CSS и динамические DOM-структуры.
Protractor предоставляет инструменты для взаимодействия с такими
элементами, позволяя управлять как простыми HTML
<input type="date">, так и кастомными календарными
виджетами.
Date picker может быть реализован:
<input type="date">.Для взаимодействия с ними важно корректно выбрать элемент:
const dateInput = element(by.css('input#date-of-birth'));
Для кастомных календарей выбор может включать отдельные элементы:
const calendarIcon = element(by.css('.calendar-icon'));
const calendarWidget = element(by.css('.calendar-widget'));
const dayCell = calendarWidget.element(by.cssContainingText('.day', '15'));
<input type="date">Нативные поля даты поддерживают прямое присваивание значения через
sendKeys, но значение должно быть в формате
yyyy-mm-dd:
await dateInput.sendKeys('2026-01-15');
Если необходимо очистить поле перед вводом новой даты:
await dateInput.clear();
await dateInput.sendKeys('2026-01-15');
Кастомные date pickers требуют симуляции кликов по элементам
интерфейса, так как прямой ввод в input может быть
недоступен.
await calendarIcon.click();
const monthSelect = calendarWidget.element(by.css('.month-select'));
await monthSelect.element(by.cssContainingText('option', 'Январь')).click();
const yearSelect = calendarWidget.element(by.css('.year-select'));
await yearSelect.element(by.cssContainingText('option', '2026')).click();
const day = calendarWidget.element(by.cssContainingText('.day', '15'));
await day.click();
const selectedDate = await dateInput.getAttribute('value');
expect(selectedDate).toEqual('2026-01-15');
Кастомные виджеты часто обновляют DOM динамически, поэтому важно использовать ожидания:
const EC = protractor.ExpectedConditions;
await browser.wait(EC.visibilityOf(calendarWidget), 5000, 'Календарь не появился');
await browser.wait(EC.elementToBeClickable(dayCell), 5000, 'День не кликабельный');
Использование ExpectedConditions предотвращает ошибки
типа ElementNotInteractableError.
Иногда требуется выбрать дату относительно текущей, например, через определённое количество дней:
const targetDate = new Date();
targetDate.setDate(targetDate.getDate() + 7);
const dayToSelect = targetDate.getDate().toString();
const monthToSelect = targetDate.toLocaleString('default', { month: 'long' });
const yearToSelect = targetDate.getFullYear().toString();
await calendarIcon.click();
await calendarWidget.element(by.cssContainingText('.month-select option', monthToSelect)).click();
await calendarWidget.element(by.cssContainingText('.year-select option', yearToSelect)).click();
await calendarWidget.element(by.cssContainingText('.day', dayToSelect)).click();
Кастомные date pickers, созданные с использованием сторонних библиотек (jQuery UI Datepicker, Angular Material, Bootstrap Datepicker), имеют свои особенности:
<td> с классами ui-datepicker-day.<mat-datepicker-toggle> и последующая работа с
mat-calendar..datepicker-days и выбор дня по CSS-классу
.day.Для всех библиотек основной подход одинаков: открыть календарь → выбрать месяц/год → выбрать день → проверить результат.
id,
data-test атрибуты предпочтительнее CSS-классов, так как
классы часто меняются.ExpectedConditions вместо
browser.sleep().async function selectDate(dateInput, day, month, year) {
await dateInput.click();
const widget = element(by.css('.calendar-widget'));
await widget.element(by.cssContainingText('.month-select option', month)).click();
await widget.element(by.cssContainingText('.year-select option', year)).click();
await widget.element(by.cssContainingText('.day', day)).click();
}
Эффективная работа с date pickers в Protractor требует комбинирования правильного выбора элементов, учёта асинхронного поведения DOM и понимания структуры конкретного календарного виджета. Это позволяет создавать стабильные и воспроизводимые тесты для любых реализаций date picker на веб-страницах.