В веб-тестировании элементы интерфейса, связанные с выбором даты,
часто оказываются сложными для автоматизации. Датапикеры и календари
реализуются с использованием HTML, CSS и JavaScript разными способами:
от стандартных <input type="date"> до сложных
кастомных компонентов на Angular, React или других фреймворках.
Protractor, как инструмент для E2E тестирования Angular-приложений,
предоставляет гибкие возможности для работы с такими элементами, но
требует внимательного подхода.
Стандартные HTML-даты Простейший вариант:
<input type="date">. Эти элементы имеют встроенный
календарь браузера. Основные особенности:
YYYY-MM-DD..sendKeys()
или через element.sendKeys('2026-01-07').Кастомные календарные виджеты Часто используются библиотеки вроде Angular Material, jQuery UI Datepicker, React-Datepicker. Особенности:
value, а обновляться через JavaScript.Комбинированные элементы Некоторые приложения используют сочетание текстового поля и кнопки для открытия календаря. Поле может быть заблокировано для ручного ввода, что требует взаимодействия именно с календарной сеткой.
const dateInput = element(by.css('input[type="date"]'));
await dateInput.clear();
await dateInput.sendKeys('2026-01-07');
Особенности:
value.Для кастомных датапикеров нужно эмулировать действия пользователя:
const calendarButton = element(by.css('.calendar-toggle'));
await calendarButton.click();
const desiredDay = element(by.cssContainingText('.day', '7'));
await desiredDay.click();
При автоматизации календарей часто полезно создавать универсальные функции, способные выбирать любую дату:
async function selectDate(dateString) {
const [year, month, day] = dateString.split('-').map(Number);
const calendarButton = element(by.css('.calendar-toggle'));
await calendarButton.click();
const monthDropdown = element(by.css('.month-selector'));
await monthDropdown.element(by.cssContainingText('option', monthNames[month - 1])).click();
const yearDropdown = element(by.css('.year-selector'));
await yearDropdown.element(by.cssContainingText('option', year.toString())).click();
const dayElement = element(by.cssContainingText('.day', day.toString()));
await dayElement.click();
}
Календарные виджеты часто подгружаются динамически. Для стабильных тестов необходимы ожидания:
const EC = protractor.ExpectedConditions;
const calendar = element(by.css('.calendar-container'));
await calendarButton.click();
await browser.wait(EC.visibilityOf(calendar), 5000, 'Календарь не появился');
const dayToSelect = calendar.element(by.cssContainingText('.day', '7'));
await browser.wait(EC.elementToBeClickable(dayToSelect), 5000);
await dayToSelect.click();
ExpectedConditions предотвращает ошибки при попытке
взаимодействия с ещё не загруженными элементами.browser.sleep(), чтобы тесты оставались быстрыми и
стабильными.const startDate = element(by.cssContainingText('.day', '5'));
const endDate = element(by.cssContainingText('.day', '10'));
await startDate.click();
await endDate.click();
Даты вне текущего месяца Некоторые виджеты отображают дни соседних месяцев. Нужно правильно идентифицировать элемент и при необходимости переключить месяц.
Проверка выбранной даты После выбора даты важно проверить, что значение корректно:
const inputValue = await dateInput.getAttribute('value');
expect(inputValue).toEqual('2026-01-07');
by.cssContainingText или by.model для
Angular-элементов.Эти подходы позволяют создавать стабильные и поддерживаемые тесты для любых датапикеров и календарей в приложениях на Angular с использованием Protractor, минимизируя зависимость от конкретной реализации интерфейса.