Skip to content

test(desktop): stub the workbar menu popup in the WorkHub layout e2e - #6008

Merged
liugddx merged 1 commit into
apache:mainfrom
ggbdpq:fix/workhub-e2e-stub-menu-popup
Oct 9, 2026
Merged

liugddx merged 1 commit into
apache:mainfrom
ggbdpq:fix/workhub-e2e-stub-menu-popup

Conversation

@ggbdpq

@ggbdpq ggbdpq commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

workhub-layout.spec.ts opened a real native menu for the workbar's add-panel button and closed it with a scripted closePopup(window), guarded by a main-process workbarMenuOpen flag. On Linux CI the GTK popup can already be torn down (for example right after a window resize) while menu-will-close has not reached JS; the flag then still holds and closePopup crashes the Electron main process, killing the whole "Desktop e2e" step on byte-identical trees that had already passed CI. closePopup may also crash on a live popup in this window setup. This is failure 1 of #5995.

Every assertion in this segment is Maka state — aria-expanded, the dock backdrop, and the WorkHub WebContentsView's native visibility — none of which needs a real GTK menu. The change stubs Menu.prototype.popup so it records the probe and restores itself immediately (the later task-action menu in the same spec keeps the real popup), then simulates the close through the menu's own menu-will-close lifecycle event, driving the popup callback from it so the renderer's request resolves and aria-expanded drops through the same path a real menu uses. This removes closePopup, and both crash paths with it. Product code never calls closePopup, so the change is test-only.

Refs #5995 (the issue asks for the three failures to be fixed and closed separately, so this intentionally does not use a close keyword; failures 2 and 3 remain open there).

Verification

Check Result
workhub-layout.spec.ts on macOS arm64, before the change (baseline on upstream/main) 1 passed (14.8s)
Same test after the change 1 passed (12.0s)
Full spec file after the change (3 tests, incl. the real-popup task-action menu) 3 passed (28.2s)
npx biome check apps/desktop/e2e/workhub-layout.spec.ts clean
npm run typecheck (desktop workspace, 4 tsconfigs) clean
npm run check:asf-headers clean (4308 covered)
Linux CI reproduction of the crash not run — GTK-only crash, not reproducible on this machine; the fix removes the native popup/closePopup path the crash rides on

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: GLM-5.3-Flash (ZCode) — analyzed the crash path from #5995, implemented the stub, ran the local verification matrix, and drafted this PR.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

(The first box is intentionally unchecked: the change is the test — a test-only flaky fix has no separate product behavior for another test to cover. The before/after runs above are the evidence that the spec still passes with the stubbed popup.)

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

The spec opened a real native menu for the workbar's add-panel button and
then closed it with a scripted closePopup guarded by a main-process
workbarMenuOpen flag. On Linux CI the GTK popup can already be torn down
(e.g. after a window resize) while menu-will-close has not reached JS, so
the stale flag still holds and closePopup crashes the Electron main
process; closePopup could also crash on a live popup in that window
setup. This intermittently killed the "Desktop e2e" step on
byte-identical trees that had already passed CI (apache#5995, failure 1).

Every assertion in this segment is Maka state — aria-expanded, the dock
backdrop, and the WorkHub WebContentsView's native visibility — none of
which needs a real GTK menu. Stub Menu.prototype.popup so it records the
probe and restores itself immediately (the later task-action menu keeps
the real popup), simulate the close through the menu's own
menu-will-close lifecycle event, and drive the popup callback from it so
the renderer's request resolves and aria-expanded drops through the same
path a real menu uses. This removes closePopup, and both crash paths,
from the test. Product code never calls closePopup, so the change is
test-only.

Verified on macOS arm64: the spec passes before (14.8s) and after
(12.0s single / 28.2s full file, 3 passed) the change, with biome check
and check:asf-headers clean. The crash itself is Linux-only and was not
reproduced locally; the fix removes the native popup/closePopup path the
crash rides on.

Addresses apache#5995 (failure 1 of 3; the issue asks for the three failures
to be fixed and closed separately).

Generated-by: GLM-5.3-Flash (ZCode)
@github-actions github-actions Bot added the effort/S Under 100 readable lines label Oct 8, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.

Full review of 364b5955 (+23/-15, apps/desktop/e2e/workhub-layout.spec.ts, test-only).

The one-shot Menu.prototype.popup stub records the menu, restores the prototype, and returns without opening a native popup. Its menu-will-close listener calls options.callback, and the close step emits menu-will-close in the main process instead of calling closePopup. This matches popupNativeMenu in src/main/native-menu.ts, which clears openMenus and resolves the renderer request only from the popup callback. So aria-expanded drops through the real product path, and the closePopup crash site is removed. The mechanics are correct. The workbarMenuOpen guard is now always true at the close step, but it is harmless.

P3: inaccurate comment and lost native-popup coverage. The comment at line 132 says restoring the prototype "keeps the later task-action menu on the real native popup", and the PR body says the same. The later "任务操作" menu in this spec is a DOM role=menuitem menu and never calls Menu.popup. The workbar add-panel is the only renderer caller of window:popupMenu/popupNativeMenu. So after this change no e2e opens a real native menu, including next to the live WorkHub WebContentsView, which was this segment's original purpose. Removing the crash is worth that trade, but the comment should be corrected and the coverage loss noted in #5995.

Overlap with #6007. #6007 (liugddx) makes the same fix to the same hunks of workhub-layout.spec.ts: stub the popup, drive the callback from menu-will-close, drop closePopup. The two PRs will conflict textually, and only one should land. #6007 is a superset: it also fixes the #5995 §2 CDP-click flake in workhub-browser-presentation-smoke.mjs and asserts that the stub captured a menu with items. Landing #6007 and closing this PR is the simpler path. If this PR lands first, #6007 needs to drop its spec hunk.

No protocol files are touched, so there is no epoch impact. The PR is MERGEABLE. CI test passes on 364b5955, and Desktop e2e (which included the changed spec) passed 34/34.

No P0-P2 findings.

probe.workbarMenuOpen = true;
// Track the popup's own lifetime in the main process: Linux may
// auto-dismiss it (e.g. after a resize) at any moment.
// Restoring immediately keeps the later task-action menu on the real

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The later task-action menu ("任务操作") in this spec is a DOM role=menuitem menu and never calls Menu.popup. The workbar add-panel is the only popupNativeMenu caller. Restoring the prototype is still good hygiene, but this comment (and the PR body) overstate the remaining coverage: after this change no e2e opens a real native popup.

@liugddx liugddx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving exact head 364b5955a. This is the right fix for #5995 failure 1. The stub drives the popup's options.callback from menu-will-close, and that callback is what popupNativeMenu (src/main/native-menu.ts:47-48) waits on before resolving the renderer request and dropping aria-expanded. So the assertions still go through the real product path, and closePopup, the crash site, is gone from the test. CI passes on this head.

I've reduced #6007 to the native-smoke fix (failure 2) only, so the two PRs no longer overlap. You had already taken #5995.

Two non-blocking notes, either fine as a follow-up:

  • The comment "Restoring immediately keeps the later task-action menu on the real native popup" overstates it. The workbar add-panel is the only renderer caller of window:popupMenu/popupNativeMenu (workbar-surface.tsx:226), and the later "任务操作" menu is a DOM role=menuitem menu. After this change, no e2e opens a real native menu next to the live WorkHub WebContentsView. That's a reasonable trade for removing a main-process crash, and I've recorded it in #5995.
  • An assertion that the stub actually captured the workbar menu (for example probe.workbarMenu.items.length > 0) would catch a future change that stops routing this button through Menu.popup, which would otherwise silently skip the close path.

Thanks @ggbdpq.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants