Break long values on the webhook page and event log at phone width (closes #391)
check / check (push) Successful in 3m39s
check / check (push) Successful in 3m39s
An event's ID or content type, or a name with no place to break, ran past its row and was cut off by the card at 390 pixels, and a long webhook name made the webhook page scroll sideways. Both pages' outer containers now carry wrap-anywhere, so such a value breaks only where it must; the event log's title row wraps like the webhook page's. The browser test gains a 390-pixel check of both pages: neither scrolls sideways and nothing shown runs past the page's or its card's edge. Its seeded webhook name and newer event's content type are long enough to fail without the change. Model: opus-5-5
This commit is contained in:
@@ -251,8 +251,9 @@ func TestHandleSourceDetail_RendersNamedTargetFields(
|
||||
// page's maximum width at 108rem (1728 px), half again the 72rem of
|
||||
// max-w-6xl that the webhook list and the event log use, so an
|
||||
// entrypoint URL fits on one line in a 1920-pixel window; and the
|
||||
// wrapping of its title row, so the buttons beside the title do not
|
||||
// push a phone-width window into scrolling sideways.
|
||||
// wrapping of its title row and of long values, so neither the buttons
|
||||
// beside the title nor a long name push a phone-width window into
|
||||
// scrolling sideways.
|
||||
func TestHandleSourceDetail_FitsWideAndNarrowWindows(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -273,7 +274,7 @@ func TestHandleSourceDetail_FitsWideAndNarrowWindows(t *testing.T) {
|
||||
|
||||
assert.Contains(
|
||||
t, body,
|
||||
`<div class="mx-auto px-6 py-8" style="max-width: 108rem"`,
|
||||
`<div class="mx-auto px-6 py-8 wrap-anywhere" style="max-width: 108rem"`,
|
||||
)
|
||||
assert.Contains(
|
||||
t, body,
|
||||
|
||||
@@ -98,20 +98,25 @@ func TestAlpineRunsUnderTheSecurityPolicy(t *testing.T) {
|
||||
checkRefusedNewWebhook(ctx, t, srv.URL+"/hooks/new")
|
||||
checkEventLog(ctx, t, page+"/events", event.ID, older.ID, target.Name)
|
||||
checkMobileMenu(ctx, t, page)
|
||||
checkPhoneWidth(ctx, t, page, page+"/events", target.Name)
|
||||
|
||||
assert.Empty(t, problems(), "the browser reported problems")
|
||||
}
|
||||
|
||||
// seedBrowserWebhook seeds the webhook the browser test loads, owned by
|
||||
// userID: an entrypoint, two events, and a target whose delivery of the
|
||||
// newer event failed once with a 502. It returns the webhook, the older
|
||||
// and the newer event, and the target.
|
||||
// newer event failed once with a 502. The webhook's name and the newer
|
||||
// event's content type are each too long for one line on a phone. It
|
||||
// returns the webhook, the older and the newer event, and the target.
|
||||
func seedBrowserWebhook(
|
||||
t *testing.T, env *testEnv, userID string,
|
||||
) (*database.Webhook, *database.Event, *database.Event, *database.Target) {
|
||||
t.Helper()
|
||||
|
||||
webhook := env.seedWebhook(t, userID)
|
||||
require.NoError(t, env.db.DB().Model(webhook).Update(
|
||||
"name", "payment_provider_production_notifications",
|
||||
).Error)
|
||||
require.NoError(t, env.db.DB().Omit(clause.Associations).Create(
|
||||
&database.Entrypoint{
|
||||
WebhookID: webhook.ID,
|
||||
@@ -126,6 +131,9 @@ func seedBrowserWebhook(
|
||||
|
||||
webhookDB, err := env.dbMgr.GetDB(webhook.ID)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, webhookDB.Model(event).Update(
|
||||
"content_type", "application/vnd.paymentprovider.event+json",
|
||||
).Error)
|
||||
require.NoError(t, webhookDB.Omit(clause.Associations).Create(
|
||||
&database.DeliveryResult{
|
||||
DeliveryID: dlv.ID,
|
||||
@@ -1292,3 +1300,60 @@ func checkMobileMenu(ctx context.Context, t *testing.T, url string) {
|
||||
click(ctx, t, button)
|
||||
assert.True(t, hidden(ctx, menu), "the menu button does not close the menu")
|
||||
}
|
||||
|
||||
// scrollsSideways reports whether the page is wider than the window. A
|
||||
// page's clientWidth is the window's width less its scroll bar.
|
||||
const scrollsSideways = `document.documentElement.scrollWidth >
|
||||
document.documentElement.clientWidth`
|
||||
|
||||
// cutOffElements lists each element, without elements inside it, that
|
||||
// is shown but runs past the page's edge or its card's, by more than a
|
||||
// pixel of rounding. A card hides what runs past its edge.
|
||||
const cutOffElements = `[...document.querySelectorAll("body *")]
|
||||
.filter((el) => {
|
||||
const box = el.getBoundingClientRect();
|
||||
const card = el.closest(".card")?.getBoundingClientRect();
|
||||
const left = card ? card.left : 0;
|
||||
const right = card ? card.right : document.documentElement.clientWidth;
|
||||
return el.children.length === 0 && box.width > 0 &&
|
||||
(box.left < left - 1 || box.right > right + 1);
|
||||
})
|
||||
.map((el) => el.outerHTML.slice(0, 120))`
|
||||
|
||||
// checkPhoneWidth loads the webhook page, url, and its event log,
|
||||
// eventLog, in a phone-sized window, the event log with the attempts of
|
||||
// the newest event's delivery to targetName shown. It checks that
|
||||
// neither page scrolls sideways and that nothing shown on either, no
|
||||
// status, time or control, is cut off at the page's or its card's edge.
|
||||
func checkPhoneWidth(
|
||||
ctx context.Context, t *testing.T, url, eventLog, targetName string,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
var (
|
||||
sideways bool
|
||||
cutOff []string
|
||||
)
|
||||
|
||||
measure := chromedp.Tasks{
|
||||
chromedp.Evaluate(scrollsSideways, &sideways),
|
||||
chromedp.Evaluate(cutOffElements, &cutOff),
|
||||
}
|
||||
|
||||
require.NoError(t, chromedp.Run(
|
||||
ctx,
|
||||
chromedp.EmulateViewport(phoneWidth, phoneHeight),
|
||||
loadPage(url),
|
||||
measure,
|
||||
))
|
||||
assert.False(t, sideways, "the webhook page scrolls sideways on a phone")
|
||||
assert.Empty(t, cutOff, "the webhook page cuts these off on a phone")
|
||||
|
||||
require.NoError(t, chromedp.Run(ctx, loadPage(eventLog)))
|
||||
click(ctx, t, `//span[text()="`+targetName+`"]`)
|
||||
require.True(t, shown(ctx, `//span[text()="Attempt 1"]`),
|
||||
"clicking the delivery does not show its attempts")
|
||||
require.NoError(t, chromedp.Run(ctx, measure))
|
||||
assert.False(t, sideways, "the event log scrolls sideways on a phone")
|
||||
assert.Empty(t, cutOff, "the event log cuts these off on a phone")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user