import { expect, test } from '@playwright/test'; /** * R2.4 — LA boucle produit : le gardien scanne le QR (aucun compte), signale, * l'équipe traite (via API), le gardien voit « Résolu » sur son téléphone. */ const suffix = Date.now().toString(36); const API = 'http://localhost:3000'; test('portail QR : signalement sans compte → traitement → suivi Résolu', async ({ page, request, }) => { // 1 · Le gardien scanne le QR de l'ascenseur A1 → formulaire prérempli await page.goto('/q/A1'); await expect(page.getByText(/Ascenseur A1/)).toBeVisible(); await expect(page.getByText('détecté par le QR')).toBeVisible(); await page.getByLabel('Décrivez le problème').fill(`E2E ${suffix} — voyant cabine éteint`); await page.getByRole('button', { name: 'Envoyer le signalement' }).click(); await expect(page.getByText('l\'équipe SPELEV est prévenue')).toBeVisible(); // « Mes signalements » : Reçu, sans jargon const ligne = page.locator('.item-liste', { hasText: suffix }); await expect(ligne).toBeVisible(); await expect(ligne.locator('.etape.fait')).toHaveText('✓ Reçu'); // 2 · Côté SPELEV (via API — le parcours UI est couvert par parcours-r2) : // approbation → démarrage → bilan → clôture const comptes = await (await request.get(`${API}/auth/demo-accounts`)).json(); const salmaId = comptes.accounts.find((a: { roleName: string }) => a.roleName === 'Dispatcher').id; const jeton = (await (await request.post(`${API}/auth/demo-login`, { data: { userId: salmaId } })).json()).accessToken; const auth = { Authorization: `Bearer ${jeton}` }; const demandes = await (await request.get(`${API}/requests`, { headers: auth })).json(); const demande = demandes.requests.find((r: { description: string }) => r.description.includes(suffix)); expect(demande).toBeTruthy(); const ot = await ( await request.post(`${API}/requests/${demande.id}/approve`, { headers: auth, data: {} }) ).json(); await request.post(`${API}/work-orders/${ot.id}/transition`, { headers: auth, data: { to: 'IN_PROGRESS' }, }); // 3 · Le gardien recharge : « Intervention » franchie await page.reload(); await expect(page.locator('.item-liste', { hasText: suffix }).getByText('✓ Intervention')).toBeVisible(); // 4 · Clôture avec bilan → « Résolu » const refs = await (await request.get(`${API}/reference-values`, { headers: auth })).json(); const valeur = (field: string) => refs.referenceValues.find((v: { field: string; isActive: boolean }) => v.field === field && v.isActive).id; await request.put(`${API}/work-orders/${ot.id}/report`, { headers: auth, data: { doorStateId: valeur('DOOR_STATE'), actionTakenId: valeur('ACTION_TAKEN'), componentConcernedId: valeur('COMPONENT_CONCERNED'), }, }); const cloture = await request.post(`${API}/work-orders/${ot.id}/transition`, { headers: auth, data: { to: 'DONE' }, }); expect(cloture.ok()).toBe(true); await page.reload(); await expect(page.locator('.item-liste', { hasText: suffix }).getByText('✓ Résolu')).toBeVisible(); }); test('QR inconnu : message clair, pas d’écran technique', async ({ page }) => { await page.goto('/q/INTROUVABLE-99'); await expect(page.getByText(/aucun appareil connu/)).toBeVisible(); });