Jos*_*eim 9 javascript jquery rspec capybara phantomjs
我在我的网页中有盲人和键盘用户的跳转链接,这些用户被移出视口以便在视觉上隐藏它们; 当他们获得焦点时,他们会被移动到视口中.
我想使用RSpec和Capybara测试这种行为,但它不知何故不起作用.
it 'moves the focus to the navigation when activating the corresponding link', js: true do
expect(page).not_to have_css '#main:focus'
page.evaluate_script "$('#jump_to_content > a').focus()"
click_link 'Jump to content'
expect(page).to have_css '#main:focus'
end
Run Code Online (Sandbox Code Playgroud)
JavaScript in evaluate_script似乎没有正确执行.我$('#jump_to_content > a').focus()在Chrome控制台中尝试了相同的JS(),我对结果有点不确定,因为在控制台中,链接没有出现,但是当点击进入浏览器视图时,它出现了部分一秒钟又消失了(它消失了,因为它不再具有焦点).在我看来,它应该在执行JS后直接显示.
这让我对这一切有点不安全.任何帮助都非常感谢.
更新
我同时得出结论,Chrome的行为是正常的:焦点保留在控制台中,因此该元素实际上并没有真正获得焦点而且没有显示.
我还得出结论,Capybara似乎无法正确处理元素(并应用:focus样式).
我创建了以下CSS规则:
#jump_to_navigation颜色:黑色
&:focus
color: red
Run Code Online (Sandbox Code Playgroud)
为了测试这个,我设置了这个非常具体的测试:
visit root_path
selector = 'a#jump_to_navigation'
# Initial style
expect(page.evaluate_script('document.activeElement.id')).to eq '' # Make sure the link isn't focused yet
expect(page.evaluate_script("$('#{selector}').css('color')")).to eq 'rgb(0, 0, 0)' # Color initially is black
# Set focus
page.evaluate_script("$('#{selector}').focus()")
# Focused style
expect(page.evaluate_script('document.activeElement.id')).to eq 'jump_to_navigation' # Make sure the link is focused now
expect(page.evaluate_script("$('#{selector}').css('color')")).to eq 'rgb(255, 0, 0)' # Color is now red
Run Code Online (Sandbox Code Playgroud)
测试打破了这样:
1) Navigation jump links visually displays them only on focus
Failure/Error: expect(page.evaluate_script("$('#{selector}').css('color')")).to eq 'rgb(255, 0, 0)' # Color is now red
expected: "rgb(255, 0, 0)"
got: "rgb(0, 0, 0)"
(compared using ==)
Run Code Online (Sandbox Code Playgroud)
因此焦点设置正确,但:focus不应用样式.我猜这是PhantomJS的一个问题?
我很乐意找到解决这个问题的方法.
我找到了一种解决方法,即使用 JavaScript 添加/删除类(在我的例子中为.sr-only),而不是依赖 CSS:hover机制。
visit root_path
selector = '#jump_to_navigation'
expect(page.evaluate_script('document.activeElement.id')).to eq '' # Make sure the link isn't focused yet
# Initial (hidden) position
expect(page.evaluate_script("$('#{selector}')[0].className")).to eq 'sr-only' # Make sure the link has sr-only class
# Set focus
page.evaluate_script("$('#{selector}').focus()")
expect('#' + page.evaluate_script('document.activeElement.id')).to eq selector # Make sure the link is focused now
# Displayed position
expect(page.evaluate_script("$('#{selector}')[0].className")).to eq '' # Make sure the link doesn't have sr-only class
# Remove focus
page.evaluate_script("$('#{selector}').blur()")
expect(page.evaluate_script('document.activeElement.id')).to eq '' # Make sure the link is focused now
# Hidden position again
expect(page.evaluate_script("$('#{selector}')[0].className")).to eq 'sr-only' # Make sure the link has sr-only class
Run Code Online (Sandbox Code Playgroud)
这似乎有效。我没有检查这种方式是否也能被 Capybara 识别 CSS 更改,但对于我的情况来说,这已经足够了。
重要提示:顺便说一句,您应该使用execute_script而不是evaluate_script,因为后者对性能有巨大的影响!