diff --git a/rtut/activity.py b/rtut/activity.py
index d9dffaa..9752ca8 100644
--- a/rtut/activity.py
+++ b/rtut/activity.py
@@ -11,6 +11,19 @@ def _step_title(run, sid: str) -> str:
return sid
+def _gate_title(run, gid: str) -> str:
+ try:
+ return run.pack.data and next(g["title"] for st in _all_stages(run.pack.data["stages"]) for g in st.get("gates", []) if g["id"] == gid)
+ except (StopIteration, KeyError):
+ return gid
+
+
+def _all_stages(stages):
+ for st in stages:
+ yield st
+ yield from _all_stages(st.get("stages", []))
+
+
def events_for(pack, pack_index: int | None) -> list[dict]:
out = []
for rid in R.list_runs(pack):
@@ -34,9 +47,9 @@ def events_for(pack, pack_index: int | None) -> list[dict]:
for gid, gs in d.get("gates", {}).items():
when = max([r["at"] for r in gs.get("results", {}).values()] or [""])
if gs["state"] in ("passed", "failed") and when:
- ev(when, f"gate “{gid}” {gs['state']}")
+ ev(when, f"gate “{_gate_title(run, gid)}” {gs['state']}")
if gs["state"] == "waived":
- ev(gs["waiver"]["at"], f"waived gate “{gid}”: {gs['waiver']['reason']}")
+ ev(gs["waiver"]["at"], f"waived gate “{_gate_title(run, gid)}”: {gs['waiver']['reason']}")
for dv in d.get("deviations", []):
if dv["kind"] in ("override", "changed-after-use"):
ev(dv["at"], f"{dv['kind'].replace('-', ' ')}: {dv['item']} ({dv['reason']})", dv.get("who", who))
diff --git a/rtut/ui.py b/rtut/ui.py
index ff3861a..d7d3921 100644
--- a/rtut/ui.py
+++ b/rtut/ui.py
@@ -138,7 +138,7 @@ class App:
f"
{e(x['at'][:16].replace('T', ' '))} · {e(x['who'])} {e(x['text'])} "
f"· {e(x['pack'])}{' · project ' + e(x['project']) if x.get('project') else ''}"
f"{' · open' if x['link'] else ''}" for x in events)
- return f"Latest activities
"
+ return f"Latest activities (times in UTC)
"
def user_page(self, msg: str = "") -> bytes:
u = USER.current()
diff --git a/tests/test_activity_artefacts.py b/tests/test_activity_artefacts.py
index 7e3aeb9..ccd52f7 100644
--- a/tests/test_activity_artefacts.py
+++ b/tests/test_activity_artefacts.py
@@ -41,6 +41,16 @@ def test_latest_activities_are_newest_first_across_packs_and_cover_the_main_even
assert len(activity.latest([v1, v2], 3)) == 3
+def test_gate_events_use_the_gate_title(tmp_path):
+ (v2,) = repo_with(tmp_path, "two2")
+ q = run2.create(v2, "cy", {"logdir": "/tmp/rtut-act-z"})
+ for sid in ("read-the-sign", "light-lamp", "read-the-sky"):
+ run2.start(q, sid); run2.verify(q, sid, confirm=True, manual_ok=True); run2.complete(q, sid)
+ run2.gate_check(q, "lamp-check", 0, manual_ok=True); run2.gate_check(q, "lamp-check", 1)
+ text = " | ".join(e["text"] for e in activity.latest([v2], 30))
+ assert "gate “The lamp burns steadily” passed" in text and "lamp-check" not in text
+
+
def test_overrides_and_changed_values_are_visible_in_the_feed(tmp_path):
(v2,) = repo_with(tmp_path, "two2")
q = run2.create(v2, "cy", {"logdir": "/tmp/rtut-act-y"})
diff --git a/tests/test_ui_round3.py b/tests/test_ui_round3.py
index 334cbcd..241d1e3 100644
--- a/tests/test_ui_round3.py
+++ b/tests/test_ui_round3.py
@@ -146,7 +146,7 @@ def test_main_page_lists_latest_activities_newest_first_with_links(srv):
feed = body.split("Latest activities")[1].split("Runbooks
")[0]
assert "erin started a run (manual mode)" in feed and "finished step “Light the lamp”" in feed
assert feed.index("Light the lamp") < feed.index("Read the poem over the door") < feed.index("started a run") # newest first
- assert f"open" in feed
+ assert f"open" in feed and "(times in UTC)" in body
# ---- (d) changing values that steps already used --------------------------------------------------------------------------