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

Puppeteer ESM导入时Locator.race报错问题排查与解决

Puppeteer ESM导入后puppeteer.Locator.race报错的原因与解决方案

错误原因

Puppeteer的CommonJS和ESM导出结构存在差异:

  • CommonJS模式下,require('puppeteer')会返回包含所有API(包括Locator类)的完整对象,所以puppeteer.Locator能正常访问。
  • ESM模式下,默认导出的puppeteer仅包含核心API集合,Locator是独立的具名导出项,直接用import puppeteer from 'puppeteer-core'无法获取到Locator,导致puppeteer.Locator为undefined,调用.race时触发TypeError。

解决方案(最小修改录制脚本)

方案1:单独导入Locator类

只需新增一行导入语句,然后将脚本中puppeteer.Locator.race替换为Locator.race,其余录制代码完全保留:

// const puppeteer = require('puppeteer'); // 原CommonJS导入
import puppeteer from 'puppeteer-core';
import { Locator } from 'puppeteer-core'; // 新增具名导入

(async () => {
    // ... 原录制脚本内容不变
    {
        const targetPage = page;
        await Locator.race([ // 仅修改此处的调用前缀
            targetPage.locator('app-header li:nth-of-type(1) > a'),
            targetPage.locator('::-p-xpath(/html/body/app-root/app-layout/app-header/nav/div/div/ul/li[1]/a)'),
            targetPage.locator(':scope >>> app-header li:nth-of-type(1) > a'),
            targetPage.locator('::-p-aria( Override User)'),
            targetPage.locator('::-p-text(Override User)')
        ])
            .setTimeout(timeout)
            .click({
              offset: {
                x: 68.199951171875,
                y: 11.625,
              },
            });
    }
    // ... 后续脚本内容不变
})();

方案2:使用命名空间导入(无需修改录制脚本)

将ESM导入方式改为命名空间导入,一次性获取Puppeteer的所有导出项,这样原脚本中的puppeteer.Locator.race可以完全保留,无需任何修改:

// const puppeteer = require('puppeteer'); // 原CommonJS导入
import * as puppeteer from 'puppeteer-core'; // 改为命名空间导入

(async () => {
    // 所有录制脚本内容完全不变,包括 puppeteer.Locator.race 的调用
})();

这两种方案都不需要大幅改写录制脚本,完美适配Mocha测试环境,同时保留了Chrome录制器生成的Locator.race逻辑,避免了用Promise.race替代的繁琐修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:32:44