UI: show command only when a step is started, buttons left of comment, fail-comment warning, keep focus on current step
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 295952@bnt-lap001 Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
This commit is contained in:
parent
e30d81c5b6
commit
86ac0bebbe
4 changed files with 124 additions and 35 deletions
|
|
@ -43,15 +43,15 @@ def test_foreign_host_and_missing_token_refused(srv):
|
|||
def test_walk_a_run(srv):
|
||||
t = srv.app.token
|
||||
st, loc, _ = req(srv, "POST", "/run/new/0", {"_t": t, "operator": "bernd", "p_host": "localhost", "p_count": "1"})
|
||||
assert st == 303 and loc.startswith("/run/0/")
|
||||
assert req(srv, "POST", loc + "/ping/start", {"_t": t})[0] == 303
|
||||
st, _, body = req(srv, "GET", loc)
|
||||
assert st == 303 and loc.startswith("/run/0/") and loc.endswith("#current")
|
||||
assert req(srv, "POST", loc.split("#")[0] + "/ping/start", {"_t": t})[0] == 303
|
||||
st, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "ping -c 1 localhost" in body and "Run check" in body
|
||||
req(srv, "POST", loc + "/ping/verify", {"_t": t, "yes": "1"})
|
||||
st, _, body = req(srv, "GET", loc)
|
||||
req(srv, "POST", loc.split("#")[0] + "/ping/verify", {"_t": t, "yes": "1"})
|
||||
st, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
if "passed" in body and "failed" not in body.split("Threat")[0].replace("Mark failed", ""):
|
||||
assert req(srv, "POST", loc + "/ping/done", {"_t": t})[0] == 303
|
||||
assert "All steps done" in req(srv, "GET", loc)[2]
|
||||
assert req(srv, "POST", loc.split("#")[0] + "/ping/done", {"_t": t})[0] == 303
|
||||
assert "All steps done" in req(srv, "GET", loc.split("#")[0])[2]
|
||||
|
||||
|
||||
def test_unsafe_parameter_rejected_and_escaped(srv):
|
||||
|
|
@ -63,8 +63,8 @@ def test_unsafe_parameter_rejected_and_escaped(srv):
|
|||
def test_secret_in_note_refused(srv):
|
||||
t = srv.app.token
|
||||
_, loc, _ = req(srv, "POST", "/run/new/0", {"_t": t, "operator": "bernd"})
|
||||
req(srv, "POST", loc + "/ping/start", {"_t": t})
|
||||
st, _, body = req(srv, "POST", loc + "/ping/fail", {"_t": t, "note": "hvs.ABCDEFGHIJKLMN"})
|
||||
req(srv, "POST", loc.split("#")[0] + "/ping/start", {"_t": t})
|
||||
st, _, body = req(srv, "POST", loc.split("#")[0] + "/ping/fail", {"_t": t, "note": "hvs.ABCDEFGHIJKLMN"})
|
||||
assert st == 400 and "secret-looking" in body
|
||||
|
||||
|
||||
|
|
@ -79,18 +79,78 @@ def test_manual_check_cycle_and_blocked_reason(srv):
|
|||
srv.app.packs.append(P.load(d / "pack.yaml"))
|
||||
i = len(srv.app.packs) - 1
|
||||
_, loc, _ = req(srv, "POST", f"/run/new/{i}", {"_t": t, "operator": "bernd"})
|
||||
_, _, body = req(srv, "GET", loc)
|
||||
_, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "0 of 8 steps done" in body and "1. Read the poem" in body
|
||||
assert "Waiting for: step 1" in body # blocked steps explain themselves
|
||||
req(srv, "POST", loc + "/read-the-sign/start", {"_t": t})
|
||||
_, _, body = req(srv, "GET", loc)
|
||||
req(srv, "POST", loc.split("#")[0] + "/read-the-sign/start", {"_t": t})
|
||||
_, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "Yes, it is" in body and "Not yet" in body and "/read-the-sign/done" not in body
|
||||
req(srv, "POST", loc + "/read-the-sign/verify", {"_t": t, "ok": "0"})
|
||||
_, _, body = req(srv, "GET", loc)
|
||||
req(srv, "POST", loc.split("#")[0] + "/read-the-sign/verify", {"_t": t, "ok": "0"})
|
||||
_, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "Check not passed" in body and "/read-the-sign/done" not in body
|
||||
req(srv, "POST", loc + "/read-the-sign/verify", {"_t": t, "ok": "1"})
|
||||
_, _, body = req(srv, "GET", loc)
|
||||
req(srv, "POST", loc.split("#")[0] + "/read-the-sign/verify", {"_t": t, "ok": "1"})
|
||||
_, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "Check passed" in body and "/read-the-sign/done" in body
|
||||
req(srv, "POST", loc + "/read-the-sign/done", {"_t": t})
|
||||
_, _, body = req(srv, "GET", loc)
|
||||
req(srv, "POST", loc.split("#")[0] + "/read-the-sign/done", {"_t": t})
|
||||
_, _, body = req(srv, "GET", loc.split("#")[0])
|
||||
assert "1 of 8 steps done" in body and "Start this step" in body
|
||||
|
||||
|
||||
def _showcase_run(srv):
|
||||
import shutil
|
||||
from rtut import pack as P
|
||||
t = srv.app.token
|
||||
d = Path(srv.app.packs[0].path).parents[2] / "runbooks" / "show2"; d.mkdir(parents=True)
|
||||
shutil.copy(ROOT / "runbooks/showcase-lighthouse/pack.yaml", d / "pack.yaml")
|
||||
srv.app.packs.append(P.load(d / "pack.yaml"))
|
||||
i = len(srv.app.packs) - 1
|
||||
st, loc, _ = req(srv, "POST", f"/run/new/{i}", {"_t": t, "operator": "bernd"})
|
||||
return t, loc, st
|
||||
|
||||
|
||||
def test_redirects_keep_focus_on_current_step(srv):
|
||||
t, loc, _ = _showcase_run(srv)
|
||||
assert loc.endswith("#current")
|
||||
base = loc.split("#")[0]
|
||||
st, redirect, _ = req(srv, "POST", base + "/read-the-sign/start", {"_t": t})
|
||||
assert st == 303 and redirect.endswith("#current")
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert body.count("id=current") == 1 and "scrollIntoView" in body
|
||||
|
||||
|
||||
def test_command_and_copy_appear_only_when_step_is_started(srv):
|
||||
t, loc, _ = _showcase_run(srv)
|
||||
base = loc.split("#")[0]
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert "<button type=button data-copy>" not in body and "<pre>" not in body # nothing started yet
|
||||
req(srv, "POST", base + "/read-the-sign/start", {"_t": t})
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert "<button type=button data-copy>" in body # started: command and Copy appear
|
||||
assert "<pre>printf" in body
|
||||
req(srv, "POST", base + "/read-the-sign/verify", {"_t": t, "ok": "1"})
|
||||
req(srv, "POST", base + "/read-the-sign/done", {"_t": t, "note": "read it twice"})
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert "<button type=button data-copy>" not in body # done: no copy button
|
||||
assert "<details>" in body and "Comment: read it twice" in body # command kept as a record, comment shown
|
||||
|
||||
|
||||
def test_action_buttons_left_of_the_comment(srv):
|
||||
t, loc, _ = _showcase_run(srv)
|
||||
base = loc.split("#")[0]
|
||||
req(srv, "POST", base + "/read-the-sign/start", {"_t": t})
|
||||
req(srv, "POST", base + "/read-the-sign/verify", {"_t": t, "ok": "1"})
|
||||
_, _, body = req(srv, "GET", base)
|
||||
row = body[body.index("<p class=row>"):]
|
||||
assert row.index("Mark done") < row.index("Mark failed") < row.index("name=note")
|
||||
|
||||
|
||||
def test_fail_without_comment_warns_first_then_is_allowed(srv):
|
||||
t, loc, _ = _showcase_run(srv)
|
||||
base = loc.split("#")[0]
|
||||
req(srv, "POST", base + "/read-the-sign/start", {"_t": t})
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert "data-fail" in body and "data-warn hidden" in body and "dataset.warned" in body # client-side first-click warning
|
||||
st, _, _ = req(srv, "POST", base + "/read-the-sign/fail", {"_t": t, "note": ""}) # the second click submits
|
||||
assert st == 303
|
||||
_, _, body = req(srv, "GET", base)
|
||||
assert "(no comment)" in body and "Retry" in body
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue