Give each event its own page and show bodies the same everywhere (closes #369)
check / check (push) Successful in 3m15s

Each row of the recent events on the webhook page links to the
event's own page, /hook/{id}/events/{eventID}, and expands to show its
body; only the newest starts expanded. The event's page shows its
details, its whole body and every delivery with its attempts.

One renderer, newBodyView with templates/event_body.html, shows a body
in all three places: whole up to 32 KiB, cut there in the lists with a
link to the event's page, JSON pretty-printed, a body of more than 200
lines or 32 KiB in a scrolling box, and a body that is not text left
out beside its download link. A resubmitted copy links to its
original's page.

Model: opus-5-5
This commit is contained in:
clawbot
2026-10-02 17:10:02 +00:00
committed by sneak
parent 40f59ec4d2
commit f346b69999
22 changed files with 959 additions and 170 deletions
+46 -1
View File
@@ -39,6 +39,9 @@ const (
// the mobile menu button instead of the navigation links.
phoneWidth = 390
phoneHeight = 844
// olderBody is the body of the event received before the newest.
olderBody = "the older event"
)
// TestAlpineRunsUnderTheSecurityPolicy loads the webhook page and the
@@ -63,6 +66,7 @@ func TestAlpineRunsUnderTheSecurityPolicy(t *testing.T) {
Active: true,
},
).Error)
env.seedEvent(t, webhook.ID, olderBody)
event := env.seedEvent(t, webhook.ID, `{"hello":"browser"}`)
target := env.seedTarget(t, webhook.ID)
dlv := env.seedFailedDelivery(t, webhook.ID, event.ID, target.ID)
@@ -86,6 +90,7 @@ func TestAlpineRunsUnderTheSecurityPolicy(t *testing.T) {
checkAddForms(ctx, t, page)
checkTargetType(ctx, t, page+"/events")
checkCopy(ctx, t, page)
checkRecentEvents(ctx, t, page)
checkEventLog(ctx, t, page+"/events", event.ID, target.Name)
checkMobileMenu(ctx, t, page)
@@ -363,6 +368,46 @@ func checkCopy(ctx context.Context, t *testing.T, url string) {
`clicking Copy does not show "Copied"`)
}
// checkRecentEvents loads a webhook page and checks that of its recent
// events only the newest starts expanded, showing its body, that
// clicking the older one's row expands it and clicking again collapses
// it, and that clicking the newest one's row collapses it. It then
// follows the newest one's Open link to the event's own page, which
// shows the body.
func checkRecentEvents(ctx context.Context, t *testing.T, url string) {
t.Helper()
// The newest event's body is pretty-printed JSON. Each row's
// toggle is the button in the element that holds its state.
newest := `//pre[contains(., '"hello": "browser"')]`
older := `//pre[text()="` + olderBody + `"]`
toggle := `/ancestor::div[@x-data][1]//button`
require.NoError(t, chromedp.Run(ctx, loadPage(url)))
assert.True(t, shown(ctx, newest), "the newest event starts collapsed")
assert.True(t, hidden(ctx, older), "an older event starts expanded")
click(ctx, t, older+toggle)
assert.True(t, shown(ctx, older), "clicking an event does not expand it")
click(ctx, t, older+toggle)
assert.True(t, hidden(ctx, older),
"clicking an event again does not collapse it")
click(ctx, t, newest+toggle)
assert.True(t, hidden(ctx, newest),
"clicking the newest event does not collapse it")
require.NoError(t, chromedp.Run(ctx, loadPage(url)))
click(ctx, t, newest+`/ancestor::div[@x-data][1]//a[text()="Open"]`)
assert.True(t, shown(ctx, `//h2[text()="Body"]`),
"Open does not lead to the event's own page")
assert.True(t, shown(ctx, newest),
"the event's own page does not show its body")
}
// checkEventLog loads the event log and checks that clicking an event's
// row expands it, that in there clicking its delivery shows the
// delivery's attempts and clicking again hides them, and that clicking
@@ -375,7 +420,7 @@ func checkEventLog(
// The event's row shows its ID, and its Resubmit form is in the part
// that expands. The delivery's row there shows the target's name.
eventRow := `//span[text()="` + eventID + `"]`
expanded := `form[action$="/resubmit"]`
expanded := `form[action$="/` + eventID + `/resubmit"]`
deliveryRow := `//span[text()="` + targetName + `"]`
attempt := `//span[text()="Attempt 1"]`