Cypress如何获取div文本存入变量供后续使用及常见异步问题解决
问题原因解析
- 第一种写法失败核心是Cypress所有
cy开头的命令都是异步入队执行,你定义的同步id变量赋值在should回调中,但后续cy.type(id)入队时should回调还未执行,id还是初始值0,搜索无效导致表格行数仍然为25。 - 第二种写法死循环是因为
should方法自带重试机制:只要回调内抛出错误就会重复执行回调直到超时。你在should回调内写入了操作类Cypress命令,每次重试都会重复执行这些命令,最终触发无限循环。注意should仅用于断言,不要在其回调内执行业务操作类命令。 - 第三种写法的同步
expect语句执行顺序早于then回调,执行到expect(variables.id).not.to.be.undefined时,then回调还未运行,variables.id还未被赋值,自然断言失败。
正确实现方案
方案1:将依赖变量的操作全部放入then回调
这是最常用的写法,保证变量赋值完成后再执行后续操作
it('should filter', () => { cy.get('[data-cy=data-table-row]').should('have.length', 25); cy.get('[data-cy=data-table-row]:nth-child(1) > .cdk-column-id').then(($div1) => { const id = $div1.text(); expect(id).not.to.be.empty; // 所有依赖id的操作都放在回调内部 cy.get('[data-cy=table-filters-search]').find('input').type(id); cy.get('[data-cy=data-table-row]').should('have.length', 1); cy.get('[data-cy=data-table-row]:nth-child(1) > .cdk-column-id').should('have.text', id); }); });
方案2:用Cypress别名存储值
如果需要跨多个代码块使用该值,可以用as定义别名存储,后续通过@别名取值
it('should filter', () => { cy.get('[data-cy=data-table-row]').should('have.length', 25); // 直接调用invoke('text')获取文本,存为别名 cy.get('[data-cy=data-table-row]:nth-child(1) > .cdk-column-id') .invoke('text') .as('rowId') .should('not.be.empty'); // 取出别名值执行搜索 cy.get('@rowId').then(id => { cy.get('[data-cy=table-filters-search]').find('input').type(id); }); cy.get('[data-cy=data-table-row]').should('have.length', 1); // 比对结果 cy.get('@rowId').then(id => { cy.get('[data-cy=data-table-row]:nth-child(1) > .cdk-column-id').should('have.text', id); }); });
注意事项
- 所有依赖Cypress命令返回结果的逻辑,必须放在
then回调内执行,不要试图用同步变量在命令外部接收值 should仅用于断言操作,不要在其回调内写入业务类Cypress命令,避免触发重试死循环invoke('text')可以直接提取元素文本内容,比手动在回调中调用text()更简洁
内容的提问来源于stack exchange,提问作者r3plica
相关产品推荐
相关产品推荐

