Lot U : contrôles repris sans les affaiblir (C3, C4, C6, C19 à C21, C23 à C26, C34, M1) ; CONTROLES.md (C35 à C37) ; retouches vues aux captures (ligne d'ordre discrète, en-tête plus court sur téléphone, liste à poignées)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+28
-14
@@ -1,5 +1,5 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { ALICE, chain, CHARLIE, deepRow, DOC, person, seedsInForce, shot, signed, signIn, TEST_DOC, VOTE_ACCOUNT, wallet } from './helpers';
|
||||
import { ALICE, chain, CHARLIE, deepRow, DOC, person, seedsInForce, shot, signed, signIn, TEST_DOC, unfold, VOTE_ACCOUNT, wallet } from './helpers';
|
||||
|
||||
// Lot B — the vote (Yvv, 2026-10-30): unfolded under the article, grouped in a
|
||||
// basket, and on the Ğ1 chain where the electorate is the web of trust. The chain
|
||||
@@ -21,7 +21,7 @@ test('C21 — le vote déplié sous l’article : ton vote, les totaux, le seuil
|
||||
await expect(toggle).toHaveAttribute('aria-controls', (await fold.getAttribute('id')) ?? '');
|
||||
// How far the threshold is: the water, the totals, the votes asked and those missing.
|
||||
await expect(fold.getByRole('img', { name: /Niveau : \d+ % du seuil/ })).toBeVisible();
|
||||
await expect(fold.getByText(/^Seuil : \d+ voix pour$/)).toBeVisible();
|
||||
await expect(fold.getByText(/^\d+ oui sur \d+ votants? pour passer$/)).toBeVisible();
|
||||
await expect(fold.getByText(/^Il manque \d+ voix pour\.$/)).toBeVisible();
|
||||
await expect(fold.getByText("Tu n'as pas voté sur cette version.")).toBeVisible();
|
||||
await expect(fold.getByText('0 pour · 0 contre')).toBeVisible();
|
||||
@@ -119,8 +119,9 @@ test('C23 — le vote par la chaîne Ğ1 : un geste, confirmé par l’indexeur
|
||||
await expect(panel.getByText("Rien dans le panier pour l'instant.")).toBeVisible();
|
||||
await panel.getByRole('button', { name: 'Fermer le panneau' }).click();
|
||||
|
||||
// Under the seed proposal: her vote, from the chain, and the totals.
|
||||
const e1 = deepRow(page, 'Unicité du compte');
|
||||
// Under the seed proposal, at the head of the text: her vote, from the chain, and the totals.
|
||||
const seed = (title: string) => page.locator('section.text article.unit', { hasText: title }).getByRole('button', { name: 'Le vote' });
|
||||
const e1 = seed('Unicité du compte');
|
||||
await e1.click();
|
||||
const fold1 = page.getByRole('region', { name: 'Le vote de « Unicité du compte »' });
|
||||
await expect(fold1.locator('.voted')).toHaveText('Ton vote : pour · inscrit sur la chaîne Ğ1');
|
||||
@@ -128,7 +129,7 @@ test('C23 — le vote par la chaîne Ğ1 : un geste, confirmé par l’indexeur
|
||||
|
||||
// The last one stands, in the order of the chain: a « contre » included first, but seen late
|
||||
// by the indexer, never overrides the withdrawal included after it.
|
||||
const e2 = deepRow(page, 'Réciprocité');
|
||||
const e2 = seed('Réciprocité');
|
||||
await e2.click();
|
||||
const fold2 = page.getByRole('region', { name: 'Le vote de « Réciprocité »' });
|
||||
await control('hide');
|
||||
@@ -155,8 +156,8 @@ test('C23 — le vote par la chaîne Ğ1 : un geste, confirmé par l’indexeur
|
||||
// Without a wallet in the browser: Ğecko, a link and a QR code; the page waits for the chain.
|
||||
const other = await person(browser, 'Maëlle');
|
||||
await other.goto(DOC);
|
||||
await deepRow(other, "Raison d'être").click();
|
||||
await other.locator('ul.deep section.fold').getByRole('button', { name: 'Pour', exact: true }).click();
|
||||
await other.locator('section.text article.unit', { hasText: "Raison d'être" }).getByRole('button', { name: 'Le vote' }).click();
|
||||
await other.locator('section.text section.fold').getByRole('button', { name: 'Pour', exact: true }).click();
|
||||
const sheet = other.getByRole('dialog', { name: 'Voter avec ton portefeuille Ğ1' });
|
||||
await expect(sheet.getByText("Aucun portefeuille n'est branché à ce navigateur", { exact: false })).toBeVisible();
|
||||
await sheet.getByRole('button', { name: 'Passer par Ğecko' }).click();
|
||||
@@ -191,13 +192,12 @@ test('C24 — sans compte de vote, le vote par la chaîne est fermé et le dit ;
|
||||
await page.goto(DOC);
|
||||
await expect(page.getByRole('button', { name: /^Voter en lot/ })).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Voter cette section' })).toHaveCount(0);
|
||||
await page.locator('ul.deep button.row').first().click();
|
||||
const fold = page.locator('ul.deep section.fold');
|
||||
await page.locator('section.text article.unit').first().getByRole('button', { name: 'Le vote' }).click();
|
||||
const fold = page.locator('section.text section.fold');
|
||||
await expect(fold.getByText("Le vote par la chaîne Ğ1 n'est pas encore ouvert : le compte qui reçoit les votes reste à créer.", { exact: false })).toBeVisible();
|
||||
await expect(fold.getByRole('button', { name: 'Pour', exact: true })).toHaveCount(0);
|
||||
// The totals and the threshold stay in sight.
|
||||
// Raison d'être, level 2, the quorum 12 (ADR 0013).
|
||||
await expect(fold.getByText('Seuil : 9 voix pour')).toBeVisible();
|
||||
// The totals and how far it is stay in sight: Raison d'être, level 2, the quorum 12 (ADR 0013).
|
||||
await expect(fold.getByText('9 oui sur 12 votants pour passer', { exact: true })).toBeVisible();
|
||||
await fold.getByText('Ton vote ne se montre à personne', { exact: false }).scrollIntoViewIfNeeded();
|
||||
await shot(page, '6-vote-ferme');
|
||||
// The basket, opened by its address, says the vote is closed — never « Tes votes comptent dès l'envoi ».
|
||||
@@ -239,11 +239,16 @@ test('C34 — la chaîne fermée, Monnaie libre vote quand même : le vote simul
|
||||
const before = await version(page, title);
|
||||
expect(before.vote).toMatchObject({ way: 'server', open: true, simulated: true });
|
||||
await page.goto(DOC);
|
||||
// The basket is there, without a wallet: the vote leaves by the server.
|
||||
// The basket is there, without a wallet: the vote leaves by the server, marked « vote simulé ».
|
||||
await expect(page.getByRole('button', { name: /^Voter en lot/ })).toBeVisible();
|
||||
await expect(page.locator('header.head .tag', { hasText: 'vote simulé' })).toBeVisible();
|
||||
await unfold(page);
|
||||
await deepRow(page, title).click();
|
||||
const fold = page.getByRole('region', { name: `Le vote de « ${title} »` });
|
||||
await fold.getByRole('button', { name: 'Contre', exact: true }).click();
|
||||
// Said simulated at once, never « enregistré » (review of M6).
|
||||
await expect(page.getByText('Vote simulé.', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Vote enregistré.')).toHaveCount(0);
|
||||
await expect(page.getByRole('dialog', { name: 'Voter avec ton portefeuille Ğ1' })).toHaveCount(0);
|
||||
await expect(fold.locator('.voted')).toHaveText(/^Ton vote : contre/);
|
||||
await expect(fold.getByText(`0 pour · ${before.p.tally.against + 1} contre`)).toBeVisible();
|
||||
@@ -257,10 +262,19 @@ test('C34 — la chaîne fermée, Monnaie libre vote quand même : le vote simul
|
||||
const after = await version(page, title);
|
||||
expect(after.p.myVoteState).toBe('simulated');
|
||||
expect(after.p.tallySimulated.against).toBe(before.p.tallySimulated.against + 1);
|
||||
// The basket too says « simulé », never « enregistrés » (review of M6): « contre » again, one line.
|
||||
await page.getByRole('button', { name: /^Voter en lot/ }).click();
|
||||
const basket = page.locator('aside.panel');
|
||||
await basket.getByRole('group', { name: `Ton choix pour « ${title} »` }).getByRole('button', { name: 'Contre' }).click();
|
||||
await basket.getByRole('button', { name: 'Voter (1)' }).click();
|
||||
await expect(page.getByText('1 vote simulé.', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('enregistré', { exact: false })).toHaveCount(0);
|
||||
await basket.getByRole('button', { name: 'Fermer le panneau' }).click();
|
||||
// In her ballots: simulated, counted for her session, never a block of the chain.
|
||||
await page.goto('/bulletins');
|
||||
const ballot = page.locator('li.ballot').first();
|
||||
await expect(ballot.locator('.state')).toHaveText("Simulé : compté pour « Sacha » jusqu'à l'ouverture de la chaîne Ğ1");
|
||||
// Until a human act erases the simulated votes — never « until the chain opens » (review of M6).
|
||||
await expect(ballot.locator('.state')).toHaveText('Simulé : compté pour « Sacha » tant que les votes simulés ne sont pas effacés');
|
||||
await expect(ballot.getByText('bloc', { exact: false })).toHaveCount(0);
|
||||
} finally {
|
||||
// The next controls need the chain.
|
||||
|
||||
Reference in New Issue
Block a user