feat(diagnostics): the debug recorder — start, the pill, steps, screenshots, stop (E16 S2)
- the start dialog is the consent: level (Részletes/Teljes), what is recorded, retention and the cap (now served as diagnostics.session_minutes) - the pill docks under the toasts: elapsed time, Step (an optional label, its own Escape layer), Screenshot (tab capture where the browser has it), Stop; compact on a phone - while recording, lib/log tags every event and every request path (req, beacon, uploadReq via one identityHeaders) names the session; applyDiagnostics raises the level for the session's run and never lowers a raised one, and lapses at whichever ends first - Stop sends what is waiting before the server closes the session; the cap says so and opens the composer - Settings → Diagnosztika and the command palette start/step/stop it - the evidence leaves the log upload's own request lines out - the step shortcut is deliberately palette-only: the keymap's D1 rule bars a new modifier chord, and a bare letter collides with the players'
This commit is contained in:
@@ -335,15 +335,16 @@ def test_the_evidence_is_the_sessions_rows_in_time_order(db, make_user, as_user)
|
||||
sid = _start(client)["id"]
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
def row(ts, source, session):
|
||||
def row(ts, source, session, event="x.y", attrs=None):
|
||||
return LogEvent(
|
||||
ts=ts,
|
||||
level="INFO",
|
||||
sev=9,
|
||||
source=source,
|
||||
logger=source,
|
||||
event="x.y",
|
||||
event=event,
|
||||
msg=source,
|
||||
attrs=attrs,
|
||||
user_id=user.id,
|
||||
debug_session_id=session,
|
||||
)
|
||||
@@ -353,15 +354,20 @@ def test_the_evidence_is_the_sessions_rows_in_time_order(db, make_user, as_user)
|
||||
row(now + timedelta(seconds=2), "api", sid),
|
||||
row(now + timedelta(seconds=1), "web", sid),
|
||||
row(now, "web", None),
|
||||
# The recording's own log upload is plumbing, not evidence…
|
||||
row(now, "api", sid, "http.request", {"path": debugsession.INGEST_PATH}),
|
||||
# …but a server line with no event code and no attrs is evidence all the same.
|
||||
row(now + timedelta(seconds=3), "api", sid, None),
|
||||
]
|
||||
)
|
||||
db.commit()
|
||||
body = client.get(f"/api/debug-sessions/{sid}/events").json()
|
||||
assert [(i["source"], i["debug_session_id"]) for i in body["items"]] == [
|
||||
("web", sid),
|
||||
("api", sid),
|
||||
assert [(i["source"], i["event"]) for i in body["items"]] == [
|
||||
("web", "x.y"),
|
||||
("api", "x.y"),
|
||||
("api", None),
|
||||
]
|
||||
assert body["total"] == 2
|
||||
assert body["total"] == 3
|
||||
|
||||
|
||||
# --- screenshots ----------------------------------------------------------------------------
|
||||
@@ -436,3 +442,7 @@ def test_a_screenshot_can_be_removed_and_is_then_gone(recording):
|
||||
assert r.json() == {"ok": True, "deleted": shot}
|
||||
r = client.get(f"/api/debug-sessions/{sid}/screenshots/{shot}")
|
||||
assert r.status_code == 404 and r.json()["detail"]["reason"] == "screenshot"
|
||||
|
||||
|
||||
def test_the_upload_path_left_out_of_the_evidence_is_the_real_one():
|
||||
assert debugsession.INGEST_PATH in {r.path for r in diagnostics_routes.router.routes}
|
||||
|
||||
@@ -68,6 +68,7 @@ def test_raising_the_level_sets_the_servers_expiry_whatever_the_client_sends(db,
|
||||
"level": "INFO",
|
||||
"until": None,
|
||||
"retention_days": 7,
|
||||
"session_minutes": 60,
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +83,7 @@ def test_a_lapsed_level_reads_as_the_base_in_me(db, client, make_user):
|
||||
"level": "INFO",
|
||||
"until": None,
|
||||
"retention_days": 7,
|
||||
"session_minutes": 60,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user