From 851e524bd16eac9c80e26f167476f1437e34cfaf Mon Sep 17 00:00:00 2001 From: Arlo Liu Date: Sun, 30 Aug 2026 13:04:38 +0800 Subject: [PATCH] test(e2e): poll the select and report the page chooseOption evaluated its expression once, and its failure named a missing label and nothing else. Every other browser helper's failure carries the session report. The console removes .panels wholesale in two states, and every label goes with it: a panel fetch answering 401 under oidc calls signIn, which sets phase to "navigating" and assigns the login URL, and a failed /v1/whoami sets phase to "error". A browser that has left the console for the issuer's login form was therefore indistinguishable, in the old message, from a control the page had not finished rendering. The helper now polls the way waitFor polls. Every early return in the expression comes before the assignment, so evaluating it again sets the value at most once. Both readings were run against a scenario that navigates to the login before choosing. The single-shot read failed in 7.70s with "no select is labelled Profile" and named no page. The polling read failed with the same reason after the action deadline, followed by a request list ending at the issuer's /auth and /auth/local. Polling does not rescue a page that has navigated away. The report is what identifies the cause; the poll closes the single-shot read. --- test/e2e/scenarios_console_test.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/test/e2e/scenarios_console_test.go b/test/e2e/scenarios_console_test.go index 487c40a..5a6b64a 100644 --- a/test/e2e/scenarios_console_test.go +++ b/test/e2e/scenarios_console_test.go @@ -656,6 +656,14 @@ func (s *session) refetchCollections(t *testing.T) { // chooseOption picks a value in the select the label names, // and dispatches the change event the page listens for, which setting the property alone would not. +// It polls the way waitFor polls rather than reading once, +// so a control the page has not finished rendering is waited for instead of reported as absent. +// Every early return in the expression comes before the assignment, +// so evaluating it a second time still sets the value at most once. +// The failure carries the session report, which every other browser helper's failure already carries: +// the request list names where the page went, +// and a page that navigated away from the console is indistinguishable from an unrendered control +// in a message that only says a label is missing. func (s *session) chooseOption(t *testing.T, label, value string) { t.Helper() expr := fmt.Sprintf(`(() => { @@ -670,9 +678,19 @@ func (s *session) chooseOption(t *testing.T, label, value string) { return ""; })()`, label, label, value, value, value) var why string - s.eval(t, "choose "+label, expr, &why) - if why != "" { - t.Fatalf("choose %s = %q: %s", label, value, why) + err := poll(s.ctx, browserDeadline, func(ctx context.Context) (bool, error) { + if err := chromedp.Run(ctx, chromedp.Evaluate(expr, &why)); err != nil { + return false, err + } + + return why == "", nil + }) + if err != nil { + // A transport error leaves no reason behind, so the error itself is the reason. + if why == "" { + why = err.Error() + } + t.Fatalf("choose %s = %q: %s\n%s", label, value, why, s.report()) } }