Files
davide c6eb493f25 feat(referto): mostra l'icona del servizio a inizio set
Aggiunge un'icona nera (nuovo asset serv-nero.png, più visibile del
serv.png bianco su sfondo chiaro) accanto al nome della squadra che
serviva all'inizio di ogni set nel referto stampabile.

Corregge inoltre generaReferto: la stampa partiva subito dopo
document.close(), prima che l'icona (risorsa esterna asincrona)
finisse di caricare, risultando in un riquadro vuoto. Ora attende
l'evento 'load' della finestra popup prima di chiamare print().
2026-07-15 10:05:47 +02:00
..

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

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:

npm install

3.2 Installa browser Playwright (solo E2E)

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

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):

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:

81 passed

Caso KO:

  • apri il report HTML
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
npm run test:e2e -- --update-snapshots

Poi rilancia controllo:

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:

npm run test:all
npm run test:e2e

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

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:

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.