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, } );
问题分析
- CI环境性能瓶颈:CI服务器资源通常比本地机器有限,DeckGL渲染3D点云的速度更慢,可能导致点击时目标点的交互逻辑还未完全绑定。
- 事件模拟精度不足:DeckGL的PointCloud基于WebGL渲染,Cypress原生的
trigger/click可能无法精确命中WebGL内部的点元素,尤其在无头浏览器环境中坐标计算易出现偏差。 - 递归逻辑缺失动作重执行:当前的
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
相关产品推荐
相关产品推荐

