我添加了视觉上隐藏的跳转链接到我的网站,当它们被聚焦时出现(类似于例如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">
答案 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