Интеграционное тестирование Flatpickr в JavaScript ориентировано на проверку взаимодействия компонента выбора даты с DOM, событиями пользовательского интерфейса, внешними библиотеками и состоянием приложения. В отличие от юнит-тестов, где изолируется логика, здесь проверяется целостное поведение календаря в реальной среде браузера или его эмуляции, включая рендеринг, реакцию на ввод, синхронизацию состояния и корректную работу API-интерфейсов.
Flatpickr, будучи UI-компонентом, тесно связан с DOM-структурой и пользовательскими событиями, поэтому интеграционные тесты должны учитывать асинхронность обновлений, особенности событийной модели и возможные побочные эффекты при повторной инициализации экземпляра.
Основная цель интеграционного тестирования заключается в проверке того, что:
change, open, close,
onChange вызываются в ожидаемой последовательности;Flatpickr имеет внутреннее состояние экземпляра, доступное через объект, возвращаемый функцией инициализации. Это состояние используется в тестах как точка контроля поведения.
Интеграционные тесты Flatpickr обычно выполняются в одном из следующих окружений:
Выбор зависит от глубины тестирования. Для проверки пользовательских сценариев предпочтительнее браузерное окружение.
Базовая подготовка DOM-элемента:
beforeEach(() => {
document.body.innerHTML = `
<input id="datepicker" type="text" />
`;
});
Инициализация Flatpickr:
import flatpickr from "flatpickr";
let instance;
beforeEach(() => {
instance = flatpickr("#datepicker", {
enableTime: true,
dateFormat: "Y-m-d H:i",
});
});
afterEach(() => {
instance.destroy();
});
Ключевой момент — обязательное уничтожение экземпляра после теста, иначе возможно накопление обработчиков событий.
Инициализация является первым критическим сценарием. Проверяется создание DOM-структуры и привязка к input.
test("инициализация Flatpickr создает экземпляр", () => {
expect(instance).toBeDefined();
expect(instance.input).toBe(document.querySelector("#datepicker"));
});
Дополнительно проверяется создание pop-up контейнера:
test("создается календарный контейнер", () => {
const calendar = document.querySelector(".flatpickr-calendar");
expect(calendar).not.toBeNull();
});
В интеграционных сценариях важно учитывать, что календарь может быть скрыт до первого открытия.
Flatpickr активно модифицирует DOM: добавляет классы, атрибуты, inline-стили. Это требует проверки состояния элементов после действий пользователя.
Пример теста открытия календаря:
test("календарь открывается по фокусу", () => {
instance.open();
const calendar = document.querySelector(".flatpickr-calendar");
expect(calendar.classList.contains("open")).toBe(true);
});
Закрытие:
test("календарь закрывается", () => {
instance.open();
instance.close();
const calendar = document.querySelector(".flatpickr-calendar");
expect(calendar.classList.contains("open")).toBe(false);
});
Важно учитывать, что Flatpickr может использовать CSS-классы для управления видимостью, а не удалять DOM-элементы.
Одним из ключевых сценариев является проверка связи между UI и значением input.
test("выбор даты обновляет значение input", () => {
instance.setDate("2026-01-01");
const input = document.querySelector("#datepicker");
expect(input.value).toBe("2026-01-01 00:00");
});
Если включено время, необходимо проверять полный формат даты.
Также важно тестировать обратный сценарий:
test("изменение input обновляет состояние Flatpickr", () => {
const input = document.querySelector("#datepicker");
input.value = "2026-02-10";
input.dispatchEvent(new Event("input", { bubbles: true }));
expect(instance.selectedDates.length).toBeGreaterThan(0);
});
Flatpickr предоставляет набор callback-событий, которые являются важной частью интеграции с приложением.
Пример тестирования onChange:
test("onChange вызывается при выборе даты", () => {
const mock = jest.fn();
instance.set("onChange", mock);
instance.setDate("2026-03-01");
expect(mock).toHaveBeenCalled();
});
Проверка порядка событий:
test("события вызываются в правильном порядке", () => {
const order = [];
instance.set("onOpen", () => order.push("open"));
instance.set("onClose", () => order.push("close"));
instance.open();
instance.close();
expect(order).toEqual(["open", "close"]);
});
При тестировании событий важно учитывать асинхронность UI-обновлений
и использовать requestAnimationFrame или
setTimeout при необходимости.
Повторная инициализация может приводить к дублированию обработчиков,
если не вызывается destroy.
test("повторная инициализация не создает дубликатов", () => {
instance.destroy();
instance = flatpickr("#datepicker");
instance.setDate("2026-04-01");
const input = document.querySelector("#datepicker");
expect(input.value).toContain("2026-04-01");
});
Критически важно проверять отсутствие утечек DOM-элементов:
test("после destroy DOM очищается", () => {
instance.destroy();
const calendar = document.querySelector(".flatpickr-calendar");
expect(calendar).toBeNull();
});
Flatpickr часто используется внутри HTML-форм, поэтому тестирование поведения при submit является обязательным.
test("значение Flatpickr отправляется в форме", () => {
document.body.innerHTML = `
<form>
<input id="datepicker" name="date" />
<button type="submit">Send</button>
</form>
`;
const fp = flatpickr("#datepicker");
fp.setDate("2026-05-01");
const form = document.querySelector("form");
const formData = new FormData(form);
expect(formData.get("date")).toBe("2026-05-01");
});
Также проверяется корректность работы с HTML5 validation и required-полями.
Flatpickr часто используется как внешний контрол внутри UI-фреймворков. Интеграционные тесты должны учитывать жизненный цикл компонентов.
Пример для React-подобной логики:
test("Flatpickr инициализируется при mount компонента", () => {
render(<DateInput />);
const input = screen.getByRole("textbox");
expect(input).toBeInTheDocument();
const calendar = document.querySelector(".flatpickr-calendar");
expect(calendar).not.toBeNull();
});
Особое внимание уделяется:
Для стабилизации тестов часто мокируются:
jest.useFakeTimers);beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
Это позволяет детерминированно тестировать анимации и задержки открытия/закрытия календаря.
Интеграционные тесты должны включать нестандартные сценарии:
Пример:
test("не позволяет выбрать дату раньше minDate", () => {
instance.set("minDate", "2026-01-10");
instance.setDate("2026-01-01");
expect(instance.selectedDates[0]).not.toBeDefined();
});
Flatpickr поддерживает изменение настроек на лету:
test("изменение конфигурации влияет на поведение", () => {
instance.set("enableTime", true);
instance.setDate("2026-06-01 10:00");
expect(document.querySelector("#datepicker").value).toContain(":");
});
Особое внимание уделяется тому, как изменения конфигурации влияют на уже открытый календарь.
При использовании Redux, Zustand или аналогичных систем важно проверять синхронизацию состояния:
Типичный сценарий:
test("синхронизация с внешним state", () => {
store.setState({ date: "2026-07-01" });
render(<DatePicker />);
expect(document.querySelector("#datepicker").value).toContain("2026-07-01");
});