Cypress技术问询:遍历交易列表按规则执行退款相关操作的测试用例开发与优化
问题分析与代码优化:基于Cypress的交易列表遍历测试用例
需求概述
需要遍历交易列表中的每一笔交易,根据不同特征执行对应操作:
- 对于可点击且带有"Remove allocation"垃圾桶图标的交易:点击删除按钮,确认删除后滚动至顶部,继续下一笔
- 对于可点击但无垃圾桶图标的交易:直接跳过
- 对于**不可点击(点击无响应)**的交易:直接跳过
现有代码的核心问题
你的代码存在几个关键问题,都是因为没吃透Cypress的异步特性和元素定位逻辑导致的:
- 同步for循环不兼容Cypress异步操作:Cypress的命令都是异步执行的,普通for循环会在Cypress命令完成前就跑完,导致
count值混乱,遍历逻辑完全失效。 cy.contains()的错误用法:if(cy.contains('Remove alocation'))这种写法是错误的,cy.contains()返回的是Cypress链式命令对象,不是布尔值,无法直接用于条件判断。而且你还拼写错了"allocation"(写成了alocation)。- 手动修改
count值无效:在Cypress命令里手动count=count+1是没用的,因为异步命令的执行时机和循环的同步逻辑完全脱节。 - 元素定位逻辑不严谨:直接用
eq(count)定位元素,但删除操作后列表可能会重新渲染,索引会变化,原来的eq(count)会定位错误的元素。 - 硬编码等待时间不可靠:
cy.wait(1500)这种固定等待时间很脆弱,页面加载慢的时候会失败,加载快的时候会浪费时间,应该用Cypress的断言等待来替代。
优化后的测试代码
我们需要用Cypress的each()命令来遍历元素(它天然支持异步遍历),结合条件判断和元素存在性检查来实现需求:
it('Find transaction for refund', function() { // 获取所有交易行,遍历每一个 cy.get('.text-center').each(($transactionRow, index) => { // 先尝试点击当前交易行,判断是否可点击 cy.wrap($transactionRow).click({ force: false }).then(() => { // 检查是否存在"Remove allocation"选项(注意拼写修正) cy.get('body').then($body => { if ($body.find(':contains("Remove allocation")').length > 0) { // 存在删除选项,执行删除流程 cy.get('.js-delete').eq(index).click() cy.contains('Yes').click() // 等待删除完成后滚动到顶部,用断言替代硬编码等待 cy.get('.text-center').should('have.length', Cypress.$('.text-center').length - 1) cy.scrollTo('top') } else { // 没有删除选项,直接跳过 cy.log(`Skipping transaction at index ${index} - no remove option`) } }) }).catch(() => { // 点击失败(交易不可点击),直接跳过 cy.log(`Skipping transaction at index ${index} - not clickable`) }) }) })
关键优化说明
- 用
each()替代for循环:cy.get('.text-center').each()会逐个遍历元素,并且等待每个元素的操作完成后再进行下一个,完美适配Cypress的异步特性。 - 正确的条件判断方式:用
$body.find(':contains("Remove allocation")').length > 0来检查元素是否存在,这是Cypress中可靠的条件判断方式。 - 处理不可点击的情况:用
.catch()捕获点击失败的异常,标记为不可点击的交易并跳过。 - 替换硬编码等待:用
cy.get('.text-center').should('have.length', Cypress.$('.text-center').length - 1)来断言列表长度变化,确保删除操作完成后再继续,比固定等待时间更可靠。 - 修正拼写错误:把"Remove alocation"修正为正确的"Remove allocation",避免匹配失败。
如果你需要从指定的行号(比如7到10,注意Cypress索引从0开始,对应索引6到9)开始遍历,可以修改为:
cy.get('.text-center').slice(6, 10).each(($transactionRow, index) => { const originalIndex = 6 + index // 获取原列表中的索引 // 后续逻辑同上 })
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

