Schermate operatore: un solo Completato grande, Fermo linea solo con run aperto, AVVIA ATTIVITA, pannello lotto/seriale dopo la scelta (#60 #61 #62 #63 #64)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 12:25:56 +02:00
parent 3856ee335a
commit 27dc5e77af
7 changed files with 149 additions and 98 deletions
@@ -104,7 +104,7 @@ def test_the_selection_screen_starts_the_sequence(
def test_avvia_on_the_list_starts_the_sequence(logged_in_client, mock_api_client):
html = _list_page(logged_in_client, mock_api_client)
assert "/measure/start/3" in html
assert "AVVIA IN SEQUENZA" in html
assert "AVVIA ATTIVITÀ" in html
# ---------------------------------------------------------------------------
@@ -163,6 +163,30 @@ def test_the_header_offers_completato_not_the_summary(
assert '@click="goToNextTask()"' in html
def test_only_one_completato_and_it_is_big(
logged_in_client, mock_api_client, monkeypatch,
):
"""#60: «Completato» una sola volta (in basso), largo e alto per il touch."""
html = _execute_page(logged_in_client, mock_api_client, monkeypatch)
# the label as a button text on its own line (comments in the JS also name it)
assert [l.strip() for l in html.splitlines()].count("Completato") == 1
assert "min-h-[64px]" in html
def test_no_open_run_means_no_fermo_linea_and_no_fake_timer(
logged_in_client, mock_api_client, monkeypatch,
):
"""#61: senza produzione aperta i pulsanti non si vedono, la modale non si
apre e un rifiuto del server non avvia un timer locale finto."""
html = _execute_page(logged_in_client, mock_api_client, monkeypatch)
assert 'x-if="isMeasureTask && productionRun"' in html
assert "!this.productionRun" in html
assert "Nessuna produzione aperta su questa stazione" in html
# il vecchio ripiego locale non c'e' piu'
assert "this.startCountdownFrom(this.measurementIntervalMinutes * 60)" not in html.split(
"async startProductionFromOverlay()")[1].split("async confirmCycle")[0]
def test_fine_ciclo_is_shown_before_it_can_be_used(
logged_in_client, mock_api_client, monkeypatch,
):
@@ -196,3 +220,27 @@ def test_the_operator_flow_never_links_to_the_statistics(
]
for html in pages:
assert "/statistics" not in html
def test_trace_panel_only_for_recipes_that_require_it(
logged_in_client, mock_api_client, monkeypatch,
):
"""#63/#64: ricerca+griglia in alto, pannello lotto/seriale solo dopo la
scelta di una ricetta che lo richiede, con i soli campi richiesti."""
_italian(logged_in_client)
monkeypatch.setattr("blueprints.measure.Config.STATION_CODE", "ST-TEST")
mock_api_client.get_station_recipes.return_value = [
{"id": 1, "code": "A", "name": "Con lotto", "requires_lot": True,
"requires_serial": False},
{"id": 2, "code": "B", "name": "Libera"},
]
html = logged_in_client.get("/measure/select").get_data(as_text=True)
assert 'id="trace-panel"' in html
assert 'x-show="selected && needsTrace(selected)"' in html
assert 'x-show="selected && selected.requires_lot"' in html
assert 'x-show="selected && selected.requires_serial"' in html
# la ricerca e la griglia precedono il pannello
assert html.index("Cerca ricetta") < html.index('id="trace-panel"')
assert html.index("Recipe Grid") < html.index('id="trace-panel"')
# le ricette senza obblighi partono direttamente
assert 'x-if="!needsTrace(recipe)"' in html