断言该元素在赛普拉斯中不可操作

时间:2018-08-29 08:52:49

标签: automated-tests chai cypress

如果某个元素在页面上不可操作(在这种情况下,该元素已被另一个元素覆盖),而您尝试单击它,则赛普拉斯将显示如下错误:

CypressError: Timed out retrying: cy.click() failed because this element:

<span>...</span>

is being covered by another element:

太好了!但是有没有办法断言是这种情况,也就是无法单击该元素?

这不起作用:

  • should.not.exist-元素确实存在
  • should.be.disabled-元素未禁用
  • should.not.be.visible-元素可见(只是被另一个透明元素覆盖)
  • 使用cy.on('uncaught:exception', ...),因为这不是例外

2 个答案:

答案 0 :(得分:6)

请参见click_spec.coffee上的赛普拉斯测试。

it "throws when a non-descendent element is covering subject", (done) ->

  $btn = $("<button>button covered</button>")
    .attr("id", "button-covered-in-span")
    .prependTo(cy.$$("body"))

  span = $("<span>span on button</span>")
    .css(position: "absolute", 
         left: $btn.offset().left, 
         top: $btn.offset().top, 
         padding: 5, display: "inline-block", 
         backgroundColor: "yellow")
    .prependTo(cy.$$("body"))

  cy.on "fail", (err) =>
    ...
    expect(err.message).to.include "cy.click() failed because this element"
    expect(err.message).to.include "is being covered by another element"
    ...
    done()

  cy.get("#button-covered-in-span").click()

最简单的方法是模仿此测试,即使文档建议仅使用cy.on('fail')进行调试。

这类似于使用expect().to.throw()来检查异常是否按预期发生的单元测试,因此我认为这里的模式是合理的。

为更全面,我将打给click({force: true})的电话。

it('should fail the click() because element is covered', (done) => {

  // Check that click succeeds when forced
  cy.get('button').click({ force: true })

  // Use once() binding for just this fail
  cy.once('fail', (err) => {

    // Capturing the fail event swallows it and lets the test succeed

    // Now look for the expected messages
    expect(err.message).to.include('cy.click() failed because this element');
    expect(err.message).to.include('is being covered by another element');

    done();
  });

  cy.get("#button-covered-in-span").click().then(x => {
    // Only here if click succeeds (so test fails)
    done(new Error('Expected button NOT to be clickable, but click() succeeded'));
  })

})

作为自定义命令

我不确定如何创建所需的chai扩展名,但是逻辑可以包装在自定义命令中

/cypress/support/index.js

Cypress.Commands.add("isNotActionable", function(selector, done) {
  cy.get(selector).click({ force: true })
  cy.once('fail', (err) => {
    expect(err.message).to.include('cy.click() failed because this element');
    expect(err.message).to.include('is being covered by another element');
    done();
  });
  cy.get("#button-covered-in-span").click().then(x => {
    done(new Error('Expected element NOT to be clickable, but click() succeeded'));
  })
}) 

/cypress/integration/myTest.spec.js

it('should fail the click() because element is covered', (done) => {
  cy.isNotActionable('button', done)
});

注意

我期望done()在测试的前提(即按钮被遮盖)为假时超时。

这不会发生(原因未知),但是通过将.then()链接到第二次单击,可以调用done()并显示错误消息。仅在点击成功后才会调用then()回调,否则cy.once('fail')回调将处理点击失败(根据赛普拉斯自己的测试)。

答案 1 :(得分:0)

不是一般的答案,但如果元素已知且已知重叠,则仅指定 z 索引可能就足够了:

cy.get('element1').should('have.css', 'z-index', '2');
cy.get('element2').should('have.css', 'z-index', '1');