我想就这个问题展开讨论,因为我也有类似的问题:
我想要cy.get('#lead_name').type('foo')
,但它被这个元素覆盖,不透明度为0.9,而表单正在加载:
<div class="blockUI blockOverlay" style="z-index: 1000; border: none; margin: 0px; padding: 0px; width: 665px; height: 100%; top: 0px; left: 0px; background-color: rgb(0, 0, 0); opacity: 0.9; cursor: wait; position: absolute;"></div>
当我以断言
开始时cy.get('#lead_name').should('be.visible)
它传递断言(可能是因为不透明?),但是当我尝试在字段中键入时,我得到错误消息,该元素已被覆盖。
当我试图断言叠加不再存在并添加
时cy.get('.blockUI blockOverlay').should('not.exist')
Cypress也传递断言,即使元素确实存在并且覆盖了另一个元素并且cy.get('#lead_name').type('foo')
失败。
有没有办法解决这个问题?
//This does not work it's just a sample to explain what I want to do
//test if the element I want to get is not covered
cy.get('#lead_name').should('not.be.covered')
//or test if the element is actionable
cy.get('#lead_name').should('be.actionable')
确保它等待表单加载完成?
{edit}这是我从Cypress得到的错误信息:
Timed out retrying after 4000ms: cy.type() failed because this element:
<input name="CrmLead[first_name]" id="CrmLead_first_name" type="text" maxlength="255">
is being covered by another element:
<div class="blockUI blockOverlay" style="z-index: 1000; border: none; margin: 0px; padding: 0px; width: 665px; height: 100%; top: 0px; left: 0px; background-color: rgb(0, 0, 0); opacity: 0.9; cursor: wait; position: absolute;"></div>
{edit 2}这是我使用的代码,浓缩到相关部分:
it('should select new lead', () {
cy.visit(Cypress.env('lead_url'))
cy.get('#new_lead).click() //this opens the new form which takes some time to load
cy.get('#lead_name').type('foo')
cy.get('#lead_last_name').type('bar')
cy.get('.button').click()
}
{edit 3}我对可能的解决方案测试得越多,我就越确信问题不在于覆盖,而在于Cypress代码本身。
当我手动打开表单时,加载旋转器消失的时间不会超过1秒,通常只需要0.1-0.2秒。
然而,当Cypress打开表单时,表单无法正确加载,因为加载旋转器无限期地停留在那里。
检查覆盖应该分两步完成。
cy.get('.blockUI.blockOverlay')
.should('exist')
.then($overlay => $overlay.remove())
cy.get('.blockUI.blockOverlay').should('not.exist')
cy.get('#lead_name', {timeout: 10000})
.should(($el) => { // should will cause retry
return Cypress.dom.isFocusable($el) // instead of visible, more relevent to actionability
})
如果你只执行第二步,Cypress会在之前传递命令叠加存在。
这与检查加载旋转器的原理相同,之前已经在SO中处理过了。
顺便说一句,你选择的元素有两个分类(根据错误消息),所以你需要两个.
在选择器。
也许这是你唯一需要的改变!
我在上面添加了另一个可能有用的检查。Cypress.dom.isFocusable
.
From docs Is focusable
Cypress内部在任何地方都使用这个方法来确定元素是否被隐藏,主要是为了可操作性。
如果你真的卡住了,看看Gleb Bahmutov的演练视频在这里调试Cypress中的元素可见性问题
还有一个想法-您可以尝试在测试中删除覆盖覆盖-在上面的示例中添加一行。
可以将{force: true}
与type()
一起使用。这将忽略其他元素的重叠。
cy.get('#lead_name').type('foo', {force: true})
或者如果你想断言元素有opacity 0.9
,你可以使用:
cy.get('.blockUI blockOverlay')
.should('have.attr', 'style')
.and('include', 'opacity: 0.9')
或者,你可以等待元素没有不透明度,在这种情况下,你可以使用:
cy.get('.blockUI blockOverlay', {timeout: 7000})
.should('have.attr', 'style')
.and('not.include', 'opacity: 0.9')