- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
题目如题,即访问父元素被隐藏的元素。问题是,根据 cypress.io docs :
An element is considered hidden if:
- Its width or height is 0.
- Its CSS property (or ancestors) is visibility: hidden.
- Its CSS property (or ancestors) is display: none.
- Its CSS property is position: fixed and it’s offscreen or covered up.
但我正在使用的代码要求我单击一个元素,该元素的父元素是隐藏的,而该元素本身是可见的。
所以每次我尝试点击这个元素时,它都会抛出一个错误:
CypressError: Timed out retrying: expected '< mdc-select-item#mdc-select-item-4.mdc-list-item>' to be 'visible'
This element '< mdc-select-item#mdc-select-item-4.mdc-list-item>' is not visible because its parent '< mdc-select-menu.mdc-simple-menu.mdc-select__menu>' has CSS property: 'display: none'
我正在使用的元素是一个 dropdown item
,它是用 pug
编写的。该元素是在 angular-mdc-web 中定义的组件,它使用 mdc-select
作为下拉菜单,使用 mdc-select-item
作为我必须访问的元素(项目)。
类似结构的示例代码:
//pug
mdc-select(placeholder="installation type"
'[closeOnScroll]'="true")
mdc-select-item(value="false") ITEM1
mdc-select-item(value="true") ITEM2
在上面,ITEM1
是我必须访问的元素。我在 cypress.io
中的操作如下:
//cypress.io
// click on the dropdown menu to show the dropdown (items)
cy.get("mdc-select").contains("installation type").click();
// try to access ITEM1
cy.get('mdc-select-item').contains("ITEM1").should('be.visible').click();
已尝试使用 {force:true}
强制点击项目,但没有成功。尝试在父级 mdc-select
上使用 {enter}
按键选择项目,但再次失败,因为它抛出:
CypressError: cy.type() can only be called on textarea or :text. Your subject is a: < mdc-select-label class="mdc-select__selected-text">Select ...< /mdc-select-label>
还尝试使用 select
command ,但这是不可能的,因为 Cypress 引擎无法将元素识别为 select
元素(因为它不是,内部工作方式不同)。它抛出:
CypressError: cy.select() can only be called on a . Your subject is a: < mdc-select-label class="mdc-select__selected-text">Select ...< /mdc-select-label>
问题 是 mdc-select-menu
是 mdc-select-item
的父级,其属性为 display:none
在打开下拉项时通过一些内部计算。
此属性被覆盖为 display:flex
,但这没有帮助。
完全没有想法。这适用于 Selenium
,但不适用于 cypress.io
。除了转移到其他框架或更改 UI 代码之外,有什么线索可以解决这种情况?
最佳答案
经过多次咬牙切齿,我想我找到了答案。
我认为根本原因是 mdc-select-item
有 display:flex
,它允许它超出它的 parent 的界限(严格来说,这感觉例如 display flex 的错误应用,如果我没记错教程的话……)。
Cypress 在确定可见性时会进行大量父检查,请参阅 visibility.coffee ,
## WARNING:
## developer beware. visibility is a sink hole
## that leads to sheer madness. you should
## avoid this file before its too late.
...
when $parent = parentHasDisplayNone($el.parent())
parentNode = $elements.stringify($parent, "short")
"This element '#{node}' is not visible because its parent '#{parentNode}' has CSS property: 'display: none'"
...
when $parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden($el.parent())
parentNode = $elements.stringify($parent, "short")
width = elOffsetWidth($parent)
height = elOffsetHeight($parent)
"This element '#{node}' is not visible because its parent '#{parentNode}' has CSS property: 'overflow: hidden' and an effective width and height of: '#{width} x #{height}' pixels."
但是,当使用 .should('be.visible')
时,即使我们实际上可以看到子项,我们也会遇到父属性未通过子项可见性检查的情况。
我们需要一个替代测试。
引用 jquery.js ,这是元素本身可见性的一种定义(忽略父属性)。
jQuery.expr.pseudos.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
}
因此我们可以将其用作替代方案的基础。
describe('Testing select options', function() {
// Change this function if other criteria are required.
const isVisible = (elem) => !!(
elem.offsetWidth ||
elem.offsetHeight ||
elem.getClientRects().length
)
it('checks select option is visible', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
//cy.get('mdc-select-item').contains("ITEM1").should('be.visible') //this will fail
cy.get('mdc-select-item').contains("ITEM1").then (item1 => {
expect(isVisible(item1[0])).to.be.true
});
});
it('checks select option is not visible', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
cy.document().then(function(document) {
const item1 = document.querySelectorAll('mdc-select-item')[0]
item1.style.display = 'none'
cy.get('mdc-select-item').contains("ITEM1").then (item => {
expect(isVisible(item[0])).to.be.false
})
})
});
it('checks select option is clickable', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
//cy.get('mdc-select-item').contains("ITEM1").click() // this will fail
cy.get('mdc-select-item').contains("ITEM1").then (item1 => {
cy.get('mdc-select-item').contains("ITEM2").then (item2 => {
expect(isVisible(item2[0])).to.be.true //visible when list is first dropped
});
item1.click();
cy.wait(500)
cy.get('mdc-select-item').contains("ITEM2").then (item2 => {
expect(isVisible(item2[0])).to.be.false // not visible after item1 selected
});
});
})
脚注 - 使用“then”(或“each”)
您通常在 cypress 中使用断言的方式是通过命令链,它基本上包装了被测试的元素并处理诸如重试和等待 DOM 更改之类的事情。
但是,在这种情况下,我们在标准可见性断言 .should('be.visible')
和用于构建页面的框架之间存在矛盾,因此我们使用 then( fn)
( ref ) 以访问未包装的 DOM。然后,我们可以使用 stand jasmine expect 语法应用我们自己版本的可见性测试。
事实证明,您也可以使用带有 .should(fn)
的函数,这同样有效
it('checks select option is visible - 2', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
cy.get('mdc-select-item').contains("ITEM1").should(item1 => {
expect(isVisible(item1[0])).to.be.true
});
});
使用 should
而不是 then
对可见性测试没有影响,但请注意 should
版本可以多次重试函数,所以它不能与 click
测试一起使用(例如)。
来自文档,
What’s the difference between .then() and .should()/.and()?
Using .then() simply allows you to use the yielded subject in a callback function and should be used when you need to manipulate some values or do some actions.
When using a callback function with .should() or .and(), on the other hand, there is special logic to rerun the callback function until no assertions throw within it. You should be careful of side affects in a .should() or .and() callback function that you would not want performed multiple times.
您也可以通过扩展 chai 断言来解决该问题,但是这方面的文档并不广泛,因此可能需要更多工作。
关于javascript - 访问其父项被隐藏的元素 - cypress.io,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47551639/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!