如何在页面中使用导入的函数.使用Jest在Puppeteer中进行评估?

Vit*_*aly 6 import module typescript jestjs puppeteer

我有一个TypeScript项目,它使用Jest进行单元测试,并且刚刚将Puppeteer添加到组合中,意图在客户端上运行一些测试.它工作正常,除非我尝试使用里面的导入函数page.evaluate.

例如,我有以下内容HdpiCanvas.test.ts:

import { createHdpiCanvas } from "./HdpiCanvas";

test("createHdpiCanvas", async () => {
    await page.setViewport({ width: 800, height: 600, deviceScaleFactor: 2 });
    let size = await page.evaluate(() => {
        const canvas = createHdpiCanvas(); // document.createElement('canvas');
        return [canvas.width, canvas.height];
    });
    console.log(size); // [600, 300] for HDPI canvas and [ 300, 150 ] for a regular one
});
Run Code Online (Sandbox Code Playgroud)

随着注释,document.createElement('canvas')测试运行得很好并且记录[ 300, 150 ].但是createHdpiCanvas()由于page.evaluate函数引发了以下错误:

Error: Evaluation failed: ReferenceError: HdpiCanvas_1 is not defined
    at __puppeteer_evaluation_script__:2:24
Run Code Online (Sandbox Code Playgroud)

实际createHdpiCanvas内部HdpiCanvas.ts定义如下:

export function createHdpiCanvas(width = 300, height = 150): HTMLCanvasElement {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    applyHdpiOverrides(canvas);
    return canvas;
}
Run Code Online (Sandbox Code Playgroud)

和本身依赖于所定义的其他功能HdpiCanvas.ts,如applyHdpiOverrides.

小智 5

在调用该函数之前,您可以这样做evaluate

await page.exposeFunction("applyHdpiOverrides",applyHdpiOverrides);
await page.exposeFunction("createHdpiCanvas",createHdpiCanvas);
Run Code Online (Sandbox Code Playgroud)

现在你的窗口将识别这些功能

  • 我已经尝试过了,但不想走这条路,原因有几个:必须一一公开它们,这很乏味,这些函数公开在页面的“window”对象上,而且我仍然遇到了这种方法的错误。 (2认同)

Kar*_*ski 5

Meni Roytenburd 建议的解决方案是正确的。如果您不喜欢每个函数都需要单独暴露给浏览器这一事实,那么您想到的唯一想法就是首先将您的项目转译为单个 JavaScript 文件,然后将其作为标签注入 \ <script>xe2\x80\x94就像你在现实生活中一样。

\n\n

第一步是使用您的包生成一个 JavaScript 文件。有时,这可以单独使用 TypeScript 编译器来完成,但也可以使用像 Webpack 这样的工具。

\n\n

完成后,您可以将包从 Puppeteer 中移动到客户端:

\n\n
await page.addScriptTag({ path: 'path/to/the/bundle' });\n
Run Code Online (Sandbox Code Playgroud)\n\n

请记住,这仍然可能会将您的函数暴露给全局范围,因此可以通过window.

\n\n
  let size = await page.evaluate(() => {\n      const canvas = window.createHdpiCanvas();\n      return [canvas.width, canvas.height];\n  });\n\n  console.log(size); // [ 300, 150 ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种方法的另一个缺点是必须处理 TypeScript \xe2\x80\x94 生成的警告,此时它不知道createHdpiCanvas上存在window,因此访问window.createHdpiCanvas将导致错误。

\n