ckerr

#55287: test: wait for an active window before sending menu shortcuts

Merged
Created: Oct 23, 2026, 2:10:46 PM
Merged: Oct 26, 2026, 3:26:58 AM
6 comments
Target: main

Description of Change

The setIgnoreMenuShortcuts specs sometimes timed out on Windows CI waiting for an honored F13 to invoke the menu.

On Windows and Linux, views hands accelerators only to the active window (View::CanHandleAccelerators). The specs waited for page or DevTools focus, which can be set inside an inactive window. The docked-DevTools and webview loops didn't wait for any focus. When the window wasn't active, an honored F13 never reached the menu, and waitUntil timed out after 10 seconds.

Before each press, sendShortcut() now:

  • focuses the window if needed and waits for isFocused(). On macOS it first takes activation with app.focus({ steal: true }), because window.focus() can't activate the app while another app is frontmost.
  • for the webview, focuses the guest and waits for document.hasFocus() there.
  • waits for the target page to be visible. The browser doesn't offer keys from a hidden widget to the menu, and Windows marks a covered window hidden until a while after it is raised. The windows are also alwaysOnTop on Windows, as in the WebContentsView visibility specs.

The press itself also changed:

  • The keyDown now goes through CDP on every platform, like the keyUp already did.
    • sendInputEvent targets the main widget while CDP targets the focused frame, so in the webview loop the two events could reach different renderers.
    • Off macOS, the keyDown carries a native key code, because CDP marks key events without one skip_if_unhandled, which keeps them away from the menu. The macOS event is unchanged.
  • The count is read as soon as the keyUp is answered.
    • The widget acks events in order, and the browser offers an unhandled keyDown to the menu while handling its ack. So by the time the keyUp is answered, the keyDown has either invoked the menu or been ignored.
    • This replaces waitUntil(() => invocations >= expected), which returned at once for the ignored presses.

The docked-DevTools spec no longer waits for devtools-focused, which the activation wait makes redundant.

Validation on Linux under Xvfb, with retries off:

  • The block passed 20/20 runs, then 10/10 after the last cleanup, 5 tests each.
  • Blurring the window before the presses reproduces the CI timeout on main. With this change, the specs pass that way.
  • A spec edited to honor a shortcut it should ignore still fails at that step, in under half a second.

Not run on Windows or macOS. On macOS the menu path itself doesn't need a key window, so the new activation wait adds that requirement to the docked-DevTools and webview specs there. The initial-preference spec already needed one.

🤖 Generated with Claude Code

Checklist

Release Notes

Notes: none

Backports

43-x-y
Merged
PR Number
#55355
Merged At
Oct 26, 2026, 10:21:10 AM
Released In
Not yet
Release Date
Not yet
44-x-y
Merged
PR Number
#55356
Merged At
Oct 26, 2026, 10:20:51 AM
Released In
Not yet
Release Date
Not yet
45-x-y
Merged
PR Number
#55357
Merged At
Oct 26, 2026, 10:21:37 AM
Released In
Not yet
Release Date
Not yet
46-x-y
Merged
PR Number
#55358
Merged At
Oct 26, 2026, 10:21:47 AM
Released In
v46.0.0-alpha.2
Release Date
Oct 26, 2026, 3:00:25 PM

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron