cy.get return 无效 jquery 元素
cy.get return invalid jquery element
这是我的测试代码片段:
cy.get('div[data-component-data-id=301602] h2:first')
.should(($el) => {
expect($el).to.have.text('dress')
})
赛普拉斯抱怨这个断言:
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.
所以我必须将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库的应用程序代码有关。我在赛普拉斯 Github 存储库中提出了一个 issue,您可以跟踪进度。
我觉得使用 .and("contain", "dress")
可以解决您的问题。
编辑:
我已经在我的机器上尝试了 运行 与您的类似的片段。使用 should
似乎没有预期的结果,我遇到了同样的 jquery 奇怪的行为。然而,当使用 then
时,它就像一个魅力。 $el 和 $el[0] 通常都是 return jquery 元素
cy.get("h1.h2:first").then(($el) => {
cy.log($el)
cy.log($el[0])
expect($el).to.have.text('measure')
expect($el[0]).to.have.text('measure')
})
我不太确定你在这个阶段要找什么,但我找到了一种方法来重置 zepto 库的效果。
总而言之,
zepto 是一个 jquery 兼容的库,它接管了您应用程序上的 $
全局 window ref
$ = function(selector, context) {
return zepto.init(selector, context)
}
结果是像 .get()
和 .wrap()
这样的 cy 命令产生了 jquery 结果的 zepto-wrapped 形式,这与 chai [=18] 不兼容=] 没有一些解构。
试验 Cypress.$
我发现这仍然引用 jquery propper,例如
const h2 = Cypress.$('h2')
returns 一个 jquery 对象不是 zepto 对象,因此我们可以从 Cypress.$.
重置应用全局 $
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
})
})
可以将重置代码合并到 cy.visit()
命令的覆盖中,以使其不那么普遍。
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
})
})
注意 这会影响 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')
const zepto_$ = win.$;
win.$ = function(selector, context) {
return typeof selector === 'string'
? zepto_$(selector, context)
: Cypress.$(selector, context);
}
})
})
使用这个 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>
这是我的测试代码片段:
cy.get('div[data-component-data-id=301602] h2:first')
.should(($el) => {
expect($el).to.have.text('dress')
})
赛普拉斯抱怨这个断言:
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.
所以我必须将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库的应用程序代码有关。我在赛普拉斯 Github 存储库中提出了一个 issue,您可以跟踪进度。
我觉得使用 .and("contain", "dress")
可以解决您的问题。
编辑:
我已经在我的机器上尝试了 运行 与您的类似的片段。使用 should
似乎没有预期的结果,我遇到了同样的 jquery 奇怪的行为。然而,当使用 then
时,它就像一个魅力。 $el 和 $el[0] 通常都是 return jquery 元素
cy.get("h1.h2:first").then(($el) => {
cy.log($el)
cy.log($el[0])
expect($el).to.have.text('measure')
expect($el[0]).to.have.text('measure')
})
我不太确定你在这个阶段要找什么,但我找到了一种方法来重置 zepto 库的效果。
总而言之,
zepto 是一个 jquery 兼容的库,它接管了您应用程序上的
$
全局 window ref$ = function(selector, context) {
return zepto.init(selector, context)
}结果是像
.get()
和.wrap()
这样的 cy 命令产生了 jquery 结果的 zepto-wrapped 形式,这与 chai [=18] 不兼容=] 没有一些解构。
试验 Cypress.$
我发现这仍然引用 jquery propper,例如
const h2 = Cypress.$('h2')
returns 一个 jquery 对象不是 zepto 对象,因此我们可以从 Cypress.$.
重置应用全局$
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
})
})
可以将重置代码合并到 cy.visit()
命令的覆盖中,以使其不那么普遍。
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
})
})
注意 这会影响 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')
const zepto_$ = win.$;
win.$ = function(selector, context) {
return typeof selector === 'string'
? zepto_$(selector, context)
: Cypress.$(selector, context);
}
})
})
使用这个 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>