dd-timer/tests/e2e/ui-feedback.spec.ts
POL Mickaël 8af626dd66 sécurité: audit commercialisation — hardening + 366 tests (24 E2E)
Sandbox Electron, HTTPS ntfy, validation import structurelle,
suppression executeJavaScript, nettoyage memory leaks, try/catch
sur tous les appels electronAPI. 27 nouveaux tests de sécurité
et validation. README mis à jour avec changelog et couverture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 07:18:28 +02:00

122 lines
4.8 KiB
TypeScript

/**
* Tests E2E — Toast, ConfirmModal et Undo
*
* Verifie que les feedbacks UI (toast, modale de confirmation,
* annulation) fonctionnent correctement.
*/
import { test, expect } from './electron-app';
test.describe('Toast notifications', () => {
test('Toast success apparait apres suppression d\'une dragodinde', async ({ page }) => {
// Naviguer vers le premier enclos
const firstEnclos = page.locator('.sb-item[data-view]').filter({
has: page.locator('.sb-dot'),
}).first();
await firstEnclos.click();
await expect(page.locator('.enclos-view')).toBeVisible({ timeout: 5000 });
// Ajouter une 2e DD pour pouvoir en supprimer une
await page.click('button:has-text("Ajouter une Dragodinde")');
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2, { timeout: 5000 });
// Cliquer sur le bouton supprimer de la premiere DD
await page.locator('.dd-del').first().click();
// La modale de confirmation doit apparaitre
await expect(page.locator('.confirm-overlay:not(.confirm-hidden)')).toBeVisible({ timeout: 3000 });
await expect(page.locator('.confirm-title')).toHaveText('Retirer la dragodinde');
// Confirmer la suppression
await page.click('.confirm-btn-ok');
// Le toast success doit apparaitre avec le bouton Annuler
await expect(page.locator('.toast-success')).toBeVisible({ timeout: 3000 });
await expect(page.locator('.toast-msg')).toContainText('Dragodinde retirée');
await expect(page.locator('.toast-action')).toBeVisible();
});
});
test.describe('ConfirmModal', () => {
test('Annuler la modale ne supprime pas la DD', async ({ page }) => {
// Naviguer vers le premier enclos
const firstEnclos = page.locator('.sb-item[data-view]').filter({
has: page.locator('.sb-dot'),
}).first();
await firstEnclos.click();
await expect(page.locator('.enclos-view')).toBeVisible({ timeout: 5000 });
// Ajouter une 2e DD
await page.click('button:has-text("Ajouter une Dragodinde")');
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2, { timeout: 5000 });
// Cliquer supprimer
await page.locator('.dd-del').first().click();
await expect(page.locator('.confirm-overlay:not(.confirm-hidden)')).toBeVisible({ timeout: 3000 });
// Annuler
await page.click('.confirm-btn-cancel');
// La modale disparait, les 2 DD sont toujours la
await expect(page.locator('.confirm-overlay.confirm-hidden')).toBeAttached({ timeout: 3000 });
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2);
});
test('Cliquer en dehors de la modale annule', async ({ page }) => {
const firstEnclos = page.locator('.sb-item[data-view]').filter({
has: page.locator('.sb-dot'),
}).first();
await firstEnclos.click();
await expect(page.locator('.enclos-view')).toBeVisible({ timeout: 5000 });
await page.click('button:has-text("Ajouter une Dragodinde")');
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2, { timeout: 5000 });
await page.locator('.dd-del').first().click();
await expect(page.locator('.confirm-overlay:not(.confirm-hidden)')).toBeVisible({ timeout: 3000 });
// Cliquer sur l'overlay (pas la box)
await page.locator('.confirm-overlay').click({ position: { x: 10, y: 10 } });
// Les 2 DD sont toujours la
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2);
});
});
test.describe('Undo via toast', () => {
test('Le bouton Annuler dans le toast restaure la DD supprimee', async ({ page }) => {
const firstEnclos = page.locator('.sb-item[data-view]').filter({
has: page.locator('.sb-dot'),
}).first();
await firstEnclos.click();
await expect(page.locator('.enclos-view')).toBeVisible({ timeout: 5000 });
// Ajouter une 2e DD
await page.click('button:has-text("Ajouter une Dragodinde")');
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2, { timeout: 5000 });
// Supprimer la premiere DD
await page.locator('.dd-del').first().click();
await expect(page.locator('.confirm-overlay:not(.confirm-hidden)')).toBeVisible({ timeout: 3000 });
await page.click('.confirm-btn-ok');
// Attendre le toast avec le bouton Annuler
await expect(page.locator('.toast-action')).toBeVisible({ timeout: 3000 });
// Cliquer sur Annuler — l'app recharge
await page.locator('.toast-action').click();
// Apres reload, la page se recharge — attendre le shell
await page.waitForSelector('.app-shell', { timeout: 15000 });
// Naviguer a nouveau vers l'enclos
const enclosAfter = page.locator('.sb-item[data-view]').filter({
has: page.locator('.sb-dot'),
}).first();
await enclosAfter.click();
await expect(page.locator('.enclos-view')).toBeVisible({ timeout: 5000 });
// Les 2 DD doivent etre restaurees
await expect(page.locator('.dd-grid .dd-card')).toHaveCount(2, { timeout: 5000 });
});
});