test(e2e): poll the select and report the page - #13
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The diagnosis this started from does not hold
console-oidcfails intermittently on thecurrentlane with:The standing explanation was a render race:
chooseOptionreads once, and thetwo waits before it cover something next to the Profile select rather than the
select itself, so a loaded runner has not rendered it yet.
internal/ui/static/app.jsrules that out..panels(:931) renders only oncephaseis none ofbooting,navigating,signInRequired,error.renderRequest(:1070) is inside.panels, and the Profile<label>(
:1094) and theinput.url<label>(:1140) are in the same${limits ? ... : null}branch (:1092).limitsis set once (:434) and never set back to null.So
input.urlholding a value entails the Profile label existing in that samesynchronous render. The second wait already covers the select. A slow render
cannot produce this message.
What does produce it
The console empties
.panelswholesale, taking every label with it, in twostates:
request()(:401): a panel fetch answering 401 underoidccallssignIn(), which setsphasetonavigatingand assigns the login URL.boot()(:369): a failed/v1/whoamisetsphasetoerror.The browser is then on the issuer's login form, where labels exist and none
holds a
<select>— which is the message, verbatim, and it fails fast ratherthan timing out, matching the 17.87s the lane recorded.
What this changes
chooseOptionnow polls the waywaitForpolls, and its failure carries thesession report the way every other browser helper's failure already does.
Both readings were run against a scenario that navigates to the login before
choosing:
no select is labelled Profile, names no page/authand/auth/localThe first row is the lane's failure reproduced exactly. The second is why this
is worth landing: the report names where the page went.
What this does not do
Polling does not rescue a page that has navigated away, so #12 may stay red
after this merges. The poll closes a genuine single-shot read; the report is
what will identify the cause.
The next failure names the fetch that did it.
Only one candidate survives reading
fetchJSON(:88): it setsstatusto 0and
rejectedto true when fetch never produces a response, andrequest()(
:399) branches onres.status === 401. A transport failure therefore neverreaches
signIn()— it records a panel error and leaves.panelsstanding.That rules out the port-forward resets the lane's log shows inside
console-oidc's window (03:00:44, :45, :47,read: connection reset by peer).A reset during a panel fetch keeps the page on the console; a reset during
boot()'s whoami leavesphaseaterrorwith no retry scheduled, becauseonly a
not_readyanswer schedules one, so the scenario would hang at awaitForfor the full deadline rather than fail fast insidechooseOption.What is left is a genuine 401 answered to a panel fetch on a load that already
carries a session cookie from a completed login.
Validation
mise run lint,mise run test,mise run check, andsemlf --base origin/mainall pass.mise run test:e2eran on thecurrentlane.