繁体   English   中英

RSpec 和 Capybara:如何获取元素的水平和垂直位置

[英]RSpec and Capybara: How to get the horizontal and vertical position of an element

我在我的网站上添加了视觉上隐藏的跳转链接,当它们被聚焦时会出现(类似于 GitHub,只需在主页上按一次 Tab)。

我想用 Capybara 测试这种行为。 我无法检查例如“可见性:真/假”,因为链接并未真正隐藏(否则屏幕阅读器将看不到它们),而只能通过绝对定位从视口移出。 当它们被聚焦时,它们被放置在视口中的原始位置。

所以我想我必须检查 X 和 Y 坐标,但是 Capybara 似乎没有提供获取它们的本地方法? 这是真的? 如果是这样,我将如何为例如元素“#jump_to_content”获取它们? 通过执行一些 JavaScript?

更新

我在这里找到了一些灵​​感: https : //content.pivotal.io/blog/testing-accessibility-with-rspec-and-capybara

但这似乎不适用于我的配置:

link.native.location
NoMethodError: undefined method `location' for #<Capybara::Poltergeist::Node tag="a">

您是对的,Capybara 没有提供获取元素在页面中位置的本机方法,但是如果您可以访问 jQuery,则可以使用page.evaluate_scriptpage.evaluate_script方法轻松确定元素的位置。 它看起来像这样:

page.evaluate_script("$('.menu > div:nth-child(1)').offset().top")

.offset()方法允许我们检索元素相对于文档的当前位置。 将此与.position() 进行对比,后者检索相对于偏移父级的当前位置

请注意

虽然可以获取设置了visibility:hidden 的元素的坐标,但是display:none 被排除在渲染树之外,因此其位置是未定义的。

使用水豚的 page.evaluate_script 将允许您执行一些 JavaScript 并根据返回值创建断言:

expect(page.evaluate_script("document.querySelectorAll('a#jump-to-content')[0].style.top;")).to eq('-8000px')

根据这个 SO answer ,使用 JavaScript 查找元素位置的最佳方法是使用getBoundingClientRect(); 因为它返回相对于视口的值。

使用 Capybara 而不是 JavaScript 来查找元素,然后找到它的位置,对我来说感觉更具可读性。 我正在使用 Selenium 和 Chrome。

link = find("a", text: "content")

link.evaluate_script("this.getBoundingClientRect().left;")
link.evaluate_script("this.getBoundingClientRect().right;")
link.evaluate_script("this.getBoundingClientRect().top;")
link.evaluate_script("this.getBoundingClientRect().bottom;")

一些浏览器(如 Chrome)也有:

link.evaluate_script("this.getBoundingClientRect().x;")
link.evaluate_script("this.getBoundingClientRect().y;")
link.evaluate_script("this.getBoundingClientRect().height;")
link.evaluate_script("this.getBoundingClientRect().width;")

你也可以这样做

link.rect.y
link.rect.height
link.rect.x
link.rect.width

根据 Nuri 的回答,最好的方法是直接询问浏览器(无头浏览器不读取 css 文件,afaik)。

然而,与其询问元素的样式,不如直接使用offsetTop来检查它的位置。 所以像

expect(page.evaluate_script("document.querySelector('a#jump-to-content').offsetTop;")).to eq('-8000px')

如果你需要更多的控制,你也可以在 javascript 中运行它:

expect(page.evaluate_script("document.querySelector('a#jump-to-content').offsetTop < document.querySelector('body').offsetTop;").to be_true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM