【问题标题】:invoke() method on cypress doesn't work if called twice如果调用两次,cypress 上的 invoke() 方法将不起作用
【发布时间】:2021-09-10 12:33:59
【问题描述】:

我是赛普拉斯的新手,我正在尝试使用现有网页实现一些简单的测试。我对结果有点困惑,因为我调用了两次 invoke():第一次检查初始值 (0%),第二次设置新值并检查更改,但它没有t 工作,它告诉我它找不到我正在搜索的属性。代码如下:

describe('My first test', function(){
    beforeEach(() => {
        cy.visit("https://www.wikiwand.com/en/IPv4")
    })
    it('test1', function() {
        const opt = cy.get("#main_menu > li").eq(3).click()
        const sty = opt.get(".noUi-origin").first()
        sty.invoke("attr", "style").should("include", "left: 0%;")
        sty.invoke("attr", "style", "left: 100%;").should("have.attr", "style", "left: 100%;")
         
        
    })
})

我只需点击菜单栏上的个性化按钮,我想更改 serif 或 sans 的值。两个invoke()的顺序有问题?错误是:

*Timed out retrying after 4000ms: cy.invoke() errored because the property: attr does not exist on your subject.
cy.invoke() waited for the specified property attr to exist, but it never did.
If you do not expect the property attr to exist, then add an assertion such as:
cy.wrap({ foo: 'bar' }).its('quux').should('not.exist')*

sty.invoke("attr", "style", "left: 100%;").should("have.attr", "style", "left: 100%;")

有人知道吗?

【问题讨论】:

  • 所以你的元素在 style 属性下同时提到了 left: 0%;left: 100%; ?如果您可以共享元素的整个 html,那就太好了。
  • @AlapanDas 它是维基百科wikiwand.com/en/IPv4 上的网页,您可以通过inspect 看到那里的html。左边是在html下的style属性,是的。
  • 是的,我后来知道了。我已经回答了你的问题,你可以检查一下。

标签: testing automated-tests cypress invoke


【解决方案1】:

所以当字体滑块为 Serif 时,样式为 left: 0%;,而当您将滑块拖动到 Sans 时,样式为 left: 100%;。所以你的测试应该是这样的:

cy.visit("https://www.wikiwand.com/en/IPv4");
cy.get("#main_menu > li").eq(3).click();
cy.get(".noUi-origin")
  .first()
  .invoke("attr", "style")
  .should("include", "left: 0%;");
cy.get('[ng-click="$root.fontStyleHandler(1, true)"]').click(); //Drags the slider from Serif to Sans
cy.get(".noUi-origin")
  .first()
  .invoke("attr", "style")
  .should("include", "left: 100%;");

或者,如果您不想使用滑块,那么您必须先删除样式属性,然后添加值为 left: 100%; 的样式属性,在这种情况下,您的测试应该如下所示:

cy.visit("https://www.wikiwand.com/en/IPv4")
cy.get("#main_menu > li").eq(3).click()
cy.get(".noUi-origin")
  .first()
  .invoke("attr", "style")
  .should("include", "left: 0%;")
cy.get(".noUi-origin").first().invoke("removeAttr", "style")
cy.get(".noUi-origin").first().invoke("attr", "style", "left: 100%;")
cy.get(".noUi-origin")
  .first()
  .invoke("attr", "style")
  .should("include", "left: 100%;")

【讨论】:

  • 谢谢。前 6 行很清楚,但我对其他行有点麻烦:第 7 行是从哪里来的?为什么我根本无法使用调用来更改值?
【解决方案2】:

Cypress 命令以“链”形式运行,当前“主题”从一个命令传递到下一个命令。

虽然您认为您保存的是对 const sty = ... 中元素的引用,但实际上您保存的是指向内部赛普拉斯主题的指针。

当您执行sty.invoke("attr", "style") 时,您现在已将主题更改为该样式属性,而不是元素。

因此,当您再次尝试 sty.invoke("attr", "style") 时,sty 不再有 attr 方法,因此出现错误。

更常规的方式是不存储命令结果。

重新查询

const opt = cy.get("#main_menu > li").eq(3).click()

cy.get(".noUi-origin").first()
  .invoke("attr", "style")
  .should("include", "left: 0%;")

cy.get(".noUi-origin").first()
  .invoke("attr", "style", "left: 100%;")
  .should("have.attr", "style", "left: 100%;")

或者使用不改变主题的断言

const opt = cy.get("#main_menu > li").eq(3).click()

cy.get(".noUi-origin").first()
  .should("have.css", "left", "0px")       // keeps the same subject
  .invoke("attr", "style", "left: 100%;")
  .should("have.attr", "style", "left: 100%;")

【讨论】:

  • 非常感谢,代码真的很清楚,但是我有点怀疑为什么 attr 不存在了。我知道我正在使用指针,但为什么 attr 会发生变化?我的意思是,我不会更改属性“style”的名称,我只是检查它的值。
  • 改变的不是属性“样式”,而是赛普拉斯主题。最初主题指向元素,但invoke() 将主题更改为指向属性值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
相关资源
最近更新 更多