106 lines
4.3 KiB
JavaScript
106 lines
4.3 KiB
JavaScript
// Rôle : vérifie la lisibilité et la zone cliquable des événements calendrier denses.
|
|
/* global getComputedStyle */
|
|
import { test, expect } from "@playwright/test";
|
|
import { resetSokkoStorage } from "./helpers/storage.js";
|
|
|
|
async function seedCalendars(page) {
|
|
await resetSokkoStorage(page);
|
|
await page.evaluate(async () => {
|
|
const db = await import("/src/utils/indexedDbStorage.js");
|
|
const dateKey = (day) => {
|
|
const now = new Date();
|
|
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
};
|
|
await db.setToolboxSnapshot([{
|
|
id: "calendar-layout",
|
|
name: "Calendar layout",
|
|
moduleColumns: 1,
|
|
modules: [
|
|
{ id: "week", type: "calendar", title: "Week" },
|
|
{ id: "month", type: "calendar", title: "Month" }
|
|
]
|
|
}], {}, {
|
|
"calendar-layout:week": {
|
|
initialized: true,
|
|
viewMode: "week",
|
|
events: [30, 60, 120].map((duration, index) => ({
|
|
id: `week-${index}`, title: `Raid ${duration}`, dayIndex: index,
|
|
startMinutes: 600, endMinutes: 600 + duration, color: "violet"
|
|
}))
|
|
},
|
|
"calendar-layout:month": {
|
|
initialized: true,
|
|
viewMode: "month",
|
|
events: [0, 1, 2, 3].map((index) => ({
|
|
id: `month-${index}`, title: `Event ${index}`, repeat: "none",
|
|
startDate: dateKey(index < 3 ? 10 : 20), endDate: dateKey(index < 3 ? 10 : 20),
|
|
color: "gold"
|
|
}))
|
|
}
|
|
});
|
|
});
|
|
await page.goto("/#/toolbox/calendar-layout");
|
|
await page.reload();
|
|
}
|
|
|
|
async function expectTitleFits(surface) {
|
|
await surface.scrollIntoViewIfNeeded();
|
|
const box = await surface.evaluate((element) => {
|
|
const button = element.querySelector("button");
|
|
const title = button.querySelector("strong");
|
|
const outer = element.getBoundingClientRect();
|
|
const inner = button.getBoundingClientRect();
|
|
const text = title.getBoundingClientRect();
|
|
const style = getComputedStyle(element);
|
|
return {
|
|
height: outer.height,
|
|
buttonHeight: inner.height,
|
|
titleHeight: text.height,
|
|
topSpace: text.top - outer.top - parseFloat(style.borderTopWidth),
|
|
bottomSpace: outer.bottom - parseFloat(style.borderBottomWidth) - text.bottom,
|
|
buttonTopSpace: text.top - inner.top,
|
|
buttonBottomSpace: inner.bottom - text.bottom
|
|
};
|
|
});
|
|
expect(box.titleHeight).toBeGreaterThan(0);
|
|
expect(box.buttonHeight).toBeGreaterThanOrEqual(box.height - 2);
|
|
for (const gap of [box.topSpace, box.bottomSpace, box.buttonTopSpace, box.buttonBottomSpace]) {
|
|
expect(gap, JSON.stringify(box)).toBeGreaterThanOrEqual(-0.5);
|
|
}
|
|
}
|
|
|
|
for (const width of [1440, 390]) {
|
|
test(`dense calendar titles fit and remain editable at ${width}px`, async ({ page }, testInfo) => {
|
|
await page.setViewportSize({ width, height: 900 });
|
|
await page.clock.setFixedTime(new Date("2026-09-01T12:00:00Z"));
|
|
const errors = [];
|
|
page.on("pageerror", (error) => errors.push(error.message));
|
|
await seedCalendars(page);
|
|
const week = page.locator('[data-module-type="calendar"]').first();
|
|
const month = page.locator('[data-module-type="calendar"]').last();
|
|
await expect(week.locator(".calendar-event")).toHaveCount(3);
|
|
await expect(month.locator(".calendar-month-bar")).toHaveCount(4);
|
|
for (const size of ["xs", "sm", "md"]) {
|
|
const surface = week.locator(`.calendar-event[data-size="${size}"]`);
|
|
await expect(surface).toHaveCount(1);
|
|
await expectTitleFits(surface);
|
|
}
|
|
for (const size of ["xs", "sm"]) {
|
|
const surfaces = month.locator(`.calendar-month-bar[data-size="${size}"]`);
|
|
await expect(surfaces).toHaveCount(size === "xs" ? 3 : 1);
|
|
for (const surface of await surfaces.all()) await expectTitleFits(surface);
|
|
}
|
|
await month.screenshot({ path: testInfo.outputPath("month.png") });
|
|
await week.screenshot({ path: testInfo.outputPath("week.png") });
|
|
for (const [module, selector, title] of [
|
|
[week, ".calendar-event", "Raid 30"],
|
|
[month, ".calendar-month-bar", "Event 0"]
|
|
]) {
|
|
const button = module.locator(`${selector}[data-size="xs"] button`).first();
|
|
await button.click();
|
|
await expect(module.getByLabel("Titre", { exact: true })).toHaveValue(title);
|
|
await module.getByRole("button", { name: "Annuler", exact: true }).click();
|
|
}
|
|
expect(errors).toEqual([]);
|
|
});
|
|
}
|