我在后台页面中具有全局功能,如下所示:
window.myfn = function(){
return new Promise((resolve, reject) => { stuff; });
};
我正在使用Jest和Puppeteer。在我的test.js
文件中考虑以下问题:
async function getBackgroundPage() {
const targets = await browser.targets(),
backgroundPageTarget = targets.find(
target => target.type() === "background_page",
),
backgroundPage = await backgroundPageTarget.page();
return backgroundPage;
}
async function sendUpdate() {
const bgPage = await getBackgroundPage(),
argString = `() => window.myfn()`;
await bgPage.evaluateHandle(argString);
await sleep(30000);
}
getBackgroundPage
实际上是从docs复制而来的,所以我希望它是正确的。但是,sendUpdate()
无法正常工作。理想情况下,应该调用window.myfn
,但实际上不要调用它。我知道这是因为:
console.log
,因此如果调用它,应该会有一些日志输出。chrome://extensions
,并通过Inspect Views打开后台页面控制台,而我在那里找不到任何日志输出。后台页面和Jest控制台都没有错误。那是什么问题呢?为什么不调用该全局函数?
答案 0 :(得分:1)
为evaluateHandle
(和evaluate
)函数提供函数和提供字符串之间存在细微差别。
如果传递函数,则该函数将在页面内调用。如果传递字符串,则将在页面上下文中执行该字符串。这意味着这两行做不同的事情:
await bgPage.evaluate(() => console.log("test"););
await bgPage.evaluate('() => console.log("test");');
第一行将在页面内执行该函数(并运行console.log
)。但是,第二行将仅声明该函数,而不会调用它。因此,如果我们传递字符串,则必须执行以下操作之一:
await bgPage.evaluate('console.log("test")'); // directly run console.log
await bgPage.evaluate('(() => console.log("test"))()'); // execute the function
修正代码
回到您的代码,这意味着您要么直接调用window.myfn()
,要么将参数作为函数传递:
await bgPage.evaluateHandle('window.myfn()'); // directly call the function
await bgPage.evaluateHandle(() => window.myfn()); // or pass as a function and not as string