Cypress从邮件服务提取OTP存fixture,元素定位报错如何解决
报错原因
- 未等待iframe内部内容完全加载就执行元素查询,当网络或页面渲染速度较慢时,
$ele.contents().find()返回空的jQuery对象,cy.wrap()传入空对象时就会触发找不到元素的超时错误 - 固定时长的
cy.wait(2000)可靠性极低,无法适配不同环境下的页面加载速度波动 - 直接使用jQuery查找元素无法利用Cypress自带的自动重试机制,元素未渲染完成时查询直接返回空结果,不会自动重试
修复方案
替换手动jQuery查询逻辑,用Cypress原生的元素查询逻辑,利用自带的重试机制等待元素出现:
it.only('Otp Test', function () { cy.visit("https://www.mailinator.com/", { timeout: 30000 }) cy.get("#addOverlay").type("jd") cy.get("#go-to-public").click() // 替换硬等待为显式等待邮件列表行出现 cy.xpath("(//table/tbody/tr[1])[2]", {timeout: 15000}).click() // 等待iframe加载完成,获取iframe内部的body cy.get('#html_msg_body') .its('0.contentDocument.body', {timeout: 15000}) .should('not.be.empty') // 在iframe body范围内查找目标OTP元素 .find('body > table > tbody > tr:nth-child(3) > td > h2', {timeout: 15000}) .invoke('text') .then(OTP => { // 保存OTP到文件 cy.readFile("cypress/fixtures/Data.json").then((profile) => { profile.OTP = OTP cy.writeFile("cypress/fixtures/Data.json", profile); }) }) })
修复说明
- 所有元素查询都新增了自定义超时时间,适配邮件服务的加载速度
- 利用Cypress原生的
its()获取iframe内部文档,自动重试直到iframe加载完成 - 直接在iframe的body范围内调用Cypress的
find()查询元素,自带重试逻辑,元素未出现时会自动重试到超时时间,不会直接返回空结果
内容的提问来源于stack exchange,提问作者Krupal Vaghasiya
相关产品推荐
相关产品推荐

