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

如何在Jest环境下使用Puppeteer page测试任意ES6模块?

问题根因

ES6 模块的顶层作用域为独立的模块作用域,你通过 export default 导出的 MyFunction 默认不会挂载到浏览器全局 window 对象上,而 page.evaluate 执行的代码仅能访问浏览器全局作用域下的变量,因此直接调用会出现函数未定义的报错。

解决方案

方案1:修改原模块挂载到全局(实现成本最低)

在 MyModule.js 末尾追加代码,将导出的函数挂载到 window 全局:

// MyModule.js 原有逻辑
export default MyFunction;
// 新增挂载逻辑
if (typeof window !== 'undefined') {
  window.MyFunction = MyFunction;
}

调整 Puppeteer 执行逻辑,增加模块加载完成的等待判断:

await page.setContent(input);
await page.addScriptTag({
  path: 'path/to/function/MyModule.js',
  type: 'module',
});
// 等待函数挂载到全局,避免模块未加载完成就调用
await page.waitForFunction(() => window.MyFunction);
const actualFieldLabel = await page.evaluate(async (selector) => {
  const field = document.querySelector(selector);
  const result = await window.MyFunction(field);
  return result;
}, selector); // 注意将selector作为参数传入evaluate
expect(actualFieldLabel).toBe(output);

方案2:不修改原模块,在evaluate中动态导入

如果不需要改动原模块代码,可以直接在 page.evaluate 内通过动态导入语法加载ES模块,注意路径要匹配浏览器上下文可访问的地址:

await page.setContent(input);
const actualFieldLabel = await page.evaluate(async (selector) => {
  // 动态导入模块,路径需为浏览器可正常解析的地址
  const { default: MyFunction } = await import('/path/to/function/MyModule.js');
  const field = document.querySelector(selector);
  const result = await MyFunction(field);
  return result;
}, selector);
expect(actualFieldLabel).toBe(output);
注意事项
  • 原 MyModule.js 存在语法错误:你写的 const MyFunction => { 为非法语法,需修正为 const MyFunction = async () => {,如果内部包含异步逻辑需显式添加async关键字
  • 依赖路径校验:你的 MyModule 依赖 MySubModule,需确保所有依赖的路径在浏览器上下文都能正常解析,否则会出现模块加载失败的问题
  • 路径适配:如果使用动态导入方案,建议先启动本地静态服务,使用完整的http路径导入模块,避免相对路径解析错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:27:04