L_K*_*L_K 5 jquery chai cypress
这是我的测试代码的片段:
cy.get('div[data-component-data-id=301602] h2:first')
.should(($el) => {
expect($el).to.have.text('dress')
})
Run Code Online (Sandbox Code Playgroud)
cypress 抱怨这个断言:
CypressError: Timed out retrying: You attempted to make a chai-jQuery assertion on an object that is neither a DOM object or a jQuery object.
The chai-jQuery assertion you used was:
> text
The invalid subject you asserted on was:
> Object{3}
To use chai-jQuery assertions your subject must be valid.
This can sometimes happen if a previous assertion changed the subject.
Run Code Online (Sandbox Code Playgroud)
所以我必须更改expect($el).to.have.text('dress')为expect($el[0]).to.have.text('dress'),然后投诉被驳回并通过了测试。
我调试了一下断言,结果$el[0]也是一个 jquery 元素。
这是关于$el和的快照$el[0]:
所以我的问题是:不cy.get等于 jquery$吗?为什么我必须从 中获取第一个元素$el?为什么$el[0] is also a jquery element?
提前致谢。
编辑:
事实证明,当它包含 zepto 库时,此错误与应用程序代码有关。我在 Cypress Github 存储库中提出了一个问题,您可以跟踪进度。
我不太确定您现阶段要寻找什么,但已经找到了一种重置 zepto 库效果的方法。
总而言之,
zepto 是一个与 jquery 兼容的库,它接管$应用程序窗口引用上的全局
$ = 函数(选择器, 上下文) {
return zepto.init(选择器, 上下文)
}
结果是 cy 命令类似于.get()和.wrap()产生 jquery 结果的 zepto 包装形式,如果expect()没有一些解构,它与 chai 不兼容。
Cypress.$例如,进行实验时我发现这仍然引用 jquery propper
const h2 = Cypress.$('h2')
Run Code Online (Sandbox Code Playgroud)
返回一个 jquery 对象而不是 zepto 对象,因此我们可以$从 Cypress.$ 重置应用程序全局。
const h2 = Cypress.$('h2')
Run Code Online (Sandbox Code Playgroud)
重置代码可以合并到命令的覆盖中,cy.visit()以使其不那么普遍。
it('title display', () => {
cy.visit('index.html') // zepto takes effect here
// Reset $
const win = cy.state('window');
win.$ = Cypress.$;
cy.get('h2')
.should($el => {
expect($el).to.have.text('dress') // passes
})
})
Run Code Online (Sandbox Code Playgroud)
注意这会影响 zepto 在应用程序中的工作方式。
解决使 Zepto 正常运行的问题
此版本的cy.visit()覆盖将使 Zepto 库保持功能,但允许 Cypress.should()接收正确的 jQuery 对象。
本质上,我们添加自己的代理(在 zepto 的代理之上)并在每次调用时检查选择器的类型。
Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
return originalFn(url, options).then(_ => {
const win = cy.state('window')
win.$ = Cypress.$
})
})
...
it('title display', () => {
cy.visit('index.html')
cy.get('h2')
.should($el => {
expect($el).to.have.text('dress') // passes
})
})
Run Code Online (Sandbox Code Playgroud)
使用这个 html 片段来测试它。如果两个日志相同,zepto 不受影响。
<body>
<h2>dress</h2>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
<script>
console.log('from app, call #1', $('h2'))
setTimeout(() => {
console.log('from app, call #2', $('h2'))
}, 1000)
</script>
</body>
Run Code Online (Sandbox Code Playgroud)