From a930517791948d7ca89c685eaf6d69c22d03a019 Mon Sep 17 00:00:00 2001 From: chaxus Date: Tue, 3 Nov 2026 13:42:21 +0800 Subject: [PATCH] test(assistant): reach the import command from the previous control The command is the last tabbable element on the page. Firefox leaves focus on it when Tab runs off the end, so Tab then Shift+Tab landed on the control before it and the nightly Firefox run has failed since 2026-10-21. Shift+Tab then Tab arrives from the previous control in every engine. Co-Authored-By: Claude Opus 5.5 --- .../2026-11-03-firefox-tab-off-the-end.md | 37 +++++++++++++++++++ test/e2e/agent-interface-affordances.spec.ts | 5 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 docs/explorations/2026-11-03-firefox-tab-off-the-end.md diff --git a/docs/explorations/2026-11-03-firefox-tab-off-the-end.md b/docs/explorations/2026-11-03-firefox-tab-off-the-end.md new file mode 100644 index 00000000..77d37392 --- /dev/null +++ b/docs/explorations/2026-11-03-firefox-tab-off-the-end.md @@ -0,0 +1,37 @@ +# Firefox 夜间 4 条红:Tab 跑出页面末尾 + +`agent-interface-affordances.spec.ts` 的 "text controls and import fields remain recognizable" +(360/1280 × light/dark 共 4 条)从 2026-10-21 起在夜间 Firefox 上每次都红,与 11-03 的 +runner 换 26.04 无关(那之前就红;夜间是信号不是门禁,一直没人看)。 + +## 现象 + +``` +expect(locator).toBeFocused() failed — "Import structured result" 按钮 inactive +``` + +用例为了让按钮进入键盘焦点态(`:focus-visible`,断言 2px 实线 outline),先 `focus()`, +再 `Tab`、`Shift+Tab` 回来。 + +## 根因 + +本地 macOS Firefox 复现,探针打印 `document.activeElement`: + +- `focus()` 之后:Import structured result +- `Tab` 之后:**仍是** Import structured result +- `Shift+Tab` 之后:`.agent-view-back` + +这个按钮是**整页最后一个可 Tab 的元素**。Chromium 从末尾 Tab 出去再 Shift+Tab 会回到它; +Firefox 在没有浏览器外壳可去时把焦点留在原地,于是 Shift+Tab 退到了前一个控件。用例假设 +"后面还有东西",产品行为本身没错(末尾 Tab 离开页面是正常的)。 + +## 改动 + +改成从前一个控件进来:`focus()` → `Shift+Tab` → `Tab`。前面一定有可聚焦控件(返回按钮), +各引擎行为一致,outline 的断言不变。 + +## 验证 + +- 本地 Firefox:改前 4/4 红(复现),改后 4/4 绿。 +- 本地 macOS WebKit 改前改后都红:macOS 默认 Tab 不聚焦按钮(系统"键盘导航"设置),是本机 + 环境,CI 上的 Linux WPE WebKit 原本就是绿的;以分支上手动触发的 nightly 为准。 diff --git a/test/e2e/agent-interface-affordances.spec.ts b/test/e2e/agent-interface-affordances.spec.ts index 6146c413..99f54545 100644 --- a/test/e2e/agent-interface-affordances.spec.ts +++ b/test/e2e/agent-interface-affordances.spec.ts @@ -59,9 +59,12 @@ for (const width of [360, 1280]) { expect(surface.background).not.toBe('rgba(0, 0, 0, 0)'); expect(surface.background).not.toBe(surface.canvas); expect(surface.contrast).toBeGreaterThanOrEqual(4.5); + // Arrive from the previous control: the command is the last tabbable + // element on the page, and Firefox leaves focus on it when Tab runs off + // the end, so Tab then Shift+Tab lands on the control before it. await command.focus(); - await page.keyboard.press('Tab'); await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Tab'); await expect(command).toBeFocused(); await expect(command).toHaveCSS('outline-style', 'solid'); await expect(command).toHaveCSS('outline-width', '2px');