我正在尝试测试指向destroy操作的链接是否会使用正确的消息抛出本机浏览器confirm
框。
使用rails {link_to
:
link_to 'Delete', user_path, method: :delete, data: { confirm: "Are you sure?" }
并生成以下html:
<a data-confirm="Are you sure?" data-method="delete" href="/users/6" rel="nofollow">Delete</a>
该功能在浏览器中正常运行,但我想在我的rspec
功能规范中对其进行测试。
我正在尝试按照here和this gist中描述的浏览器的confirm
功能进行存根,但我无法让它发挥作用。
it 'requests confirmation', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };"
click_link 'Delete'
expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')
end
从rspec
发出以下错误:
Failure/Error: expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')
expected: "Are you sure?"
got: nil
(compared using ==)
但是,如果我通过confirm
直接致电page.execute_script
:
it 'requests confirmation', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };
window.confirm('Are you sure?');"
expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')
end
然后测试通过。
即使直接为confirm
调用page.execute_script
,点击删除链接也会导致测试失败:
it 'requests confirmation', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };
window.confirm('Are you sure?');"
click_link 'Delete'
expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')
end
从rspec
发出相同的错误:
Failure/Error: expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')
expected: "Are you sure?"
got: nil
(compared using ==)
为什么测试失败?而且,我如何正确测试确认对话?
上下文
我正在使用Vagrant虚拟机运行我的测试,该虚拟机为Ubuntu 12.04.4 LTS
并且正在运行ruby 2.1.2p95
。
我的Gemfile.lock
表明我有以下版本:
rails (4.1.4)
poltergeist (1.5.1)
capybara (2.4.1)
答案 0 :(得分:27)
page.driver.browser.accept_js_confirms已弃用。而是使用
page.accept_confirm do
click_link 'Delete'
end
答案 1 :(得分:6)
不幸的是,你cannot do this,因为Poltergeist只能在一个窗口中工作。
对于该特定测试,您需要使用Selenium和此API:
page.driver.browser.switch_to.alert.accept
如果您担心想要无头运行测试,可以像这样使用Xvfb(X Virtual Framebuffer):
Xvfb :1 -screen 0 1024x768x24+32
或者您也可以使用capybara-webkit:
page.driver.browser.accept_js_confirms
page.driver.browser.reject_js_confirms
然而,在必要的情况下,我使用了(主要是)Poltergeist和Selenium的混合物,获得了最好的体验。
答案 2 :(得分:1)
为了扩展上述内容,使用Selenium时,您可以使用以下方法测试确认对话框的实际文本:
click_link 'Delete'
a = page.driver.browser.switch_to.alert
expect(a.text).to eq("Are you sure?")
a.accept
另外,刚刚找到了一个关于警报是否存在的良好测试:selenium 2.4.0, how to check for presence of an alert我稍微修改了它,将我的spec_helper文件放入:
def alert_present?
begin
page.driver.browser.switch_to.alert
return true
rescue
return false
end
end
然后在你的测试中做:
click_link 'Delete'
expect(alert_present?).to eq(true)
答案 3 :(得分:0)
测试JavaScript行为很难。但是如果你想检查确认消息,可以在没有Poltergeist的情况下测试链接属性:
it 'requests confirmation' do
visit user_path(user)
delete_link = find_link 'Delete', href: user_path(user)
expect(delete_link['data-confirm']).to eq 'Are you sure?'
end
以下是替代方案:
it 'requests confirmation' do
visit user_path(user)
expect(page).to have_selector "a[data-confirm='Are you sure?'][href='#{user_path(user)}']", text: 'Delete'
end
此测试无法检查JS是否正常工作,但在大多数情况下可能已足够。 (快点!)
答案 4 :(得分:0)
鉴于此Javascript:
confirm('You have unsaved changes, do you want to continue?')
对于Poltergiest,我发现以下内容有效:
expect(page.driver.browser.modal_message).eq 'You have unsaved changes, do you want to contine?'
page.driver.browser.dismiss_confirm
page.driver.browser.accept_confirm
答案 5 :(得分:0)
这就是我在Rails 3.2和capybara (~> 2.18.0)
context 'when `All listing` overlaps with listing 1' do
it 'displays warning' do
set_weekday_times('.show_window','10:00 AM', '02:00 PM', listing1.address)
set_weekday_times('.show_window:last-child', '11:00 AM', '03:00 PM', 'All Listing')
# button click event that triggers the confirm to appear
submit_weekdays_form
# Get the message in the confirm dialog
confirm_text = page.driver.browser.switch_to.alert.text
expect(confirm_text).to include('overlapping show windows on Sunday')
end
end