Ag Grid服务端行模型刷新吞点击问题及Cypress测试优化求助
问题根源分析
点击被吞的原因
在Server Side Row Model模式下,Ag Grid每6秒刷新数据(purge=false)时,会进入数据更新与DOM重渲染的过渡状态。此期间网格内部会暂时拦截或忽略用户交互事件,导致第6-7秒窗口内的点击无法触发行选中——即便单元格获得焦点,也会被网格的状态同步逻辑吞掉。而setSelected API直接操作网格的状态管理层,不受DOM渲染周期影响,因此能正常生效。
现有代码的多选问题原因
- DOM元素状态判断不可靠:用
.ag-row-selected类判断选中状态时,网格刷新会替换行DOM节点,$el1和$el2可能对应不同的DOM实例,导致状态对比逻辑失效。 - 固定等待时间的重试逻辑:
cy.wait(1000)无法精准匹配网格刷新完成时机,若重试点击发生在网格未完成旧选中状态清除时,会触发状态混乱,在单选模式下出现两行同时选中的异常。
更优实现方案
优先推荐直接使用Ag Grid API实现选行,完全规避DOM交互的不稳定问题;若必须模拟用户点击,需基于网格状态而非DOM进行逻辑判断。
方案1:直接调用Ag Grid API(最可靠)
通过API直接操作行选中状态,不受DOM刷新影响,同时确保单选模式下自动取消旧选中行:
export function selectRow(value: string) { // 从window获取网格实例(需确保Angular组件将gridApi暴露到全局,或通过组件实例获取) cy.window().then(win => { const gridApi = win.yourGridComponentInstance.gridApi; // 根据实际项目调整获取路径 // 匹配目标行的rowNode const targetRowNode = gridApi.getRowNodes().find(node => node.data.test === value); if (!targetRowNode) throw new Error(`未找到值为${value}的行`); // 选中目标行,第二个参数设为true确保单选模式下清除其他选中行 gridApi.setSelectedNodes([targetRowNode], true); // 验证选中状态 expect(targetRowNode.isSelected()).to.be.true; }); }
方案2:优化模拟点击逻辑(若需测试用户交互)
若必须模拟真实点击,需基于网格状态而非DOM进行重试与验证:
export function selectRow(value: string) { // 获取目标行的rowNode const getTargetRowNode = () => { return cy.window().then(win => { const gridApi = win.yourGridComponentInstance.gridApi; return gridApi.getRowNodes().find(node => node.data.test === value); }); }; // 等待网格加载完成(隐藏loading遮罩) cy.get('my-grid .ag-overlay-loading-wrapper').should('not.exist'); getTargetRowNode().then(targetNode => { // 点击目标行DOM getRow(value).click(); // 验证选中状态,未选中则等待网格刷新后重试 cy.wait(100).then(() => { getTargetRowNode().then(updatedNode => { if (!updatedNode.isSelected()) { // 等待网格数据更新完成(监听rowDataChanged事件) cy.window().then(win => { const gridApi = win.yourGridComponentInstance.gridApi; cy.wrap(null).should(() => { return new Cypress.Promise(resolve => { gridApi.addEventListener('rowDataChanged', resolve); }); }); }); // 再次点击目标行 getRow(value).click(); } // 验证单选模式下仅目标行被选中 expect(targetNode.gridApi.getSelectedNodes()).to.deep.equal([updatedNode]); }); }); }); } function getRow(value) { return cy.get('my-grid [col-id="test"]').contains(value); }
内容的提问来源于stack exchange,提问作者Flo Rida
相关产品推荐
相关产品推荐

