9beaf2ed67
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
144 lines
7.9 KiB
Python
144 lines
7.9 KiB
Python
"""Test della pagina a due tab (#91, #92): contenuto statico di PAGINA, senza servizio."""
|
|
|
|
import importlib.util
|
|
import re
|
|
from pathlib import Path
|
|
|
|
_FILE = Path(__file__).resolve().parents[1] / "calibrazione_pagina.py"
|
|
_spec = importlib.util.spec_from_file_location("calibrazione_pagina_tab", _FILE)
|
|
_mod = importlib.util.module_from_spec(_spec)
|
|
_spec.loader.exec_module(_mod)
|
|
PAGINA = _mod.PAGINA
|
|
|
|
|
|
def test_due_tab_con_ruolo_e_selezione():
|
|
assert re.search(r'<button id="tabAcq"[^>]*role="tab"[^>]*aria-selected="true"', PAGINA)
|
|
assert re.search(r'<button id="tabCal"[^>]*role="tab"[^>]*aria-selected="false"', PAGINA)
|
|
assert ">Acquisizione</button>" in PAGINA and ">Calibrazione</button>" in PAGINA
|
|
assert 'role="tablist"' in PAGINA and 'role="tabpanel"' in PAGINA
|
|
assert 'aria-selected", cal ?' in PAGINA # la selezione cambia da JS
|
|
assert '"tmf.acq.tab"' in PAGINA # tab scelta ricordata (via memoria(), protetta)
|
|
|
|
|
|
def test_sorgente_in_cima_poi_riquadri():
|
|
# #92: Sorgente, anteprima e parametri stanno nel pannello Acquisizione; Sorgente prima dei riquadri
|
|
i_acq = PAGINA.index('id="pannelloAcq"')
|
|
i_cal = PAGINA.index('id="pannelloCal"')
|
|
i_sorg = PAGINA.index('id="sezioneSorgente"')
|
|
i_ant = PAGINA.index('id="sezioneAnteprima"')
|
|
i_riq = PAGINA.index('id="riquadri"')
|
|
assert i_acq < i_sorg < i_ant < i_riq < PAGINA.index('id="sezioneParametri"') < i_cal
|
|
assert PAGINA.index('id="sezioneCalibrazione"') > i_cal
|
|
# barra: casella calibrata e mirino; la vecchia casella «Immagine grezza» non c'e' piu'
|
|
assert 'id="mostraCal"' in PAGINA and "Attiva calibrazione" in PAGINA
|
|
assert 'id="grezzo"' not in PAGINA and "Immagine grezza (senza correzione)" not in PAGINA
|
|
# riquadri: «Immagine» sempre visibile, «Calibrata» nascosta finche' la casella e' spenta
|
|
assert re.search(r'<div class="riquadro" id="riquadroCal" hidden>', PAGINA)
|
|
assert "grezzo: true" in PAGINA
|
|
|
|
|
|
def test_id_del_pannello_calibrazione():
|
|
ids = set(re.findall(r'id="([^"]+)"', PAGINA))
|
|
attesi = {"calSorgente", "quadrato", "acquisisci", "nomeCal", "salva", "msgSalva", "calibrazioni",
|
|
"msgElenco", "stato", "risultato", "overlay",
|
|
"caricaImmagine", "fileImmagine", "rimuoviImmagine", "riquadroCal", "immagineCal", "mirinoCal"}
|
|
assert attesi <= ids, attesi - ids
|
|
usati = set(re.findall(r'\$\("([^"]+)"\)', PAGINA))
|
|
assert usati <= ids, usati - ids
|
|
assert len(re.findall(r'id="([^"]+)"', PAGINA)) == len(ids) # nessun id doppio
|
|
|
|
|
|
def test_calibrazione_senza_file_ne_radio():
|
|
# #92: l'immagine da file e' una sorgente di acquisizione, non un'opzione della calibrazione
|
|
for sparito in ("origFile", "origSorgente", "scegliFile", "nomeFile", 'type="radio"', "Immagine da file", "Sorgente selezionata"):
|
|
assert sparito not in PAGINA, sparito
|
|
# l'unico input file e' nella sezione Sorgente, in cima alla tab Acquisizione
|
|
assert PAGINA.count('type="file"') == 1
|
|
assert PAGINA.index('type="file"') < PAGINA.index('id="pannelloCal"')
|
|
assert "immagine grezza dalla tab Acquisizione" in PAGINA
|
|
# il calcolo manda solo la sorgente (e il lato), mai il file
|
|
assert 'f.append("source", sorgente)' in PAGINA and 'f.append("image"' not in PAGINA.split("async function calcola")[1].split("async function salvaNome")[0]
|
|
|
|
|
|
def test_testi_del_pannello():
|
|
for testo in ("Camera o immagine", "Carica immagine da file...", "Rimuovi immagine", "Calcola",
|
|
"Calibrazioni salvate", "risoluzione diversa", "Calibrata",
|
|
"Carica", "Elimina", "Scollega", "Sovrascrivi «", "Clic ancora", "Nome",
|
|
"calibrata: ", "non calibrata"):
|
|
assert testo in PAGINA, testo
|
|
|
|
|
|
def test_rotte_del_contratto():
|
|
for rotta in ("/camera/calibrazioni", "/camera/calibrazione-attiva", "/camera/calibrate",
|
|
"/camera/calibration?source=", "/camera/immagini", "/camera/immagini?nome=",
|
|
"/camera/anteprima/calibrata"): # #92
|
|
assert '"' + rotta in PAGINA, rotta
|
|
for parola in ("calcolo_id", "sovrascrivi", "method: \"PUT\"", "method: \"DELETE\"", "X-Larghezza", "X-Altezza"):
|
|
assert parola in PAGINA, parola
|
|
# il calcolo non salva piu': il campo save sparisce
|
|
assert 'append("save"' not in PAGINA
|
|
|
|
|
|
def test_nessuna_finestra_del_browser_e_offline():
|
|
for vietato in ("alert(", "confirm(", "prompt(", "http://", "https://"):
|
|
assert vietato not in PAGINA, vietato
|
|
|
|
|
|
def test_acquisizione_di_87_90_conservata():
|
|
# anteprima, indicatori, mirino, grezzo, parametri camera e ciclo a 100 ms restano
|
|
for parola in ("Parametri camera", "Mirino centrale",
|
|
"Math.max(100 - (Date.now() - t0), 0)", "/camera/anteprima", "/camera/parametri"):
|
|
assert parola in PAGINA, parola
|
|
|
|
|
|
def test_pagina_stretta():
|
|
assert "@media (max-width: 500px)" in PAGINA
|
|
# #91: elenco a schede, niente tabella larga ne' scorrimento orizzontale
|
|
assert 'id="calibrazioni" class="elenco"' in PAGINA and "overflow-x" not in PAGINA
|
|
assert "Lettura dei parametri..." in PAGINA
|
|
|
|
|
|
def test_ciclo_non_sospeso_nella_tab_calibrazione():
|
|
# #94: il ciclo non si ferma piu' entrando in Calibrazione (prima #92: A.riprendi); Calcola senza blocco aspetta le richieste in volo
|
|
assert "A.riprendi" not in PAGINA
|
|
calcola = PAGINA.split("async function calcola")[1].split("async function salvaNome")[0]
|
|
assert "fermaAnteprima();" in calcola and "A.inVolo) await pausa(50)" in calcola
|
|
|
|
|
|
def test_calibrata_dopo_anteprima_e_dopo_carica():
|
|
# #92: la calibrata segue ogni anteprima grezza riuscita e si aggiorna dopo Carica/Scollega; 404/409 al posto dell'immagine
|
|
assert "await aggiornaCalibrata(lato);" in PAGINA
|
|
assert PAGINA.count("aggiornaCalibrata();") >= 3
|
|
assert "messaggioCalibrata(await dettaglio(r))" in PAGINA
|
|
assert 'decodeURIComponent(r.headers.get("X-Calibrazione")' in PAGINA
|
|
|
|
|
|
def test_elenco_sorgenti_senza_attese_e_calibrata_solo_se_serve():
|
|
# #92: la voce dell'immagine caricata si aggiunge in pagina (niente rilettura dell'elenco); «Aggiorna» forza la ricerca camere
|
|
assert "aggiungiSorgente(j);" in PAGINA and "caricaSorgenti(j.source)" not in PAGINA
|
|
assert 'id="aggiornaSorgenti"' in PAGINA and ">Aggiorna</button>" in PAGINA
|
|
assert '"?aggiorna=true"' in PAGINA
|
|
# nessuna calibrazione attiva: il riquadro lo dice senza chiamare il servizio; dopo un 409 non si richiede piu'
|
|
assert "if (A.calAttiva === false)" in PAGINA
|
|
assert "nessuna calibrazione attiva su questa sorgente" in PAGINA
|
|
assert "if (r.status === 409) A.bloccoCal = true;" in PAGINA and "if (A.bloccoCal) return;" in PAGINA
|
|
assert PAGINA.count("A.bloccoCal = false;") >= 3 # cambio sorgente, Carica, Scollega
|
|
|
|
|
|
def test_attiva_calibrazione_con_scelta_e_conferma():
|
|
# #93: sotto la calibrata una combo e CONFERMA; la casella cambia nome
|
|
for i in ('id="sceltaCal"', 'id="confermaCal"', 'id="msgSceltaCal"'):
|
|
assert i in PAGINA, i
|
|
assert "Attiva calibrazione" in PAGINA and ">CONFERMA</button>" in PAGINA
|
|
assert "Mostra immagine calibrata" not in PAGINA
|
|
assert PAGINA.index('id="riquadroCal"') < PAGINA.index('id="sceltaCal"') < PAGINA.index('id="confermaCal"') < PAGINA.index('id="msgSceltaCal"')
|
|
# il gestore di CONFERMA usa PUT calibrazione-attiva (via caricaNome) o DELETE calibration (via scollega), messaggio sotto la calibrata
|
|
gestore = PAGINA[PAGINA.index('$("confermaCal").onclick'):]
|
|
gestore = gestore[:gestore.index("};")]
|
|
assert 'caricaNome(nome, "msgSceltaCal")' in gestore and 'scollega("msgSceltaCal")' in gestore
|
|
assert 'method: "PUT"' in PAGINA and "/camera/calibrazione-attiva" in PAGINA
|
|
assert 'method: "DELETE"' in PAGINA and '"/camera/calibration?source="' in PAGINA
|
|
# voce vuota «nessuna», suffisso di risoluzione, combo ridisegnata con l'elenco e spenta senza sorgente
|
|
assert "— nessuna (non calibrata) —" in PAGINA and "— risoluzione diversa" in PAGINA
|
|
assert "disegnaSceltaCal();" in PAGINA and "= !$(\"sorgente\").value" in PAGINA
|