fix(auth): land on home after gate entry; align the @humain e2e to the identifier flow
Removing ConnexionScreen dropped its post-login navigate('/home'). Since the
identifier is now entered at the barrier (before the broker round-trip), on return
the app can load at '/' (WelcomeScreen) with a session already open. AuthGate now
redirects welcome→/home once connected AND identified (gate-disabled paths, i.e.
@e2e/@data harness, are exempt).
Update the @humain assisted-import e2e (the real staging flow, the coverage for
this page) to the new UX: the tester types an identifier then clicks « Entrer »
(one act), and lands directly on home — the 'choisir un nom d'utilisateur'
(ConnexionScreen) steps are removed. Step bindings verified; tsc + build green.
Doctrine: knowledge_multibrowser-harness.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-1
@@ -13,10 +13,11 @@
|
||||
* screens, not the auth flow). Absent → gate ON.
|
||||
*/
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect, type ReactNode } from 'react';
|
||||
import { useNextGraph } from '../shared/context/NextGraphContext';
|
||||
import { useAccount } from '../shared/context/AccountContext';
|
||||
import { AccessGateScreen } from '../modules/auth/screens/AccessGateScreen';
|
||||
import { useRouter, useNavigate } from './router';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
@@ -27,6 +28,18 @@ const GATE_DISABLED = globalThis.__FESTIPOD_ACCESS_GATE_DISABLED__ === true;
|
||||
export function AuthGate({ children }: { children: ReactNode }) {
|
||||
const { status, error, connect } = useNextGraph();
|
||||
const { username, login } = useAccount();
|
||||
const { route } = useRouter();
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Once connected AND identified, leave the disconnected welcome screen for the
|
||||
// app home. The identifier is now set at the barrier (before the broker
|
||||
// round-trip), so on return the app can land on '/' with a session already
|
||||
// open; the removed ConnexionScreen used to do this navigate on login.
|
||||
useEffect(() => {
|
||||
if (!GATE_DISABLED && status === 'connected' && username && route.page === 'welcome') {
|
||||
navigate('/home');
|
||||
}
|
||||
}, [status, username, route.page, navigate]);
|
||||
|
||||
// Gate explicitly disabled (no-gate build / @e2e harness) → straight to app.
|
||||
if (GATE_DISABLED) {
|
||||
|
||||
@@ -69,7 +69,5 @@ Fonctionnalité: Harness multi-navigateur — modèles private-wallet et shared-
|
||||
Étant donné un nouveau testeur ouvre Festipod en staging sur un navigateur vierge
|
||||
Alors Festipod affiche l'écran d'accès avec le portefeuille à télécharger
|
||||
Quand le testeur télécharge le portefeuille et l'importe sur nextgraph.eu
|
||||
Et le testeur revient sur Festipod et clique « Entrer »
|
||||
Alors Festipod est connecté et propose de choisir un nom d'utilisateur
|
||||
Quand le testeur choisit un nom d'utilisateur
|
||||
Et le testeur revient sur Festipod, saisit un identifiant et clique « Entrer »
|
||||
Alors il arrive sur l'accueil de l'application
|
||||
|
||||
@@ -57,34 +57,22 @@ When('le testeur télécharge le portefeuille et l\'importe sur nextgraph.eu', a
|
||||
await pool.importWalletViaFile(page, filePath!, (this as any).displayedPassword);
|
||||
});
|
||||
|
||||
When('le testeur revient sur Festipod et clique « Entrer »', async function (this: FestipodWorld) {
|
||||
When('le testeur revient sur Festipod, saisit un identifiant et clique « Entrer »', async function (this: FestipodWorld) {
|
||||
const handle = this.browser('H');
|
||||
await handle.page.goto((this as any).stagingUrl, { waitUntil: 'domcontentloaded' });
|
||||
// Saisit son identifiant (il nomme l'espace virtuel) — « Entrer » reste désactivé
|
||||
// tant qu'il est vide. Naming the space and opening the wallet are one act.
|
||||
const idf = handle.page.locator('[data-testid=identifier-input]');
|
||||
await idf.waitFor({ state: 'visible', timeout: 15000 });
|
||||
await idf.fill('testeur');
|
||||
const entrer = handle.page.getByText('Entrer', { exact: true });
|
||||
await entrer.waitFor({ state: 'visible', timeout: 15000 });
|
||||
await entrer.click(); // déclenche le redirect vers le broker
|
||||
await entrer.click(); // enregistre l'identifiant PUIS déclenche le redirect broker
|
||||
await handle.page.waitForURL('**nextgraph**', { timeout: 20000 }).catch(() => {});
|
||||
// Le broker demande de déverrouiller le wallet fraîchement importé → son mot de
|
||||
// passe (completeBrokerLogin attend la page de login wallet de façon robuste).
|
||||
handle.appFrame = await pool.completeBrokerLogin(handle.page, (this as any).stagingUrl, pool.sharedWalletPassword);
|
||||
});
|
||||
|
||||
Then('Festipod est connecté et propose de choisir un nom d\'utilisateur', async function (this: FestipodWorld) {
|
||||
const handle = this.browser('H');
|
||||
expect(handle.appFrame, 'l\'app doit être chargée dans l\'iframe broker').to.not.equal(null);
|
||||
// Connecté → AuthGate passe l'AccessGateScreen et montre ConnexionScreen.
|
||||
await handle.appFrame!.waitForFunction(
|
||||
() => /Choisissez votre nom d'utilisateur|Connexion/.test(document.body?.innerText ?? ''),
|
||||
{ timeout: 30000 },
|
||||
);
|
||||
});
|
||||
|
||||
When('le testeur choisit un nom d\'utilisateur', async function (this: FestipodWorld) {
|
||||
const frame = this.browser('H').appFrame!;
|
||||
await frame.locator('input[placeholder="@votrepseudo"]').fill('@testeur');
|
||||
await frame.getByRole('button', { name: 'Se connecter' }).click();
|
||||
});
|
||||
|
||||
Then('il arrive sur l\'accueil de l\'application', async function (this: FestipodWorld) {
|
||||
const frame = this.browser('H').appFrame!;
|
||||
// On atterrit sur /home (l'app), PAS sur l'onboarding hors-connexion ('/'
|
||||
|
||||
Reference in New Issue
Block a user