Lot U3b : le test d'abord, rouge sur a47aed0 — C44 (ouverture.spec.ts) : les réglages de la formule ouverts, en tête du document et depuis une version (« cet article »), à 1360 × 900, à 1024 × 768 et sur Pixel 7, chaque cellule du tableau des cinq crans, en-têtes compris, dans le panneau, son texte dans sa cellule, ni le tableau, ni le panneau, ni la page ne défilent de côté. Rouge à 1360 et à 1024 (le tableau défile, 412 et 421 px pour 394 ; « Voix pour » et ses cinq chiffres hors du panneau), vert sur téléphone

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-03 22:45:59 +01:00
co-authored by Claude Opus 5.5
parent a47aed0f72
commit c626f1aded
+75 -1
View File
@@ -1,4 +1,4 @@
import { expect, test, type Page } from '@playwright/test';
import { devices, expect, test, type Page } from '@playwright/test';
import { DOC, seedsInForce, shot, signIn, TEST_DOC } from './helpers';
// Lot U3 (Yvv, 2026-11-03, vers 20 h 38 et avant 20 h 44): the rules of operation leave the votes
@@ -255,3 +255,77 @@ test('C43 — les informations de fonctionnement là où elles servent : le vote
await expect(inForce).toContainText('Si plusieurs versions atteignent leur seuil, celle qui a la marge la plus large entre en vigueur.');
await shot(page, 'c43-3-ordre-rival');
});
/**
* What of the table of the five levels is not seen whole in the settings panel: a header or a
* cell that leaves the table or the panel, a text that leaves its cell; the table, the panel or
* the page scrolled sideways to reach it. Empty when every column reads in full.
*/
async function hiddenInSettings(page: Page): Promise<string[]> {
return page.evaluate(() => {
const panel = document.querySelector('aside.panel');
const scroll = panel?.querySelector('.settings .scroll');
const table = scroll?.querySelector('table');
const body = panel?.querySelector('.body');
if (!panel || !scroll || !table || !body) return ['pas de tableau dans le panneau'];
const faults: string[] = [];
for (const [el, what] of [
[scroll, 'le tableau'],
[body, 'le panneau'],
[document.documentElement, 'la page'],
] as const) {
if (el.scrollWidth > el.clientWidth + 1) faults.push(`${what} défile de côté (${el.scrollWidth} > ${el.clientWidth})`);
}
const p = panel.getBoundingClientRect();
const s = scroll.getBoundingClientRect();
const left = Math.max(p.left, s.left, 0);
const right = Math.min(p.right, s.right, document.documentElement.clientWidth);
const cols = table.querySelectorAll('thead th').length;
if (cols !== 6) faults.push(`${cols} colonnes au lieu de 6`);
for (const cell of table.querySelectorAll('th, td')) {
const name = (cell.textContent ?? '').replace(/\s+/g, ' ').trim();
const c = cell.getBoundingClientRect();
const range = document.createRange();
range.selectNodeContents(cell);
const r = range.getBoundingClientRect();
if (c.left < left - 0.5 || c.right > right + 0.5)
faults.push(`« ${name} » : sa cellule sort du panneau (${Math.round(c.left)}–${Math.round(c.right)} hors de ${Math.round(left)}–${Math.round(right)})`);
if (r.left < c.left - 0.5 || r.right > c.right + 0.5) faults.push(`« ${name} » : son texte sort de sa cellule`);
}
return faults;
});
}
test('C44 — les réglages de la formule se lisent en entier : chaque colonne des cinq crans et chaque en-tête dans le panneau, sur bureau et sur téléphone', async ({ page, browser }) => {
// Lot U3b (03/11): on a desktop, the panel cut the table on the right, « Voix pour » out of sight.
await signIn(page, 'Chiara');
const g = await (await page.request.get('/api/groups/monnaie-libre')).json();
const d = await (await page.request.get(`/api/docs/${g.docs[0].id}`)).json();
const e1 = d.units.find((u: { code: string }) => u.code === 'E1');
const version: string = e1.proposals.find((p: { seedProposal?: boolean }) => p.seedProposal).id;
const phone = await browser.newContext({ ...devices['Pixel 7'], locale: 'fr-FR' });
const screens: { name: string; tag: string; page: Page; size?: { width: number; height: number } }[] = [
{ name: 'bureau 1360 × 900', tag: 'bureau-1360', page, size: { width: 1360, height: 900 } },
{ name: 'bureau 1024 × 768', tag: 'bureau-1024', page, size: { width: 1024, height: 768 } },
{ name: 'téléphone (Pixel 7)', tag: 'telephone', page: await phone.newPage() },
];
for (const screen of screens) {
const p = screen.page;
if (screen.size) await p.setViewportSize(screen.size);
if (p !== page) await signIn(p, 'Chiara');
// From the head of the document (the usual turnout), then from a version (« cet article » in its row).
for (const from of ['tete', 'version']) {
await p.goto(from === 'tete' ? `${DOC}?onglet=reglages` : `${DOC}?onglet=reglages&version=${version}`);
const panel = p.locator('aside.panel');
await expect(panel.getByRole('heading', { name: 'Réglages de la formule' })).toBeVisible();
await expect(panel.locator('table tbody tr')).toHaveCount(5);
if (from === 'version') await expect(panel.locator('tr.current th')).toContainText('cet article');
await expect(panel.locator('thead th').last()).toHaveText('Voix pour');
await panel.locator('table').scrollIntoViewIfNeeded();
// Soft: every screen is looked at, and the report names each one where the table is cut.
expect.soft(await hiddenInSettings(p), `${screen.name}, ${from === 'tete' ? 'en tête du document' : 'depuis une version'}`).toEqual([]);
await shot(p, `c44-${screen.tag}-${from}`);
}
}
await phone.close();
});