You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Playwright+Browserstack的Firefox无法读取剪贴板问题

问题

在Playwright结合Browserstack运行Firefox时,执行const clipboardText = await page.evaluate("navigator.clipboard.readText()");持续报错:

page.evaluate: navigator.clipboard.readText is not a function @debugger eval code line 208 > eval:1:21 evaluate@debugger eval code:208:30 @debugger eval code:1:44

本地直接启动Firefox时(不通过Browserstack),读取剪贴板功能完全正常,但这种方式无法连接到Browserstack。

Browserstack连接代码

test.beforeEach(async ({ playwright }, testInfo) => {
  test.setTimeout(2400000);
    patchCaps(testInfo.project.name, `${testInfo.title}`);
    browser = await playwright.firefox.connect({
      wsEndpoint:
        `wss://cdp.browserstack.com/playwright?caps=` +
        `${encodeURIComponent(JSON.stringify(caps))}`,
        firefoxUserPrefs: {
              'dom.events.asyncClipboard.readText': true,
              'dom.events.testing.asyncClipboard': true,
            },
    });
    context = await browser.newContext(testInfo.project.use);
  context = await browser.newContext()
  page = await context.newPage();

  await page.goto(`${url}/form`)
  await page.waitForTimeout(15000)

});

项目配置

{
  name: "playwright-firefox@latest:OSX Ventura@browserstack",
  use: {
    launchOptions: {
      firefoxUserPrefs: {
        'dom.events.asyncClipboard.readText': true,
        'dom.events.testing.asyncClipboard': true,
      },
    }
  },
},

本地正常启动代码

browser = await firefox.launch({
  firefoxUserPrefs: {
    'dom.events.asyncClipboard.readText': true,
    'dom.events.testing.asyncClipboard': true,
  },
})

原因

  1. 远程浏览器配置不生效:Browserstack的远程Firefox实例不会读取本地playwright.firefox.connect()中的firefoxUserPrefs,也不会读取项目配置里的launchOptions——这些配置只对本地启动的浏览器有效。远程浏览器的行为由Browserstack端的capabilities(即你传入wsEndpoint的caps对象)控制。
  2. 代码重复创建上下文:原代码中两次调用context = await browser.newContext(),第二次调用覆盖了第一次的上下文,导致任何通过testInfo.project.use传入的配置都失效。

解决方法

1. 将Firefox偏好配置到Browserstack的Capabilities中

把剪贴板相关的Firefox偏好添加到caps对象里,Browserstack会用这些配置初始化远程的Firefox实例。注意Browserstack使用firefox_user_prefs作为配置字段名(下划线格式,不是驼峰)。

2. 修正重复创建上下文的代码

确保只调用一次browser.newContext(),保留需要的配置。

修改后的完整代码示例

test.beforeEach(async ({ playwright }, testInfo) => {
  test.setTimeout(2400000);
  patchCaps(testInfo.project.name, `${testInfo.title}`);
  
  // 把Firefox剪贴板偏好添加到Browserstack的caps中
  caps['firefox_user_prefs'] = {
    'dom.events.asyncClipboard.readText': true,
    'dom.events.testing.asyncClipboard': true,
  };

  browser = await playwright.firefox.connect({
    wsEndpoint:
      `wss://cdp.browserstack.com/playwright?caps=` +
      `${encodeURIComponent(JSON.stringify(caps))}`,
  });
  
  // 仅创建一次上下文,保留项目配置
  context = await browser.newContext(testInfo.project.use);
  page = await context.newPage();

  await page.goto(`${url}/form`)
  await page.waitForTimeout(15000)
});

额外说明

项目配置里的launchOptions可以保留(用于本地调试),但在连接Browserstack时不会生效,所有远程浏览器的配置都需要通过caps对象传递。

内容的提问来源于stack exchange,提问作者zzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 17:28:18