815d49d699
Refs #122 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
98 lines
4.4 KiB
Python
98 lines
4.4 KiB
Python
"""gitea:Adriano/TieMeasureFlow#118 #119 #120 #121 - pannello visione dell'operatore (task_execute.html).
|
|
|
|
Controlli sul testo del template: barra in alto con/senza camera, pulsante Salva,
|
|
conteggio quote e «Completato» dopo «Registra», cella NaN, svg al posto del canvas.
|
|
"""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
TEMPLATE = Path(__file__).resolve().parents[1] / "templates" / "measure" / "task_execute.html"
|
|
SRC = TEMPLATE.read_text(encoding="utf-8")
|
|
|
|
|
|
def _panel():
|
|
start = SRC.rindex("<div", 0, SRC.index('x-data="visionExecute()"'))
|
|
return SRC[start:SRC.index("MEASUREMENT TIMER BANNER")]
|
|
|
|
|
|
def _bar(panel):
|
|
# barra in alto: dall'apertura fino al blocco di errore
|
|
return panel[:panel.index('<div x-show="error"')]
|
|
|
|
|
|
def test_file_input_only_without_camera():
|
|
# #119: l'input file «Acquisisci immagine/Riprova» sta nel ramo `not camera_enabled`
|
|
bar = _bar(_panel())
|
|
no_cam = bar[bar.index("{% if not camera_enabled %}"):bar.index("{% else %}")]
|
|
assert 'type="file"' in no_cam
|
|
cam = bar[bar.index("{% else %}"):]
|
|
assert 'type="file"' not in cam
|
|
assert bar.count('type="file"') == 1
|
|
|
|
|
|
def test_camera_bar_has_grab_and_record_only():
|
|
# #119: con camera «Acquisisci da camera» (grab) e «Registra»; in_linea resta Pausa/Riprendi
|
|
cam = _bar(_panel())
|
|
cam = cam[cam.index("{% else %}"):]
|
|
assert "{{ _('Acquisisci da camera') }}" in cam and '@click="grab()"' in cam
|
|
assert '@click="record()"' in cam and "{{ _('Registra') }}" in cam
|
|
assert "togglePause()" in cam and "{{ _('Pausa') }}" in cam and "{{ _('Riprendi') }}" in cam
|
|
assert "onPick(" not in cam
|
|
|
|
|
|
def test_save_button_is_tmf_viewer_with_texts():
|
|
# #119 #122: «Salva» e' del componente <tmf-viewer> (barra: Riduci, Ingrandisci, Adatta, Salva, %); il template gli passa nome e testi
|
|
panel = _panel()
|
|
assert "<tmf-viewer" in panel and ':src="shownImage"' in panel and ':save-name="saveName"' in panel
|
|
for t in ("Adatta", "Salva", "Ingrandisci", "Riduci", "Salva immagine"):
|
|
assert "{{ _('%s') }}" % t in panel, t
|
|
assert "saveImage()" not in panel and "zPct()" not in panel
|
|
assert "taskName:" in SRC
|
|
|
|
|
|
def test_viewer_scripts_order():
|
|
# #122: image_viewer.js dopo vision_overlay.js e save_image.js (e prima di vision_execute.js non serve: e' un Custom Element)
|
|
assert SRC.index("js/vision_overlay.js") < SRC.index("js/image_viewer.js")
|
|
assert SRC.index("js/save_image.js") < SRC.index("js/image_viewer.js")
|
|
|
|
|
|
def test_overlay_and_labels_passed_to_viewer():
|
|
# #121 #122: overlay e etichette arrivano al viewer con x-effect (proprieta'), niente canvas
|
|
panel = _panel()
|
|
assert "<canvas" not in panel
|
|
assert "$el.overlay = (result && result.overlay) || []" in panel and "$el.labels = viewerLabels" in panel
|
|
assert "overlayLabels" not in panel
|
|
|
|
|
|
def test_value_cell_shows_nan_for_null():
|
|
# #118: la cella passa da fmtValue (null -> NaN), non da Number(r.value).toFixed
|
|
panel = _panel()
|
|
assert 'fmtValue(r.value, r.unit)' in panel
|
|
assert "Number(r.value)" not in panel
|
|
|
|
|
|
def test_can_leave_task_depends_on_vision_recorded():
|
|
# #120: «Completato» e «Fine ciclo misura» richiedono visionRecorded per i task visione
|
|
m = re.search(r"get canLeaveTask\(\) \{(.*?)\n \},", SRC, re.S)
|
|
assert m and "isVisionTask && !this.visionRecorded" in m.group(1)
|
|
assert m.group(1).index("visionRecorded") < m.group(1).index("cycleConfirmed")
|
|
assert "visionRecorded: false" in SRC
|
|
|
|
|
|
def test_missing_label_says_record_the_piece():
|
|
# #120: non registrato -> «Registra il pezzo», non «Mancano N quote»
|
|
m = re.search(r"get missingQuotesLabel\(\) \{(.*?)\n \},", SRC, re.S)
|
|
assert m and "Registra il pezzo" in m.group(1)
|
|
assert m.group(1).index("Registra il pezzo") < m.group(1).index("Mancano")
|
|
|
|
|
|
def test_page_listens_to_vision_recorded_and_resets():
|
|
# #120: la radice ascolta l'evento; resetForNewCycle azzera visionRecorded; il ripristino mette deviation null
|
|
assert '@vision-recorded.window="onVisionRecorded($event.detail)"' in SRC
|
|
m = re.search(r"resetForNewCycle\(\) \{(.*?)\n \},", SRC, re.S)
|
|
assert m and "visionRecorded = false" in m.group(1)
|
|
m = re.search(r"onVisionRecorded\(detail\) \{(.*?)\n \},", SRC, re.S)
|
|
assert m and "visionRecorded = true" in m.group(1) and "this.measurements = " in m.group(1)
|
|
assert "deviation: m.value == null ? null" in SRC
|
|
assert "if (this.isVisionTask) this.visionRecorded = true" in SRC
|