cypress - 单击 iframe 元素,几秒钟后 iframe 的主体发生变化

cypress - click iframe element while the body of the iframe change after few seconds

我在使用 cy.getIframeBody().find('#some-button') 时遇到问题,#some-button 元素尚不可用,因为 iframe 仍在加载,但 body 元素不为空,因此触发了 .find() .

这是获取 iframe 主体的自定义命令

Cypress.Commands.add('getIframeBody', ()=> {
    return cy.get('iframe.cy-external-link-container')
        .its('0.contentDocument.body')
        .should('not.empty')
        .then(cy.wrap)
});

不使用 cy.wait() 怎么办?

您可以添加超时并添加should('be.visible')。应该断言将确保在达到超时值之前它会重新启动并确保 iframe 已成功加载。

Cypress.Commands.add('getIframeBody', () => {
  return cy
    .get('iframe.cy-external-link-container', {timeout: 7000})
    .should('be.visible')
    .its('0.contentDocument.body')
    .should('not.empty')
    .then(cy.wrap)
})

您可以添加随机超时和 .should() 断言,但如果它们全部起作用,则测试可能不稳定。

关键是重复body元素的查询(这一行)

.its('0.contentDocument.body')

直到按钮出现。

所以不是

.its('0.contentDocument.body')
.should('not.empty')

但是像

.its('0.contentDocument.body')
.should('have.child', '#some-button')  // force a retry on body query

.should() 回调会做到这一点

Cypress.Commands.add('getIframeBodyWithSelector', (waitForSelector) => {
  return cy.get('iframe.cy-external-link-container')
    .its('0.contentDocument.body')
    .should(body => {
      expect(Cypress.$(body).has(waitForSelector).length).gt(0)
    })
    .then(cy.wrap)
})

it('finds some button', () => {
  cy.getIframeBodyWithSelector('#some-button')
    .find('#some-button')                      // passes
})