78 lines
3.7 KiB
JavaScript
78 lines
3.7 KiB
JavaScript
|
|
// © 2026 TechnoLibre (http://www.technolibre.ca)
|
|||
|
|
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
|||
|
|
|
|||
|
|
// L'avancement d'une génération dans un vrai moteur de rendu (§ 5.10) : la
|
|||
|
|
// barre de progression se voit. Le composant est monté seul, dans un
|
|||
|
|
// conteneur de largeur fixée ; la barre se lit par son rôle, son
|
|||
|
|
// remplissage par son premier enfant, les couleurs par leurs jetons, dans
|
|||
|
|
// les deux thèmes.
|
|||
|
|
//
|
|||
|
|
// Le projet navigateur emploie expect, et test et describe de Vitest
|
|||
|
|
// (§ 14.8).
|
|||
|
|
import '../jetons.css';
|
|||
|
|
import { flushSync, mount, unmount } from 'svelte';
|
|||
|
|
import { afterEach, describe, expect, test } from 'vitest';
|
|||
|
|
import { creerHorlogePilotee } from '../../application/horloge.js';
|
|||
|
|
import { TABLES_APPLICATION } from '../../application/libelles.js';
|
|||
|
|
import { creerTraduction } from '../../application/traduction.js';
|
|||
|
|
import { couleurDeJeton } from '../../../test/navigateur/captures.js';
|
|||
|
|
import { composantes, contraste, sousTheme } from '../../../test/navigateur/rendu.js';
|
|||
|
|
import { TABLES_INTERFACE } from '../libelles.js';
|
|||
|
|
import Avancement from './Avancement.svelte';
|
|||
|
|
|
|||
|
|
const { t } = creerTraduction([...TABLES_APPLICATION, ...TABLES_INTERFACE]);
|
|||
|
|
|
|||
|
|
const montes = [];
|
|||
|
|
afterEach(() => {
|
|||
|
|
for (const { composant, conteneur } of montes.splice(0)) {
|
|||
|
|
unmount(composant);
|
|||
|
|
conteneur.remove();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Monte Avancement dans un conteneur de 600 px.
|
|||
|
|
function monter(props) {
|
|||
|
|
const conteneur = document.createElement('div');
|
|||
|
|
conteneur.style.width = '600px';
|
|||
|
|
document.body.prepend(conteneur);
|
|||
|
|
const contexte = new Map([
|
|||
|
|
['t', t],
|
|||
|
|
['horloge', creerHorlogePilotee()],
|
|||
|
|
]);
|
|||
|
|
const composant = mount(Avancement, { target: conteneur, props, context: contexte });
|
|||
|
|
flushSync();
|
|||
|
|
montes.push({ composant, conteneur });
|
|||
|
|
return conteneur;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
describe('l’avancement se voit (§ 5.10)', () => {
|
|||
|
|
test('la barre occupe la largeur de son conteneur ; son remplissage, au prorata, se peint de la teinte de l’action à 3:1 sur la piste, dans les deux thèmes', async () => {
|
|||
|
|
const conteneur = monter({ fait: 250, total: 1000, annuler: () => {} });
|
|||
|
|
const barre = conteneur.querySelector('[role="progressbar"]');
|
|||
|
|
expect(barre.getAttribute('aria-valuenow')).toBe('250');
|
|||
|
|
expect(barre.getBoundingClientRect().width).toBeGreaterThanOrEqual(0.9 * conteneur.getBoundingClientRect().width);
|
|||
|
|
const plein = barre.firstElementChild;
|
|||
|
|
expect(plein.getBoundingClientRect().width / barre.clientWidth).toBeCloseTo(0.25, 2);
|
|||
|
|
expect(barre.getBoundingClientRect().height).toBeGreaterThanOrEqual(8);
|
|||
|
|
for (const theme of ['clair', 'sombre']) {
|
|||
|
|
await sousTheme(theme, async () => {
|
|||
|
|
const remplissage = composantes(getComputedStyle(plein).backgroundColor);
|
|||
|
|
const piste = composantes(getComputedStyle(barre).backgroundColor);
|
|||
|
|
expect(remplissage.join(), theme).toBe(couleurDeJeton('--couleur-action-fond').join());
|
|||
|
|
expect(piste.join(), theme).toBe(couleurDeJeton('--couleur-carte-fond-sourd').join());
|
|||
|
|
expect(contraste(remplissage, piste), theme).toBeGreaterThanOrEqual(3);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('le compte se lit en mots au-dessus de la barre, et « Annuler la génération » la suit', () => {
|
|||
|
|
const conteneur = monter({ fait: 250, total: 1000, annuler: () => {} });
|
|||
|
|
const barre = conteneur.querySelector('[role="progressbar"]');
|
|||
|
|
const texte = [...conteneur.querySelectorAll('p')].find((p) => p.textContent === t('generation.avancement.texte', { fait: 250, total: 1000 }));
|
|||
|
|
expect(texte).toBeDefined();
|
|||
|
|
expect(texte.getBoundingClientRect().bottom).toBeLessThanOrEqual(barre.getBoundingClientRect().top);
|
|||
|
|
const annuler = conteneur.querySelector('[data-commande="annuler"]');
|
|||
|
|
expect(annuler.getBoundingClientRect().top).toBeGreaterThanOrEqual(barre.getBoundingClientRect().bottom);
|
|||
|
|
});
|
|||
|
|
});
|