veza/tests/e2e/audit/interaction/02-modals-dialogs.spec.ts
senke 463ad5386b test: update e2e test suite and add audit tests
Refine auth, player, tracks, playlists, search, workflows, edge cases,
forms, responsive, network errors, error boundary, performance, visual
regression, cross-browser, profile, smoke, storybook, chat, and session
tests. Add audit test suite (accessibility, ethical, functional, design
tokens). Update test helpers and visual snapshots.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:06:26 +01:00

109 lines
4.2 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { loginViaAPI, navigateTo } from '../helpers';
import { testModal } from '../helpers/interaction-helpers';
import { TEST_USERS } from '../design-tokens';
test.describe('MODALS & DIALOGS — Ouvrent, ferment, piègent le focus', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
});
test('Settings — les modals de confirmation fonctionnent', async ({ page }) => {
await navigateTo(page, '/settings');
// Chercher les boutons qui ouvrent des modals (delete, danger, etc.)
const dangerButtons = await page.locator('button:visible').filter({ hasText: /supprimer|delete|effacer|réinitialiser|reset|déconnexion|confirmer/i }).all();
for (const btn of dangerButtons.slice(0, 3)) {
try {
const text = await btn.textContent().then(t => t?.trim().slice(0, 30) || '').catch(() => '');
console.log(`[MODAL] Testing trigger: "${text}"`);
const result = await testModal(page, btn);
if (result.opens) {
console.log(` Opens: ${result.opens}`);
console.log(` Backdrop: ${result.hasBackdrop}`);
console.log(` Escape: ${result.closesOnEscape}`);
console.log(` Close btn: ${result.closesOnCloseButton}`);
console.log(` Focus trap: ${result.focusTrapped}`);
for (const issue of result.issues) {
console.log(` [ISSUE] ${issue}`);
}
expect(result.closesOnEscape, `Modal "${text}" ne se ferme pas avec Escape`).toBe(true);
}
} catch {
/* skip */
}
}
});
test('Playlists — la modal de création fonctionne', async ({ page }) => {
await navigateTo(page, '/playlists');
// Chercher le bouton "Créer une playlist" ou similaire
const createBtn = page.getByRole('button', { name: /créer|create|nouvelle|new/i }).first()
.or(page.locator('[data-testid*="create"]').first());
if (!await createBtn.isVisible({ timeout: 5_000 }).catch(() => false)) {
console.log('[MODAL] Pas de bouton de création de playlist trouvé');
return;
}
await createBtn.click();
await page.waitForTimeout(500);
const dialog = page.locator('[role="dialog"]').first();
const isOpen = await dialog.isVisible().catch(() => false);
if (isOpen) {
console.log('[MODAL] Modal de création de playlist ouverte');
// Vérifier qu'elle a un titre
const title = await dialog.locator('h2, h3, [class*="title"]').first().textContent().catch(() => '');
console.log(` Titre: "${title}"`);
// Vérifier qu'elle a un champ input
const input = dialog.locator('input:visible').first();
const hasInput = await input.isVisible().catch(() => false);
expect(hasInput, 'La modal de création devrait avoir un champ input').toBe(true);
// Escape ferme
await page.keyboard.press('Escape');
await page.waitForTimeout(300);
const closed = !(await dialog.isVisible().catch(() => false));
expect(closed, 'La modal ne se ferme pas avec Escape').toBe(true);
}
});
test('Dialogs — le backdrop bloque les clics sous le modal', async ({ page }) => {
await navigateTo(page, '/settings');
// Ouvrir n'importe quel modal disponible
const triggerBtn = await page.locator('button:visible').filter({ hasText: /supprimer|delete|logout|déconnexion|modifier|edit/i }).first();
if (!await triggerBtn.isVisible({ timeout: 5_000 }).catch(() => false)) return;
await triggerBtn.click();
await page.waitForTimeout(500);
const dialog = page.locator('[role="dialog"]').first();
if (!await dialog.isVisible().catch(() => false)) return;
// Vérifier la présence du backdrop
const hasBackdrop = await page.evaluate(() => {
return Array.from(document.querySelectorAll('.fixed.inset-0')).some(el => {
const s = getComputedStyle(el);
return s.backgroundColor !== 'rgba(0, 0, 0, 0)' || s.backdropFilter !== 'none';
});
});
console.log(`[MODAL] Backdrop présent: ${hasBackdrop}`);
expect(hasBackdrop, 'Le modal devrait avoir un backdrop visible').toBe(true);
// Nettoyage
await page.keyboard.press('Escape');
});
});