diff --git a/src/modules/event/features/reconnexion-meme-identite.feature b/src/modules/event/features/reconnexion-meme-identite.feature index 511e4d1..b7fa7b4 100644 --- a/src/modules/event/features/reconnexion-meme-identite.feature +++ b/src/modules/event/features/reconnexion-meme-identite.feature @@ -1,5 +1,5 @@ # language: fr -@EVENT @priority-1 @data @wip +@EVENT @priority-1 @data Fonctionnalité: Reconnexion d'une même identité sur le wallet persistant En tant qu'utilisateur qui, sur le MÊME wallet physique, ouvre une PAGE FRAÎCHE (nouveau login broker, session fraîche) sous le MÊME identifiant qu'avant, diff --git a/src/modules/event/steps/data/reconnexion.steps.ts b/src/modules/event/steps/data/reconnexion.steps.ts index dbeb883..264fa86 100644 --- a/src/modules/event/steps/data/reconnexion.steps.ts +++ b/src/modules/event/steps/data/reconnexion.steps.ts @@ -52,21 +52,34 @@ When('une page fraîche pour la MÊME identité A recharge sur le même wallet', (this as any).recoFreshFrame = freshFrame; }); -Then('l\'événement {string} est sur l\'accueil de la page fraîche A', async function (this: FestipodWorld, title: string) { +// The cold-start read is a BOUNDED SYNC-LAG (measured: the just-created public +// doc lists on the first cold attempt, home titles converge at ~1s), and the real +// UI is reactive — so these assertions POLL for convergence (up to ~15s) instead +// of reading once. A single-shot read races the first-open/sync window and would +// flake. This mirrors how the app's own steps already poll participation. +Then('l\'événement {string} est sur l\'accueil de la page fraîche A', { timeout: 60000 }, async function (this: FestipodWorld, title: string) { const freshFrame = (this as any).recoFreshFrame; - const onHome = await freshFrame.evaluate((title: string) => { + const onHome = await freshFrame.evaluate(async (title: string) => { const td = (window as any).__testData; + for (let i = 0; i < 30; i++) { + if (td.homeEventTitles().includes(title)) return true; + await new Promise(r => setTimeout(r, 500)); + } return td.homeEventTitles().includes(title); }, title); expect(onHome, `"${title}" MUST appear on the fresh A page's home (getUserEvents(A) after reconnect)`).to.be.true; }); -Then('la page fraîche A est participante de l\'événement {string}', async function (this: FestipodWorld, title: string) { +Then('la page fraîche A est participante de l\'événement {string}', { timeout: 60000 }, async function (this: FestipodWorld, title: string) { const freshFrame = (this as any).recoFreshFrame; const eventId = (this as any).isoEventId; const isPart = await freshFrame.evaluate(async ({ eventId }: { eventId: string }) => { const td = (window as any).__testData; const aId = await td.ensureCurrentUser(); + for (let i = 0; i < 30; i++) { + if (td.isParticipating(eventId, aId)) return true; + await new Promise(r => setTimeout(r, 500)); + } return td.isParticipating(eventId, aId); }, { eventId }); expect(isPart, `The fresh A page MUST read its own participation in "${title}" after reconnect`).to.be.true; @@ -75,10 +88,16 @@ Then('la page fraîche A est participante de l\'événement {string}', async fun Then('le compte autoritatif de participation de A à l\'événement {string} est {int}', { timeout: 60000 }, async function (this: FestipodWorld, _title: string, expected: number) { const freshFrame = (this as any).recoFreshFrame; const eventId = (this as any).isoEventId; - const count = await freshFrame.evaluate(async ({ eventId }: { eventId: string }) => { + const count = await freshFrame.evaluate(async ({ eventId, expected }: { eventId: string; expected: number }) => { const td = (window as any).__testData; const aId = await td.ensureCurrentUser(); - return td.authParticipationCount(eventId, aId); - }, { eventId }); + let last = -1; + for (let i = 0; i < 30; i++) { + last = await td.authParticipationCount(eventId, aId); + if (last === expected) return last; + await new Promise(r => setTimeout(r, 500)); + } + return last; + }, { eventId, expected }); expect(count, `Authoritative broker count of A's participation must be ${expected} after reconnect`).to.equal(expected); });