# Guida ai Test

Obiettivo della guida:
- capire che tipi di test esistono nel progetto
- capire a cosa servono davvero
- sapere come lanciarli senza errori
- sapere come leggere i risultati
- sapere cosa fare quando qualcosa fallisce

## 0) Perche facciamo i test?

Un test è un controllo automatico.

In pratica:
- tu cambi il codice
- lanci i test
- i test ti dicono se hai rotto qualcosa

Se i test sono verdi, hai una buona probabilita che il progetto sia ancora stabile.
Se i test sono rossi, c'e un problema da capire e sistemare.

## 1) Struttura delle cartelle test

```text
tests/
├── unit/          # Test della logica pura (molto veloci)
├── integration/   # Test di moduli che comunicano tra loro
├── component/     # Test dei componenti Vue in isolamento
├── stress/        # Test sotto carico (molti client/azioni)
├── e2e/           # Test end-to-end su browser reale
└── README.md      # Questa guida
```

## 2) Tecnologie usate

- `Vitest`: per `unit`, `integration`, `component`, `stress`
- `Playwright`: per `e2e`

Tradotto in modo semplice:
- Vitest controlla parti interne del progetto
- Playwright controlla il comportamento reale dell'app nel browser

## 3) Prerequisiti (prima di tutto)

### 3.1 Installa dipendenze

Dalla root del progetto:

```bash
npm install
```

### 3.2 Installa browser Playwright (solo E2E)

```bash
npx playwright install chromium firefox
```

Se non fai questo passo, gli E2E possono fallire subito con errore tipo:
- `Executable doesn't exist`

## 4) Comandi principali

```bash
npm run test            # Vitest in watch mode (resta in ascolto)
npm run test:all        # Tutta la suite Vitest una volta
npm run test:unit       # Unit + integration
npm run test:component  # Solo component test
npm run test:stress     # Solo stress test
npm run test:e2e        # Tutti gli E2E Playwright
npm run test:e2e:ui     # Playwright con interfaccia grafica
```

Ordine consigliato (quando vuoi verificare tutto):
1. `npm run test:all`
2. `npm run test:e2e`

## 5) Cosa testa ogni suite (spiegato semplice)

### 5.1 Unit (`tests/unit`)

Cosa sono:
- test piccoli e veloci sulla logica del gioco

A cosa servono:
- trovano subito bug in regole punteggio/set/reset

Esempi reali nel progetto:
- incremento/decremento punti
- cambio palla
- vittoria set con regola dei 2 punti di scarto
- reset stato
- `formInizio` (snapshot formazione di partenza del set)
- time out (`startTimeout`/`stopTimeout`: squadra, video, timestamp)
- generazione del referto (`buildRefertoHtml`)
- persistenza stato su disco (`persist.js`, con `fs` mockato)
- utility di rete (`server-utils.js`), incluso il rilevamento piattaforma
  (WSL/PowerShell vs. `os.networkInterfaces()`, con `fs`/`child_process`/`os`
  mockati per non dipendere dalla macchina che esegue i test)
- elenco video spot (`spot-utils.js`, su cartella temporanea reale)

Quando falliscono:
- quasi sempre c'e un problema nella logica core

> Nota: punteggio, set e servizio NON sono campi dello stato: si ricavano dalla
> `striscia` con `punteggio` / `setVinti` / `servizio`. Nei test si impostano gli
> scenari costruendo la `striscia`, non scrivendo `sp.punt`/`sp.set`.

### 5.2 Integration (`tests/integration`)

Cosa sono:
- test su pezzi che lavorano insieme (es. WebSocket + handler)

A cosa servono:
- verificano che i messaggi si muovano nel modo corretto

Esempi reali nel progetto:
- registrazione client `display`/`controller`
- broadcast stato ai client
- validazione input malformati
- autorizzazioni (solo controller puo inviare certe azioni)
- timer server-side del time out (auto-`stopTimeout` dopo 30s, `startedAt` impostato dal server)
- routing del server Express (`createApp`: rotte display/controller/asset, `/spot/list` e file statici `/spot/`)
- rami di errore del WebSocket handler (`ws.send`/`ws.terminate` che lanciano, `applyAction` che fallisce a metà azione: lo stato precedente va ripristinato senza propagare l'eccezione)
- avvio effettivo di `startServer` (`server.js`): ascolto HTTP, upgrade su `/ws`, rifiuto su altri percorsi, persistenza dopo un'azione — con `persist.js` mockato per non toccare mai `.segnapunti/state.json` reale

Quando falliscono:
- spesso c'e problema nel protocollo messaggi o nei controlli di ruolo

### 5.3 Component (`tests/component`)

Cosa sono:
- test dei componenti Vue senza browser completo

A cosa servono:
- controllano rendering e comportamento UI locale

Esempi reali nel progetto:
- punteggio mostrato correttamente
- stato connessione
- click bottoni controller
- dialog reset/config/cambi
- modal time out del controller (scelta squadra/video, banner, countdown)
- overlay time out del display (video, placeholder, countdown, dissolvenza)
- bottone REFERTO nel dialog PARTITA FINITA e generazione del referto stampabile (`generaReferto`: `window.open`, scrittura HTML, stampa)
- client WebSocket (`wsMixin`: connessione, riconnessione con backoff, cleanup allo smontaggio, `sendWs`, errori)
- layout esteso/landscape del controller (pannelli squadra, popup automatico SET VINTO con soglia decisiva)

Quando falliscono:
- spesso hai rotto template, computed, metodi o binding

### 5.4 Stress (`tests/stress`)

Cosa sono:
- test per simulare carico elevato

A cosa servono:
- verificano che il sistema regga molti client e molte azioni rapide

Esempi reali nel progetto:
- tanti client display connessi insieme
- burst di azioni consecutive

Quando falliscono:
- possono emergere problemi di performance o consistenza stato

### 5.5 End-to-End (`tests/e2e`)

Cosa sono:
- test realistici nel browser

A cosa servono:
- verificano che Controller e Display funzionino davvero insieme

File principali:
- `helpers.cjs`: helper condivisi (`openController`/`openDisplay`/`resetGame`/`addPoints`)
- `basic-flow.spec.cjs`: flusso base Controller <-> Display
- `game-operations.spec.cjs`: reset, config, toggle, cambi
- `game-simulation.spec.cjs`: simulazione partita
- `full-match.spec.cjs`: scenari partita completi
- `timeout.spec.cjs`: time out end-to-end (modal, overlay sul display, chiusura anticipata)
- `referto.spec.cjs`: generazione referto a PARTITA FINITA
- `accessibility.spec.cjs`: controlli accessibilita con axe
- `visual-regression.spec.cjs`: confronto screenshot con baseline

Note importanti:
- gli E2E sono configurati in seriale (`workers: 1`) per evitare interferenze sullo stato partita condiviso.
- il controller viene aperto in viewport portrait (layout "mobile") tramite `openController`: in landscape userebbe la dashboard estesa con selettori diversi.
- lo stato è UNICO e persistente sul server: ogni test inizia con `resetGame`, che azzera e reimposta i nomi di default per garantire determinismo.

## 6) Come leggere i risultati

### 6.1 Risultati Vitest

Caso OK (verde):

```text
Test Files  15 passed (15)
Tests      362 passed (362)
```

Significa:
- tutti i test Vitest sono passati

Caso KO (rosso):
- guarda prima il nome del file test
- poi il nome del test (`describe/test`)
- poi la riga con `expected` e `received`
- infine vai alla riga indicata nello stack trace

### 6.2 Risultati Playwright

Caso OK:

```text
81 passed
```

Caso KO:
- apri il report HTML

```bash
npx playwright show-report
```

Nel report puoi vedere:
- step del test
- errori precisi
- screenshot/diff
- trace

## 7) Visual Regression (screenshot)

I test visual confrontano immagini attuali con immagini baseline.

Cartella baseline:
- `tests/e2e/visual-regression.spec.cjs-snapshots/`

Se cambia la UI in modo intenzionale:
- aggiorna snapshot

```bash
npm run test:e2e -- --update-snapshots
```

Poi rilancia controllo:

```bash
npm run test:e2e
```

Se la UI non doveva cambiare:
- non aggiornare snapshot
- correggi prima il codice UI/CSS

## 8) Errori comuni e soluzione veloce

- Errore Playwright `Executable doesn't exist`:
  - esegui `npx playwright install chromium firefox`

- E2E instabili con punteggi strani:
  - assicurati che i test restino seriali (`workers: 1`)
  - assicurati che ogni test parta da stato pulito (reset)

- Selettore ambiguo (esempio bottone `Cambi`):
  - usa selector piu specifici, ad esempio `getByRole(..., { exact: true })`

- Failure accessibilita:
  - controlla prima `alt` delle immagini e contrasto colori

## 9) Mini checklist prima di fare push

Esegui:

```bash
npm run test:all
npm run test:e2e
```

Se hai cambiato UI e i visual falliscono per differenze volute:

```bash
npm run test:e2e -- --update-snapshots
npm run test:e2e
```

## 10) Copertura del codice

Non c'è uno script `npm` dedicato, ma si può controllare la copertura in
qualsiasi momento con:

```bash
npx vitest run tests/unit tests/integration tests/component --coverage
```

Il report a schermo mostra percentuale e righe scoperte per file. La suite
attuale copre oltre il 99% di statement/linee; le poche righe rimaste
scoperte sono documentate nei commit dei rispettivi test come codice morto,
difensivo, oppure legato a HMR (`import.meta.hot`) o all'avvio diretto
(`node server.js`) — casi non testabili in modo significativo senza side
effect reali sull'ambiente.

## 11) Come aggiungere un nuovo test (consigli pratici)

- metti i test nel posto giusto:
  - `tests/unit` per logica pura
  - `tests/integration` per moduli che dialogano
  - `tests/component` per Vue in isolamento
  - `tests/stress` per carico
  - `tests/e2e` per flussi reali

- mantieni nomi chiari:
  - il titolo del test deve spiegare cosa verifica

- evita test dipendenti da ordine:
  - ogni test deve potersi eseguire da solo

- negli E2E:
  - porta sempre il sistema in stato iniziale
  - usa selector robusti
  - limita `waitForTimeout` e preferisci attese su condizioni reali

Se segui questi punti, i test restano stabili e facili da capire anche per chi entra ora nel progetto.
