Skip to main content
Cypress应用

invoke

调用先前生成对象上的函数。

info

如果你想获取先前生成对象上不是函数的属性,请使用 .its()

caution

如果你在 .invoke() 后继续链式调用其他命令,该函数会被多次调用。如果只想让方法被调用一次,请以 .invoke() 结束链式调用,然后重新开始使用 cy

语法

.invoke(functionName)
.invoke(options, functionName)
.invoke(functionName, args...)
.invoke(options, functionName, args...)

用法

正确用法

cy.get('.input').invoke('val').should('eq', 'foo') // 调用 'val' 函数
cy.get('.modal').invoke('show') // 调用 jQuery 的 'show' 函数
cy.wrap({ animate: fn }).invoke('animate') // 调用 'animate' 函数

错误用法

cy.invoke('convert') // 错误,不能直接链式调用 'cy'
cy.wrap({ name: 'Jane' }).invoke('name') // 错误,'name' 不是函数
cy.wrap({ animate: fn })
.invoke('animate')
.then(() => {}) // 'animate' 会被多次调用

参数

functionName (String, Number)

要调用的函数名称。

options (Object)

传入一个选项对象以改变 .invoke() 的默认行为。

选项默认值描述
logtrue命令日志中显示该命令
timeoutdefaultCommandTimeout等待 .invoke() 解析的超时时间,超过则超时

args...**

传递给函数调用的额外参数。参数数量没有限制。

生成结果 了解主题管理

  • .invoke() 返回方法的返回值。
  • .invoke() 是一个查询命令,可以安全地链式调用其他命令。
  • 如果在 .invoke() 后继续链式调用其他命令,该函数会被多次调用!

示例

函数

断言函数的返回值

const fn = () => {
return 'bar'
}

cy.wrap({ foo: fn }).invoke('foo').should('eq', 'bar') // true

使用 .invoke() 测试 HTML 内容

调用作为属性的函数

在下面的示例中,我们使用 .invoke() 强制隐藏的 div 变为 'display: block',以便与其子元素交互。

cy.get('div.container')
.should('be.hidden') // 元素是隐藏的
.invoke('show') // 调用 jQuery 的 'show' 方法
.should('be.visible') // 元素现在可见
.find('input') // 深入查找子元素 "input"
.type('Cypress is great') // 并输入文本

使用 .invoke('show').invoke('trigger')

带参数的函数

向函数传递特定参数

const fn = (a, b, c) => {
return a + b + c
}

cy.wrap({ sum: fn })
.invoke('sum', 2, 4, 6)
.should('be.gt', 10) // true
.and('be.lt', 20) // true

使用 cy.invoke('removeAttr', 'target') 避免新标签页

参数自动传递给函数

cy.get('img').invoke('attr', 'src').should('include', 'myLogo')

数组

在上述示例中,主题是对象,但 cy.invoke 也适用于数组,并允许使用数字索引选择要运行的函数。

const reverse = (s) => Cypress._.reverse(s)
const double = (n) => n * n

// 选择索引为 1 的函数并用参数 4 调用它
cy.wrap([reverse, double]).invoke(1, 4).should('eq', 16)

jQuery 方法

如果父命令生成一个 jQuery 元素,我们可以调用 jQuery 方法,如 attrtextval。例如,确认元素的 id 属性:

<div id="code-snippet">The code example</div>
cy.contains('The code example')
.invoke('attr', 'id')
.should('equal', 'code-snippet')

提示: Cypress 内置了 Chai-jQuery 断言来确认属性。上述示例可以简写为:

cy.contains('The code example').should('have.attr', 'id', 'code-snippet')

注意事项

第三方插件

使用 Kendo DropDown

如果你使用 jQuery,那么 jQuery 包装的元素会自动拥有可调用的第三方插件方法。

cy.get('input')
.invoke('getKendoDropDownList')
.then((dropDownList) => {
// 返回 $input.getKendoDropDownList() 的结果
return dropDownList.select('apples')
})

我们可以用更简洁的方式重写上面的示例,并添加断言。

cy.get('input')
.invoke('getKendoDropDownList')
.invoke('select', 'apples')
.invoke('val')
.should('match', /apples/)

重试

.invoke() 会自动重试调用指定的方法,直到返回值满足附加的断言。下面的示例在 1 秒后通过。

let message = 'hello'
const english = {
greeting() {
return message
},
}

setTimeout(() => {
message = 'bye'
}, 1000)

// 最初 english.greeting() 返回 "hello",断言失败。
// .invoke('greeting') 会不断重试,直到 1 秒后
// 返回的消息变为 "bye",断言通过
cy.wrap(english).invoke('greeting').should('equal', 'bye')
Invoke 重试示例

规则

要求 了解命令链

  • .invoke() 需要链式调用在前一个命令之后。

断言 了解断言

  • .invoke() 会等待主题上的 function 存在后再运行。
  • .invoke() 会在调用的 function 返回 promise 时抛出错误。如果你想调用返回 promise 的函数,请改用 .then()
  • .invoke() 会自动重试,直到所有链式断言通过。

超时设置 了解超时机制

  • .invoke() 可能会因等待附加的断言通过而超时。

命令日志

在元素上调用 jQuery show 方法

cy.get('.connectors-div')
.should('be.hidden')
.invoke('show')
.should('be.visible')

上述命令会在命令日志中显示为:

invoke 的命令日志

点击命令日志中的 invoke 时,控制台会输出以下内容:

invoke 的控制台日志

历史

版本变更
12.0.0.invoke() 不再支持 promise 或异步函数
3.8.0添加了对 options 参数的支持
3.7.0添加了对 functionName 为 Number 类型的参数的支持

另请参阅