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

使用Puppeteer+Jest测试时,ElementHandle无法赋值给Element的TS错误求助

解决Puppeteer+Jest测试中ElementHandle与DOM Element类型不匹配的问题

问题分析

你遇到的核心问题有两个:

  1. 环境混淆:window.getComputedStyle是浏览器端API,测试代码运行在Node.js环境中,无法直接调用浏览器上下文的API。
  2. 类型不匹配:page.$('#keys')返回的是ElementHandle<Element> | null——这是Puppeteer提供的DOM元素句柄,并非浏览器实际的Element对象,两者无法直接转换。

解决方案

要获取元素的计算样式,必须在浏览器上下文内执行相关逻辑,推荐两种实现方式:

方式一:使用evaluate方法(分步操作)

先断言元素存在以消除null类型问题,再通过evaluate传入元素句柄,在浏览器环境中获取样式:

import * as puppeteer from 'puppeteer';

describe('Puppeteer Test', () => {
    let browser: puppeteer.Browser;
    let page: puppeteer.Page;

    beforeAll(async () => {
        browser = await puppeteer.launch({
            headless: true,
            defaultViewport: null,
        });
        page = await browser.newPage();
        await page.goto('http://localhost:5500/dist/dummy.html');
    });

    test('`#keys` has display: flex after pressing `/`', async () => {
        const keysElement = await page.$('#keys');
        // 断言元素存在,消除null类型报错
        expect(keysElement).not.toBeNull();
        
        await page.keyboard.press('/');

        // 在浏览器上下文内获取计算样式
        const displayStyle = await page.evaluate((elem) => {
            return window.getComputedStyle(elem).display;
        }, keysElement!); // 因已做非空断言,用!标记元素不为null

        expect(displayStyle).toBe('flex');
    });

    afterAll(async () => {
        await browser.close();
    });
});

方式二:使用$eval方法(简洁版)

直接通过$eval定位元素并执行样式获取逻辑,无需单独处理ElementHandle:

import * as puppeteer from 'puppeteer';

describe('Puppeteer Test', () => {
    let browser: puppeteer.Browser;
    let page: puppeteer.Page;

    beforeAll(async () => {
        browser = await puppeteer.launch({
            headless: true,
            defaultViewport: null,
        });
        page = await browser.newPage();
        await page.goto('http://localhost:5500/dist/dummy.html');
    });

    test('`#keys` has display: flex after pressing `/`', async () => {
        await page.keyboard.press('/');

        // 直接定位元素并在浏览器上下文获取样式
        const displayStyle = await page.$eval('#keys', (elem) => {
            return window.getComputedStyle(elem).display;
        });

        expect(displayStyle).toBe('flex');
    });

    afterAll(async () => {
        await browser.close();
    });
});

关键说明

  • evaluate/$eval是Puppeteer用于在浏览器上下文执行代码的核心方法,所有操作DOM或调用浏览器API的逻辑都必须放在这些方法的回调中。
  • 用expect(keysElement).not.toBeNull()可以让TypeScript自动推断元素非空,比直接用!强制断言更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:25:20