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

Jest Puppeteer自定义测试环境中扩展Page类方法丢失问题

问题分析与解决方案

我一眼就看出了两个关键问题导致你遇到page.sendText is not a function的错误:

1. Jest GlobalSetup是独立进程,原型扩展不共享

Jest的GlobalSetup是在单独的进程中运行的,你在那里对Page.prototype的修改只会作用于那个进程,不会影响到执行测试的主进程。当你在测试进程中用puppeteer.connect()连接已有浏览器时,新创建的Page实例来自测试进程里的原始Puppeteer Page类,自然没有你添加的sendText方法。而直接在测试里launch浏览器时,扩展代码是在测试进程内执行的,所以原型修改生效了。

2. 箭头函数导致的this绑定错误

就算你解决了进程问题,原来的sendText用箭头函数定义也会报错——箭头函数没有自己的this,它会捕获外层上下文的this,而不是指向调用它的Page实例,到时候你会遇到this.waitForSelector is not a function的新问题。


修复步骤

第一步:抽离扩展逻辑为独立模块

把你的Page扩展代码单独放在一个文件里,比如puppeteer-extensions.js:

// puppeteer-extensions.js
const puppeteer = require('puppeteer');
const Page = puppeteer.lib.Page.Page;

// 改用普通函数,确保this指向Page实例
Page.prototype.sendText = async function(selector, text) {
  const element = await this.waitForSelector(selector, { visible: true });
  await element.type(text);
};

第二步:在测试进程中加载扩展

确保你的扩展代码在测试进程中被执行,而不是只在GlobalSetup里。修改你的npm模块中的测试环境代码,在创建浏览器连接前先加载扩展:

// 你的测试环境代码
require('./puppeteer-extensions'); // 先加载扩展,修改当前进程的Page原型

this.global.__BROWSER__ = await puppeteer.connect({ browserWSEndpoint: wsEndpoint });

第三步:验证测试代码

你的测试代码不需要修改,现在重新运行测试,page.sendText应该可以正常调用了:

describe('awesome test', () => {
  it('something will be ok', async () => {
    const context = global.__BROWSER__.defaultBrowserContext();
    page = await context.newPage();
    await page.goto('https://google.com/')
    await page.sendText('#search', "puppeteer")
    await page.screenshot({path: 'google.png', fullPage: true})
  })
});

额外说明

如果你的npm模块需要让测试项目自动加载扩展,也可以在模块的入口文件中引入puppeteer-extensions.js,或者告诉用户在测试项目的jest.config.js的setupFilesAfterEnv数组中添加你的扩展模块路径,确保测试启动时自动执行扩展逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:15:53