【问题标题】:Assert that element is not actionable in Cypress断言该元素在赛普拉斯中不可操作
【发布时间】:2019-02-03 23:59:56
【问题描述】:

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

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', ...),因为这不是例外

【问题讨论】:

    标签: automated-tests chai cypress


    【解决方案1】:

    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(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') 回调会处理点击失败(根据赛普拉斯自己的测试)。

    【讨论】:

    • 这看起来很有希望 - 会尝试,并尝试将其包装为 chai 扩展名(例如is.actionable - 虽然不确定是否可能,因为它看起来非常具体)。在尝试使用force 查看点击是否成功时,您看到了什么价值?对于我要测试的具体案例,我的想法可能过于狭隘,所以我没有看到这里的重点?
    • 重新尝试force,这个想法是为了覆盖元素由于其他原因变得不可点击的情况,所以force然后失败了。我没有测试过,只是有点保险。
    • 有道理 - 遗憾的是,我还没有机会测试它,但我认为你的方式是正确的,所以我会接受这个作为答案,并希望尽快恢复看看它是否可以用 chai 包裹起来。
    • 这里的自定义命令不起作用。它依赖于来自it()done(),而这在命令中并不存在。
    • 我花了一天时间试图在我的项目中实现这个答案,但似乎没有任何效果。在这一点上,我怀疑赛普拉斯存在错误。当我单击原始测试中的覆盖元素时,操作失败。但是,当我从自定义命令内部单击时,单击成功。我什至尝试设置{force: false},这是我期望的默认值。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2018-11-09
      • 2021-12-22
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多