如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?
Posted
技术标签:
【中文标题】如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?【英文标题】:How to check if element is never visible in Cypress e2e testing?如何检查在赛普拉斯 e2e 测试中元素是否永远不可见? 【发布时间】:2019-05-13 17:23:37 【问题描述】:在赛普拉斯中路由时,有什么方法可以断言元素在任何时候都不可见?
我有一个服务器渲染的网络应用程序,有时它不应该显示“正在加载”状态。因此,当我在页面之间导航时,“加载”指示器会显示几秒钟然后消失。
我知道赛普拉斯的断言有时会“等待”——在这种情况下,赛普拉斯一直等到加载指示器消失,这使得测试认为它已经通过了。但我希望测试失败,因为加载指示器在某些时候是可见的。
我正在使用这两个断言:
cy.get('[data-test="loading"]').should('not.exist');
cy.get('[data-test="loading"]').should('not.be.visible');
但是由于加载指示器消失了,它们都通过了。
我已经检查了所有文档,但似乎没有某种方法可以检查元素是否从不可见。是否有一些我遗漏的方法或一些黑客来测试这个不同的方式?
【问题讨论】:
你能添加某种 0 的等待,所以我不等待吗? 【参考方案1】:Cypress 有一个精简版的 jQuery,所以我们可以观察不应该存在的元素的父元素的变化。
只要发生变化,就会应用@Maccurt 的测试。
您希望将手表触发保持在最低限度,因此请找到测试元素的直接(或最近)父级。
注意这涵盖了exists
测试,但如果元素一直存在但不可见,则visible
测试不应该是必需的。
在这个例子中,一个按钮被添加到body
。
第一个测试监视span
(从未添加,因此测试成功)。button
的第二次测试手表失败了。
describe('watching for an element to not appear', () =>
const watchAndTest = function(parentSelector, assert)
Cypress.$(parentSelector).bind('DOMNodeInserted', function(event)
assert()
);
it('should succeed because "span" does not exist', () =>
const parentSelector = 'body'
const watchForSelector = 'span'
watchAndTest(parentSelector,
() =>
// Place your 'assert' code here
cy.get(`$parentSelector $watchForSelector`, timeout: 0 )
.should('not.exist');
)
// Place your 'act' code here
cy.get(parentSelector).then(parent =>
var newElement = document.createElement('button');
parent[0].appendChild(newElement)
)
Cypress.$(parentSelector).unbind('DOMNodeInserted')
)
it('should fail because "button" exists', () =>
const parentSelector = 'body'
const watchForSelector = 'button'
watchAndTest(parentSelector,
() =>
// Place your 'assert' code here
cy.get(`$parentSelector $watchForSelector`, timeout: 0 )
.should('not.exist');
)
// Place your 'act' code here
cy.get(parentSelector).then(parent =>
var newElement = document.createElement('button');
parent[0].appendChild(newElement)
)
Cypress.$(parentSelector).unbind('DOMNodeInserted')
)
)
【讨论】:
感谢您发布此答案,我会看看。 这很漂亮,干得好!【参考方案2】:我可能疯了,我还没有测试过这个,但我想把它扔出去
我假设您正在测试不应该有加载指示器,并且它正在等待默认的 4 秒并且指示器消失,因此您的测试通过。所以下面我将等待设置为零,所以它不等待。我也很困惑为什么你不修复实际代码,所以如果你不应该看到指示器,你就看不到。也许您无权访问代码..
cy.get('[data-test="loading"]', timeout: 0 ).should('not.exist');
cy.get('[data-test="loading"]', timeout: 0 ).should('not.be.visible');
【讨论】:
是的,超时工作完美,非常感谢!我也可以访问代码,但我基本上暂时使用加载指示器作为后备。它的工作方式是在服务器上呈现页面(我正在使用 React / Next.js)并显示一个完全加载的页面。 这只会测试元素在特定时刻是否可见。您的问题是在寻找一种“断言元素在任何时候都不可见”的方法。该元素可能在整个测试期间一直存在,直到您调用上述代码之前的一毫秒,测试就会通过。 @Brendan 你能提供一个替代方案吗,我愿意接受。我怀疑这是否是一件好事。我愿意学习.. @Maccurt 负面测试总是很棘手。显示加载状态时是否发送了 XHR 请求?如果是这样,您可以在测试结束时检查该路线。 docs.cypress.io/api/commands/route.html#Syntax以上是关于如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?的主要内容,如果未能解决你的问题,请参考以下文章