import { expect, test } from '@playwright/test' test.describe('critical frontend flows - extended', () => { test.beforeEach(async ({ page }) => { await page.goto('/') await page.evaluate(() => { localStorage.clear() }) }) test('profile route requires auth, then allows access after demo login', async ({ page }) => { await page.goto('/profile') await expect(page.getByText('Connexion requise pour accéder au profil joueur.')).toBeVisible() await page.getByRole('button', { name: 'Se connecter (mode démo)' }).click() await expect(page.getByText('Statistiques joueur')).toBeVisible() await expect(page.getByText(/Parties jouées/i)).toBeVisible() }) test('start new game from home and render first playable question', async ({ page }) => { await page.goto('/') const homeNameInput = page.getByTestId('home-player-name-input') await homeNameInput.evaluate((el) => { const input = el as HTMLInputElement input.value = 'E2E Player' input.dispatchEvent(new Event('input', { bubbles: true })) input.dispatchEvent(new Event('change', { bubbles: true })) }) await page.getByRole('button', { name: 'Démarrer la partie' }).click() await expect(page).toHaveURL(/\/game$/) await expect(page.getByRole('heading', { name: 'Partie' })).toBeVisible() await expect(page.getByText('Thème : Général')).toBeVisible() await expect(page.getByText('Quel est le plus petit nombre premier ?')).toBeVisible() await expect(page.getByLabel('Ta réponse')).toBeVisible() await expect(page.getByText('3 restant(s)')).toBeVisible() }) test('hint usage reduces awarded score for a correct answer', async ({ page }) => { await page.goto('/game') await page.getByRole('button', { name: 'Indice (score réduit)' }).click() await expect(page.getByText('Confirmer l’indice')).toBeVisible() await page.locator('button', { hasText: 'Oui, utiliser un indice' }).click() await expect(page.getByText(/Indice:/i)).toBeVisible() const answerInput = page.getByLabel('Ta réponse') await answerInput.evaluate((el) => { const input = el as HTMLInputElement input.value = '2' input.dispatchEvent(new Event('input', { bubbles: true })) input.dispatchEvent(new Event('change', { bubbles: true })) }) await page.getByRole('button', { name: 'Envoyer' }).click() await expect(page).toHaveURL(/\/results$/) await expect(page.getByText('Score final : 1')).toBeVisible() }) test.fixme('after 3 wrong answers, game advances to next question', async ({ page }) => { await page.goto('/game') await page.getByLabel('Ta réponse').fill('wrong') await page.getByRole('button', { name: 'Envoyer' }).click() await page.getByLabel('Ta réponse').fill('wrong') await page.getByRole('button', { name: 'Envoyer' }).click() await page.getByLabel('Ta réponse').fill('wrong') await page.getByRole('button', { name: 'Envoyer' }).click() await expect(page.getByText('Question 2')).toBeVisible() await expect(page.getByText("Plus d'essais.")).not.toBeVisible() }) test.fixme('session timeout ends game and redirects to results', async ({ page }) => { await page.goto('/game') await expect(page.getByRole('heading', { name: 'Partie' })).toBeVisible() await expect(page).toHaveURL(/\/results$/) await expect(page.getByText(/Temps écoulé/i)).toBeVisible() }) test('results remain visible after page reload', async ({ page }) => { await page.goto('/') await page.evaluate(() => { localStorage.setItem( 'kf.lastResult', JSON.stringify({ playerName: 'Reload Tester', finalScore: 7, answered: 4, correct: 3, successRate: 75, durationSec: 95, leaderboardPosition: 2, finishedAt: new Date().toISOString(), }) ) }) await page.goto('/results') await expect(page.getByText('Score final : 7')).toBeVisible() await page.reload() await expect(page.getByText('Score final : 7')).toBeVisible() await expect(page.getByText('Position leaderboard : #2')).toBeVisible() }) test.fixme('leaderboard shows empty and error states from API', async ({ page }) => { await page.goto('/leaderboard') await expect(page.getByText('Aucun score pour le moment.')).toBeVisible() await page.getByRole('button', { name: 'Rafraîchir' }).click() await expect(page.getByText(/Erreur|Impossible/i)).toBeVisible() }) test.fixme('admin can create, edit, then delete a question', async ({ page }) => { await page.goto('/admin/questions') await page.getByTestId('admin-theme-input').fill('Science') await page.getByTestId('admin-question-input').fill('Quelle planète est rouge ?') await page.getByTestId('admin-answer-input').fill('Mars') await page.getByTestId('admin-hint-input').fill('4e planète') await page.getByTestId('admin-create-question').click() await expect(page.getByText('Quelle planète est rouge ?')).toBeVisible() await page .getByRole('button', { name: /Modifier/i }) .first() .click() await page .getByTestId('admin-question-input') .fill('Quelle planète est appelée planète rouge ?') await page.getByRole('button', { name: /Enregistrer la modification/i }).click() await expect(page.getByText('Quelle planète est appelée planète rouge ?')).toBeVisible() await page.getByRole('button', { name: 'Supprimer' }).first().click() await expect(page.getByText('Quelle planète est appelée planète rouge ?')).toHaveCount(0) }) test('admin form validation blocks invalid submission', async ({ page }) => { await page.goto('/admin/questions') await page.getByTestId('admin-theme-input').fill('') await page.getByTestId('admin-question-input').fill('') await page.getByTestId('admin-answer-input').fill('') await page.getByTestId('admin-create-question').click() await expect(page.getByText('Theme, question et réponse sont requis.')).toBeVisible() }) }) test.describe('critical frontend flows - mobile viewport', () => { test.use({ viewport: { width: 390, height: 844 } }) test('mobile player flow keeps core controls visible', async ({ page }) => { await page.goto('/') await page.evaluate(() => { localStorage.clear() }) const mobileNameInput = page.getByTestId('home-player-name-input') await mobileNameInput.evaluate((el) => { const input = el as HTMLInputElement input.value = 'Mobile Player' input.dispatchEvent(new Event('input', { bubbles: true })) input.dispatchEvent(new Event('change', { bubbles: true })) }) await page.getByRole('button', { name: 'Démarrer la partie' }).click() await expect(page).toHaveURL(/\/game$/) await expect(page.getByRole('button', { name: 'Envoyer' })).toBeVisible() await expect(page.getByRole('button', { name: 'Indice (score réduit)' })).toBeVisible() await expect(page.getByLabel('Ta réponse')).toBeVisible() }) })