Jest搭配Puppeteer运行示例报URL未定义等错误如何解决
Puppeteer + Jest 运行通用示例代码两类报错解决方案
两类报错属于同一根因的连锁反应:
ReferenceError: URL is not defined是直接表现:测试执行环境中没有成功读取到配置里定义的URL变量,传入page.goto()的参数为undefinedProtocolError: Protocol error (Page.navigate): Invalid parameters Failed to deserialize params.url是衍生错误:Puppeteer调用Chrome DevTools协议做页面跳转时,url是必填字段,传undefined就会触发参数反序列化失败的报错
排查解决步骤
优先解决命名冲突问题
URL是JavaScript内置的原生构造函数(用于new URL()地址解析场景),不适合作为自定义变量名,很容易出现值被覆盖、注入失败的问题,直接把自定义的测试地址变量改名为TEST_URL或者BASE_URL即可规避这类冲突。检查Jest版本与配置兼容性
网上大部分老教程基于Jest 27及更早、jest-puppeteer 5.x及更早版本编写,新版Jest(29+)默认调整了全局变量注入逻辑:- 需要在
jest.config.js中开启injectGlobals: true配置,才会自动把globals节点下定义的变量、test/describe/beforeAll等API注入到测试上下文 - 不建议依赖全局注入传递测试地址,最稳妥的方式是直接在测试文件头部定义测试地址常量,完全避开配置加载、环境兼容问题:
const timeout = 10000; const TEST_URL = "https://sabe.io"; beforeAll(async () => { await page.goto(TEST_URL, { waitUntil: "domcontentloaded" }); }); // 后续测试逻辑保持不变即可- 需要在
检查配置文件加载路径
确认jest.config.js存放在执行jest命令的项目根目录下,执行测试时没有通过--config参数指定其他位置的配置文件,避免因配置加载失败导致全局变量丢失。
可直接运行的参考配置
修改后的jest.config.js:
module.exports = { preset: "jest-puppeteer", injectGlobals: true, globals: { TEST_URL: "https://sabe.io" }, testMatch: [ "**/test/**/*.test.js" ], verbose: true }
修改后的测试文件:
const timeout = 10000; beforeAll(async () => { await page.goto(TEST_URL, { waitUntil: "domcontentloaded" }); }); describe("Test title and header of the homepage", () => { test("Title of the page", async () => { const title = await page.title(); expect(title).toBe("Learn Web Development with free Classes and Tutorials - Sabe.io"); }, timeout); test("Header of the page", async () => { const h1Handle = await page.$("h1"); const html = await page.evaluate(h1Handle => h1Handle.innerHTML, h1Handle); expect(html).toBe("Become a better developer"); }, timeout); });
内容的提问来源于stack exchange,提问作者Michael.Andromeda
相关产品推荐
相关产品推荐

