[MCP]: --extension --background: noDefaults skips focus emulation, hidden tabs get no rAF and clicks time out

未关闭
#44,096 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@microsoft-playwright-automation 已经在做这个了。

开始于 2026年11月13日。

  • #44101 来自 @microsoft-playwright-automation —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
25/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
typescript
领域
testing-qa

调研方向

Read packages/playwright-core/src/tools/mcp/extensionContextFactory.ts and packages/playwright-core/src/server/chromium/crPage.ts to trace how noDefaults affects focus emulation; compare the issue’s hidden-tab reproduction with focus emulation enabled. Check linked PR #44101, which is already open. Done means the reported background-tab click and Enter failures are addressed without overriding the user's browser defaults.

由索引模型根据 Issue 内容生成。

描述

agent-triage

Follow-up to #43868, as asked there: with extension 0.5.0 and @playwright/mcp 0.0.85, clicks and Enter still fail in --background tabs. In my setup focus emulation isn't enabled on the controlled tab.

What's going on?

In a tab controlled by @playwright/mcp --extension --background (not the active tab of its window), the page reports:

  • document.visibilityState === 'hidden', document.hasFocus() === false
  • 0 requestAnimationFrame callbacks in 2 s, and a 10 ms setTimeout loop runs about once per second

On https://en.wikipedia.org/wiki/Main_Page:

  • browser_click on the "Search" button fails with TimeoutError: browserBackend.callTool: Timeout 5000ms exceeded., and the call log ends at waiting for element to be visible, enabled and stable
  • browser_type with submit: true, and a later browser_press_key Enter, leave the page on Main_Page: the search is never submitted
Why

In #43868 the comment says Playwright enables focus emulation on each page. On main today, the extension path still connects with noDefaults: true (packages/playwright-core/src/tools/mcp/extensionContextFactory.ts, line 45):

const browser = await playwright.chromium.connectOverCDP(relay.cdpEndpoint(), { isLocal: true, timeout: 0, noDefaults: true });

In packages/playwright-core/src/server/chromium/crPage.ts (lines 547-552), noDefaults on the default context also skips focus emulation:

const skipDefaultOverrides = browserOptions.noDefaults &&
    this._crPage._browserContext === this._crPage._browserContext._browser._defaultContext;
...
if (this._isMainFrame() && !skipDefaultOverrides)
  promises.push(this._client.send('Emulation.setFocusEmulationEnabled', { enabled: true }));

I understand noDefaults is there so the extension doesn't override the user's existing browser defaults (#42117). Focus emulation goes with them, and it's the setting that lets a background tab render and pass actionability checks.

Repro without the extension

Plain connectOverCDP with noDefaults: true, against Chrome started with --remote-debugging-port=9334 and a fresh --user-data-dir:

const { chromium } = require('playwright-core');
(async () => {
  const b = await chromium.connectOverCDP('http://127.0.0.1:9334', { noDefaults: true });
  const ctx = b.contexts()[0];
  const bg = ctx.pages()[0];
  await bg.goto('https://example.com');
  const fg = await ctx.newPage(); await fg.goto('https://example.com'); await fg.bringToFront();
  const frames = () => bg.evaluate(async () => { const t0 = performance.now(); let n = 0;
    await new Promise(r => { const f = () => { n++; performance.now() < t0 + 2000 ? requestAnimationFrame(f) : r(); };
      requestAnimationFrame(f); setTimeout(r, 2500); });
    return { vis: document.visibilityState, raf: n }; });
  console.log(await frames());                                   // { vis: 'hidden', raf: 0 }
  await bg.click('a', { trial: true, timeout: 5000 }).catch(e => console.log('timeout'));  // timeout
  const s = await ctx.newCDPSession(bg);
  await s.send('Emulation.setFocusEmulationEnabled', { enabled: true });
  console.log(await frames());                                   // { vis: 'visible', raf: 97-103 }
  await bg.click('a', { trial: true, timeout: 5000 });           // ok
  await b.close();
})();

The same setup on the Wikipedia main page, filling the search box in the hidden tab and then pressing Enter or clicking "Search":

visibilityState Enter submits the search click on "Search"
focus emulation off hidden no (still on Main_Page after 8 s) Timeout 5000ms exceeded, waiting for "stable"
focus emulation on visible yes ok, 717 ms

Through the extension I couldn't turn it on from the MCP side: browser_run_code_unsafe with page.context().newCDPSession(page) returns Protocol error (Target.attachToBrowserTarget): {"code":-32000,"message":"Not allowed"}, and I found no option for it.

Suggestion

Keep noDefaults for the user's browser defaults, but enable Emulation.setFocusEmulationEnabled on the tabs the MCP controls in extension mode, at least with --background.

Version

@playwright/mcp 0.0.85 (playwright-core 1.66.0-alpha-2026-11-09), Playwright Extension 0.5.0, Google Chrome 157.0.8103.52, macOS 27.2, Node 20.6.1. The test in #43868 used Chromium 158.0.8127.2. I haven't tested 158.

主要语言
TypeScript
星标
99.7k
派生
6.8k
平均合并
16 小时 10 分钟
30 天内合并 PR
301

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/playwright 的其他 Issue

查看 microsoft/playwright 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。