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

DeckGL画布点击后无元素添加至列表的CI环境问题排查

Cypress E2E测试DeckGL PointCloud点击不稳定(仅CI环境)

我正在用Cypress测试一个渲染DeckGL PointCloud图层的3D点云Web应用,测试逻辑是点击画布上的特定点后,该点应被添加到列表中。但仅在CI环境会出现不稳定问题:点击动作看似执行成功,但列表里没新增点;本地多次尝试都无法复现。我已经用了cypress-recurse的递归逻辑重试点击,但问题依然存在。

简化后的测试代码如下:

const hoverAndClickPoint = (canvasSelector, point) => {
    cy.get(canvasSelector)
        .trigger("mousemove", { clientX: point.x, clientY: point.y, force: true })
        .wait(500) // 有时需要但会被ESLint标记
        .click(point.x, point.y, { force: true });
};

cy.recurse(
    () => cy.get('.pointListContainer hds-list-item').its("length"),
    (length) => length > 0, 
    {
        log: true,
        timeout: 15000,
        delay: 1000,
    }
);

问题分析

  1. CI环境性能瓶颈:CI服务器资源通常比本地机器有限,DeckGL渲染3D点云的速度更慢,可能导致点击时目标点的交互逻辑还未完全绑定。
  2. 事件模拟精度不足:DeckGL的PointCloud基于WebGL渲染,Cypress原生的trigger/click可能无法精确命中WebGL内部的点元素,尤其在无头浏览器环境中坐标计算易出现偏差。
  3. 递归逻辑缺失动作重执行:当前的cy.recurse仅检查列表长度,没有在每次重试时重新执行点击操作,导致单次点击失败后无法触发新的尝试。

解决方案

1. 修复递归逻辑,将点击动作纳入重试循环

把点击操作整合到递归的执行函数中,确保每次重试都会重新触发点击:

const hoverAndClickPoint = (canvasSelector, point) => {
    return cy.get(canvasSelector)
        .trigger("mousemove", { clientX: point.x, clientY: point.y, force: true })
        .click(point.x, point.y, { force: true });
};

// 递归执行点击 + 结果校验
cy.recurse(
    () => {
        return hoverAndClickPoint("#canvas", {x: 100, y: 200})
            .then(() => cy.get('.pointListContainer hds-list-item').its("length"));
    },
    (length) => length > 0, 
    {
        log: true,
        timeout: 15000,
        delay: 1000,
        limit: 5 // 限制重试次数,避免无限循环
    }
);

2. 替换硬等待为渲染状态监听

利用DeckGL的rendered事件(若应用暴露了Deck实例)等待点云完全渲染:

// 等待DeckGL渲染完成
cy.window().then(win => {
    return new Cypress.Promise(resolve => {
        win.deck.on("rendered", resolve);
    });
});

hoverAndClickPoint("#canvas", {x: 100, y: 200});
cy.get('.pointListContainer hds-list-item').should('have.length.greaterThan', 0);

如果未暴露Deck实例,可通过WebGL上下文检查渲染状态:

cy.get(canvasSelector).then($canvas => {
    const gl = $canvas[0].getContext('webgl');
    return new Cypress.Promise(resolve => {
        const checkRender = () => {
            if (!gl.isContextLost()) {
                const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
                framebuffer ? resolve() : requestAnimationFrame(checkRender);
            } else {
                resolve();
            }
        };
        checkRender();
    });
});

3. 优化CI测试配置

  • 为CI环境分配更多CPU/内存资源,降低渲染延迟;
  • 在cypress.config.js中统一视口分辨率,避免坐标偏移:
    module.exports = {
      e2e: {
        viewportWidth: 1920,
        viewportHeight: 1080,
        browser: 'chrome',
        args: ['--disable-gpu', '--no-sandbox'] // 根据CI环境调整
      }
    };
    

4. 使用真实事件模拟

安装cypress-real-events插件模拟更接近真实用户的点击行为:

npm install cypress-real-events --save-dev

修改点击逻辑:

import 'cypress-real-events/support';

const hoverAndClickPoint = (canvasSelector, point) => {
    cy.get(canvasSelector)
        .realHover({ position: {x: point.x, y: point.y} })
        .realClick({ position: {x: point.x, y: point.y} });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:13:13