forked from yvv/decision
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:
@@ -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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user