如何使用 Jest 在 Puppeteer 中的 page.evaluate 中使用导入的函数? [英] How to use imported function inside page.evaluate in Puppeteer with Jest?

查看:34
本文介绍了如何使用 Jest 在 Puppeteer 中的 page.evaluate 中使用导入的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a TypeScript project that uses Jest for unit tests and have just added Puppeteer to the mix with the intention to run some tests on the client. It works fine, unless I try use imported functions inside page.evaluate.

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

For example, I have the following in 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
});

使用注释掉的 document.createElement('canvas') 测试运行得很好并记录 [ 300, 150 ].但是对于 createHdpiCanvas()page.evaluate 函数会抛出以下错误:

With the commented out document.createElement('canvas') the test runs just fine and logs [ 300, 150 ]. But with the createHdpiCanvas() the following error is thrown by the page.evaluate function:

Error: Evaluation failed: ReferenceError: HdpiCanvas_1 is not defined
    at __puppeteer_evaluation_script__:2:24

HdpiCanvas.ts中实际的createHdpiCanvas定义如下:

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

本身依赖于HdpiCanvas.ts中定义的其他函数,比如applyHdpiOverrides.

and itself depends on other functions defined in HdpiCanvas.ts, like applyHdpiOverrides.

推荐答案

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

The solution suggested by Meni Roytenburd is correct. If you don't like the fact that every function needs to be exposed to the browser separately, the only idea that comes to mind is transpiling your project to a single JavaScript file first and then injecting it as a <script> tag — just like you would in real life.

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

The first step would be to generate a single JavaScript file with your bundle. Sometimes this can be accomplished with the TypeScript compiler alone, but a tool like Webpack can be used, too.

完成后,您可以将捆绑包从 Puppeteer 中移至客户端:

Once it's done, you can move your bundle to the client from within Puppeteer:

await page.addScriptTag({ path: 'path/to/the/bundle' });

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

Keep in mind this still may expose your functions to the global scope, hence accessing them via window.

  let size = await page.evaluate(() => {
      const canvas = window.createHdpiCanvas();
      return [canvas.width, canvas.height];
  });

  console.log(size); // [ 300, 150 ]

这种方法必须处理 TypeScript 生成的警告的另一个缺点——此时它不知道 createHdpiCanvas 存在于 window 上,因此访问 window.createHdpiCanvas 会导致错误.

Another downside to this approach to having to deal with the warnings generated by TypeScript — at this point it doesn't know that createHdpiCanvas exists on window, so accessing window.createHdpiCanvas will cause an error.

这篇关于如何使用 Jest 在 Puppeteer 中的 page.evaluate 中使用导入的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆