Repository navigation
fix(webui): keep the live-turn mark honest, and let the browser-driven gates run - #242
Merged
Merged
Conversation
added 8 commits
October 23, 2026 15:59
…e gate that needs it Two failures keep the webui branch red, and both live in code the branch carries today. The fork dialog seeds its title field from the fork options. Those options arrive after the dialog is already open, so the seed is a late reply: a name the person typed into the dialog could be overwritten by the suggested title that landed afterwards, and the fork was then created with the session's own title instead of the name that was asked for. The dialog now remembers whether the name has been edited, and only seeds the field when it has not. The WebUI integration suites drive a real Chromium - the loopback host test opens the built client in one and submits through it. The browser used to arrive with the `test:webui-browser` gate, which runs after `test:webui`, so a suite inside `test:webui` that needs a browser depended on a later gate having run first. The case that exercises the loopback host found it: the browser was simply not there. A dedicated gate now installs it before `test:webui` runs. The install stays free of `--with-deps` on purpose. Playwright's dependency installer has a Windows branch that shells out to PowerShell, and this gate runs on every platform. The Linux browser gate keeps its own `--with-deps` install, because that is what the visual baselines need - the CJK fonts among them.
The fork case read the reply frame once, right after the request had been observed. The reply travels on its own frame, so it can land later than the request, and the read then found nothing. Wait for the forked session's id itself, which is what the assertion is about. No expectation changed: the id still has to be a string.
The transcript-and-composer baseline was regenerated on a workstation, so it carried that machine's glyphs. On the Linux runner that runs the browser gate the same labels are drawn with the runner's CJK font, and the image no longer matched: 7415 pixels, a ratio of 0.01 - the size of a font difference, not of a layout change. The baseline is regenerated here on the CI runner, in the same Linux Chromium the browser gate compares against, which is the only environment that can produce a matching image. Two runs of the regeneration are compared byte for byte before the image is taken, and they are identical. The other nine baselines in this file are unchanged.
The case waits for the model server to see the request that starts a cancelable local response. The wait is for that event; the ceiling only decides how long the case may look for it. Twenty seconds is enough on Linux and not on macOS, whose whole verification run is about 1.5x the Linux one - 197.8s against 134.3s, measured on the same gate set. This step is also the first in the case that only runs once the earlier assertions hold, so on macOS it is the first one to be reached, and it is the first to hit the ceiling. The ceiling for this wait goes to 60 seconds, the same figure the isolated Chromium suite uses for its own slower steps. No expectation changed, and the other two waits keep their 20 seconds.
A `session.start` recheck resolves against the runtime's active turn. When that turn had already finished by the time the probe answered, the client attaches to pick up the frames it produced — an attach with no turn in it, because there is no turn left to name. That attach raised the session's `sending` flag, and `sending` is what the submission admission reads as "a turn is live". So the next message was queued instead of sent, and the composer's send button became the stop button, which swallowed the click that was meant to send it. An attach that cannot name the turn it follows therefore never marks the session live, and never clears a mark it did not raise. The probe's answer also has to name the turn for the client to follow it at all: an answer without a turn id cannot be resumed, and a lease opened for it would hold the next `session.start` off instead of letting this client follow it.
…tle-and-browser-gate
The expanded panel is declared together with the covering one, so a lookup that matched the selector string exactly found only the media-query rule that carries the panel's width and read no position at all. The cascade lookup is the one that reads a grouped selector, so the panel's position and inset are read through it. The panel now covers its own container — which the container already pins to the viewport — rather than the viewport itself, so the position the rule declares is `absolute`. The workspace panel's reveal is three more declared keyframes, which the "every keyframe animation the shell references" case now lists.
added 3 commits
October 23, 2026 18:57
The launcher's padding became symmetric, so its content now sits exactly on the panel body's centre line: the brand and the tiles are the first and last children of a centred column, so the midpoint between them is the launcher's own vertical centre. The assertion said "strictly above the centre", which the symmetric padding made unreachable, and it now fails with the two sides exactly equal. Assert the centring the new tab page actually has.
The new tab page the workspace launcher draws is not the one the baseline was taken from: the brand is the MiniMax wordmark instead of the app icon, and the address box is the wider rounded field of the redesign. The baseline was never regenerated because the gate that compares it had not run since the redesign landed. It is regenerated on the CI runner's own Chromium, and two consecutive runs produce byte-identical files.
Two files in the WebUI group drive a real browser, and they were running at the same time as each other and as the rest of the group. On a CI runner that is a browser per file competing for the same cores: the case that drives the browser panel needs about half again the time it gets, and it runs past its own deadline — a failure that says nothing about the code under test. The same thing already happens on Windows, where the whole suite is serialized for I/O contention. Serialize the group's files instead of relaxing any deadline: the browser gets the machine to itself, and every deadline stays the one its case was written against.
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.
Change
The
webuibranch was red in three places, and the reds were hiding each other: the first gate that failed stopped the ones after it, so a second and a third failure had never run. This PR fixes them in order.The client
session.startrecheck resolves against the runtime's active turn. When that turn had already finished by the time the probe answered, the client attaches to pick up the frames it produced — an attach with no turn in it, because there is no turn left to name. That attach raised the session'ssendingflag, andsendingis what the submission admission reads as "a turn is live": the next message was queued instead of sent, and the composer's send button became the stop button, which swallowed the click that was meant to send it. An attach that cannot name the turn it follows no longer marks the session live, and the probe's answer has to name the turn for the client to follow it at all.The gates
test:webuigate runs before the gate that installs playwright's chromium, so a browser-driving case in that group had nothing to launch. The browser install now runs ahead of it.The cases that the newer changes had moved under
eb6cd3e5redesigned the workspace's new tab page and4d06e817added the transcript case that drives the browser panel. Both landed while the gate that would have said so was not running.Validation
pnpm --filter @mavis/webui typecheck:client,typecheck:test— clean.packages/webui/test/unit/webui-w0-css-structure.test.ts— 29 passed.packages/webui/test/integration/agent-transcript.test.ts— 10 consecutive green runs locally (Chromium 153, the same build CI uses). Before the live-turn fix the same case failed roughly half the time.packages/webui/test/browser/browser-workspace.spec.mjs— 10 passed.webuigroup — 212 passed, 4 skipped.Publication and contribution checks
release/public-source.json; new tests are declared intest/vitest-suites.jsonwhere applicable.Maintainer handoff
Publication scope or license changes (if any): none.
Shared-source port: not needed. Record public PR references only; keep private links and review material out of this PR.