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

时间:2015-03-23 11:52:00

标签: javascript rspec capybara-webkit

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

我想用Capybara测试这种行为。我无法检查,例如'visibility:true / false',因为链接不是真正隐藏的(否则屏幕阅读器不会看到它们),但只能通过绝对定位从视口中移出。当它们被聚焦时,它们被放置在视口中的原始位置。

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

更新

我在这里找到了一些灵​​感:http://pivotallabs.com/accessible-tab-navigation-using-sass-mixins/

但这对我的移民似乎不起作用:

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

4 个答案:

答案 0 :(得分:2)

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

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

  

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

请注意

  

虽然可以获得具有可见性的元素坐标:隐藏集,但显示:无从渲染树中排除,因此具有未定义的位置。

答案 1 :(得分:1)

使用capybara的page.evaluate_script将允许您执行一些JavaScript并从返回值创建一个断言:

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

答案 2 :(得分:1)

根据this 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

答案 3 :(得分:0)

根据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