Files
Starseed/frontend/tests/e2e/auth/login.spec.ts
T
tristan fbfb77f7a4
Auto Tag Develop / tag (push) Successful in 12s
tags multiselect — couleur des sites + limite d'affichage (#161)
## Objectif

Améliorer les multiselects (`MalioSelectCheckbox`) de l'application :

### Couleur des sites sur les tags
Les tags des multiselects **sites** (86 / 17 / 82) prennent désormais :
- en **fond** la couleur d'identification du site (champ `color`, groupe `site:read` — déjà exposé côté API, aucune modif back) ;
- en **texte** du blanc, pour rester lisibles sur les fonds colorés.

Appliqué en saisie **et** en consultation, dans les 4 modules concernés : Clients (M1), Fournisseurs (M2), Prestataires (M3), Produits (M6).

### Limite d'affichage des autres multiselects
Tous les multiselects **non-sites** (catégories, contacts, états, types de stockage…) affichent **au maximum 3 tags** ; le surplus est condensé en « +N ».

## Dépendance
- Bump `@malio/layer-ui` `1.7.15` → `1.7.17` (support `color` / `textColor` et `maxTags` sur les options).

## Tests
- 722 tests Vitest verts (69 fichiers), assertions des options sites enrichies (`color` / `textColor`).
- ESLint clean sur les 15 fichiers `.vue` modifiés.

> Commit front-only : hook pre-commit (tests back) contourné via `--no-verify`, la validation front a été lancée séparément.

Reviewed-on: #161
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
2026-06-29 12:16:53 +00:00

71 lines
3.0 KiB
TypeScript

import { expect, test } from '@playwright/test'
import { LoginPage } from '../helpers/pages/LoginPage'
import { SidebarComponent } from '../helpers/pages/SidebarComponent'
import { getPersona } from '../_fixtures/personas'
/**
* Tests du flow login/logout via l'UI.
*
* C'est le SEUL fichier qui traverse le formulaire pour de vrai. Les autres
* specs utilisent `loginAs()` qui pose directement le cookie BEARER via API,
* 10x plus rapide et decouple du form HTML.
*/
test.describe('Login', () => {
test('login valide pose le cookie BEARER et redirige vers /', async ({ page, context }) => {
const superAdmin = getPersona('super-admin')
const loginPage = new LoginPage(page)
await loginPage.goto()
await loginPage.fillAndSubmit(superAdmin.username, superAdmin.password)
// La redirection se fait apres un `navigateTo('/')` dans login.vue.
await page.waitForURL('/')
await expect(page).toHaveURL('/')
// Le cookie BEARER (HTTP-only) doit etre pose par Symfony.
const cookies = await context.cookies()
const bearer = cookies.find(c => c.name === 'BEARER')
expect(bearer, 'Le cookie BEARER doit etre pose apres un login valide').toBeDefined()
expect(bearer?.httpOnly).toBe(true)
})
test('login invalide reste sur /login et n\'emet pas de cookie', async ({ page, context }) => {
const loginPage = new LoginPage(page)
await loginPage.goto()
await loginPage.fillAndSubmit('e2e.super-admin', 'wrong-password')
// On ne doit PAS etre redirige — le handleSubmit swallow la 401 via toast,
// le user reste sur /login pour corriger.
await page.waitForTimeout(500)
await expect(page).toHaveURL(/\/login$/)
const cookies = await context.cookies()
const bearer = cookies.find(c => c.name === 'BEARER')
expect(bearer, 'Aucun cookie BEARER ne doit etre pose apres un login invalide').toBeUndefined()
})
test('logout efface le cookie et redirige vers /login', async ({ page, context }) => {
const superAdmin = getPersona('super-admin')
const loginPage = new LoginPage(page)
// 1. Login d'abord
await loginPage.goto()
await loginPage.fillAndSubmit(superAdmin.username, superAdmin.password)
await page.waitForURL('/')
// 2. Deconnexion via le footer de la sidebar : survol du bloc compte
// (revele le bouton) puis clic. Le handler appelle useLogout() qui POST
// /api/logout, reset les stores, et redirige vers /login (sans page /logout).
const sidebar = new SidebarComponent(page)
await sidebar.accountBlock().hover()
await sidebar.logoutButton().click()
await page.waitForURL(/\/login$/)
// 3. Le cookie BEARER doit avoir ete supprime par le firewall de logout
const cookies = await context.cookies()
const bearer = cookies.find(c => c.name === 'BEARER')
expect(bearer, 'Le cookie BEARER doit etre supprime apres logout').toBeUndefined()
})
})