sokko-g/e2e/calendar-layout.spec.js
Shinuwa 2bff58f08c
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s
Fix compact calendar events and stabilize E2E execution
2026-09-11 08:52:20 +02:00

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([]);
});
}