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

Jest测试无法访问Puppeteer Proxy:#frameManager私有成员读取错误

解决Jest测试中Puppeteer Proxy访问私有成员报错问题

你遇到的TypeError: Cannot read private member #frameManager from an object whose class did not declare it错误,根源在于Proxy的get陷阱直接返回了Puppeteer Page/Browser实例的属性。当调用close()这类方法时,方法内部访问私有成员#frameManager时,this指向的是Proxy对象而非原始的Page/Browser实例,导致私有成员的访问权限验证失败。

修复方案

修改Proxy的get逻辑,确保访问Page/Browser的方法时,将方法的this绑定到原始的Page/Browser实例上,而非直接返回方法引用。

修改后的CustomPage代码

const puppeteer = require("puppeteer");

class CustomPage {
  static async build() {
    const browser = await puppeteer.launch({
      headless: false,
    });
    const page = await browser.newPage();
    const customPage = new CustomPage(page);
    
    return new Proxy(customPage, {
      get: function (target, property) {
        // 优先使用自定义页面的属性/方法
        if (customPage[property]) {
          return customPage[property];
        }
        // 处理Browser的属性:函数绑定Browser实例作为this
        if (browser[property]) {
          return typeof browser[property] === 'function' 
            ? browser[property].bind(browser) 
            : browser[property];
        }
        // 处理Page的属性:函数绑定Page实例作为this
        if (page[property]) {
          return typeof page[property] === 'function' 
            ? page[property].bind(page) 
            : page[property];
        }
      },
    });
  }
  
  constructor(page) {
    this.page = page;
  }
  
  getContentsOf(selector) {
    return this.page.$eval(selector, el => el.innerHTML);
  }
}

module.exports = CustomPage;

原理说明

通过bind()方法将Browser/Page实例绑定到对应的方法上,确保方法执行时内部的this指向原始实例,这样访问私有成员#frameManager时,就符合Puppeteer类的私有成员访问规则,不会触发权限错误。测试代码无需修改,保持原有逻辑即可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:15:22