将类传入Nightmare的evaluate调用静态方法时遇未定义问题求助
解决Nightmare evaluate传类静态方法失败及console.log的问题
我来帮你搞定这两个困扰你的问题:
一、为什么传递App类会报错?
Nightmare的evaluate方法是在浏览器上下文中执行代码的,它和Node.js主进程之间的数据传递依赖「序列化/反序列化」(类似JSON.stringify/parse的逻辑)。而类(包括它的静态方法)属于复杂对象,序列化时会丢失函数、原型链这些结构——也就是说,当你把App类传给evaluate后,浏览器上下文里拿到的driver其实是一个被“拆空”的对象,自然调用driver.resolve()会报Cannot read property 'resolve' of undefined。
解决方法
你有两种可行的方案:
方案1:直接把逻辑写到evaluate内部
如果你的静态方法逻辑不复杂,直接把代码搬到evaluate里就行:.evaluate(() => { // 直接实现resolve的逻辑 const resolveResult = true; console.log('resolve result', resolveResult); return document.getElementById("a").textContent; })方案2:抽离静态方法为独立函数传递
要是逻辑需要复用,别传整个类,单独把静态方法抽成普通函数传进去:// 先在Node上下文抽离函数 const appResolve = () => { return true }; // 然后把函数传给evaluate .evaluate((resolveFn) => { console.log('driver result', resolveFn()); return document.getElementById("a").textContent; }, appResolve)
二、evaluate里能不能用console.log?
完全可以,但默认情况下,浏览器上下文的console.log不会输出到你的Node.js控制台。要看到这些日志,你需要给Nightmare实例添加console事件监听,捕获浏览器的日志输出:
nightmare // 监听浏览器控制台输出 .on('console', (type, message) => { console.log(`[Browser ${type}]`, message); }) .goto("abc.com") // ... 后续代码
修改后的完整测试代码
// abc.test.ts it('should contain "abc" text in Href', (done) => { const appResolve = () => { return true }; nightmare .on('console', (type, message) => { console.log(`Browser console [${type}]:`, message); }) .goto("abc.com") .evaluate((resolveFn) => { console.log('driver result', resolveFn()); return document.getElementById("a").textContent; }, appResolve) .end() .then((response: any) => { expect(response).to.have.containIgnoreSpaces("abc"); done(); }) .catch((error: any) => console.log("Error", error)); });
另外你运行测试的npm命令是没问题的,确保所有依赖(nightmare、mocha、ts-node、jsdom-global等)都正确安装即可。
内容的提问来源于stack exchange,提问作者Abdul Qadir R.
相关产品推荐
相关产品推荐

