fix(ui): preserve slow build-link navigation (#120334)

* fix(ui): preserve slow build-link navigation

* test(ui): stabilize slow build-link e2e
This commit is contained in:
Peter Steinberger
2026-08-07 14:32:14 -07:00
committed by GitHub
parent 0aa85c7f83
commit b53c02b2f2
2 changed files with 35 additions and 4 deletions
+11 -2
View File
@@ -48,6 +48,15 @@ const AGENT_VALUE_PREFIX = "agent:";
const COMMAND_VALUE_PREFIX = "command:";
const LINK_VALUE_PREFIX = "link:";
// Nested overlays bubble lifecycle events through the dropdown. Only the
// owner's completed hide may remove its menu or consume its Escape state.
function closeMenuAfterOwnDropdownHide(event: Event, onClose: (restoreFocus?: boolean) => void) {
if (event.target !== event.currentTarget) {
return;
}
onClose(consumeDropdownKeyboardDismissal(event));
}
type AgentMenuAgent = {
id: string;
name?: string;
@@ -285,7 +294,7 @@ export function renderSidebarAgentMenu(params: SidebarAgentMenuParams) {
}}
@keydown=${(event: KeyboardEvent) =>
trackDropdownKeyboardDismissal(event, params.onTabAway)}
@wa-after-hide=${(event: Event) => params.onClose(consumeDropdownKeyboardDismissal(event))}
@wa-after-hide=${(event: Event) => closeMenuAfterOwnDropdownHide(event, params.onClose)}
>
<button
slot="trigger"
@@ -425,7 +434,7 @@ export function renderSidebarIdentityMenu(params: SidebarIdentityMenuParams) {
}}
@keydown=${(event: KeyboardEvent) =>
trackDropdownKeyboardDismissal(event, params.onTabAway)}
@wa-after-hide=${(event: Event) => params.onClose(consumeDropdownKeyboardDismissal(event))}
@wa-after-hide=${(event: Event) => closeMenuAfterOwnDropdownHide(event, params.onClose)}
>
<button
slot="trigger"
+24 -2
View File
@@ -62,7 +62,29 @@ async function openBuildDetails(page: Page) {
expect(compactText).not.toContain("");
expect(containsBrokenSurrogate(compactText)).toBe(false);
await buildLink.click();
await buildLink.hover();
const tooltip = sidebar.locator("openclaw-sidebar-build-chip openclaw-tooltip wa-tooltip");
await expect.poll(() => tooltip.evaluate((element) => element.hasAttribute("open"))).toBe(true);
const buildLinkHandle = await buildLink.elementHandle();
if (!buildLinkHandle) {
throw new Error("Expected the identity-menu build link to be attached");
}
const afterHideMarker = "data-openclaw-test-after-hide";
await tooltip.evaluate((element, marker) => {
element.removeAttribute(marker);
element.addEventListener("wa-after-hide", () => element.setAttribute(marker, ""), {
once: true,
});
}, afterHideMarker);
await page.mouse.down();
await expect
.poll(() =>
tooltip.evaluate((element, marker) => element.hasAttribute(marker), afterHideMarker),
)
.toBe(true);
expect(await buildLinkHandle.evaluate((element) => element.isConnected)).toBe(true);
await tooltip.evaluate((element, marker) => element.removeAttribute(marker), afterHideMarker);
await page.mouse.up();
await expect.poll(() => new URL(page.url()).pathname).toBe("/settings/about");
}
@@ -78,7 +100,7 @@ async function assertFullBranchLabel(page: Page) {
}
suite.define(() => {
it("renders intact emoji at compact and metadata boundaries across navigation and reload", async () => {
it("keeps slow build-link navigation intact across Unicode boundaries and reload", async () => {
await suite.withPage(
{
locale: "en-US",