断言该元素在赛普拉斯中不可操作
Assert that element is not actionable in Cypress
如果某个元素在页面上不可操作(在本例中,被另一个元素覆盖)并且您尝试单击它,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', ...)
,因为这也不例外
在 click_spec.coffee 查看 Cypress 测试。
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(selector).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')
回调会处理点击失败(根据赛普拉斯自己的测试)。
不是一般性答案,但如果元素已知且已知重叠,则仅指定 z 索引可能就足够了:
cy.get('element1').should('have.css', 'z-index', '2');
cy.get('element2').should('have.css', 'z-index', '1');
如果某个元素在页面上不可操作(在本例中,被另一个元素覆盖)并且您尝试单击它,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', ...)
,因为这也不例外
在 click_spec.coffee 查看 Cypress 测试。
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(selector).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')
回调会处理点击失败(根据赛普拉斯自己的测试)。
不是一般性答案,但如果元素已知且已知重叠,则仅指定 z 索引可能就足够了:
cy.get('element1').should('have.css', 'z-index', '2');
cy.get('element2').should('have.css', 'z-index', '1');