【问题标题】:How can I test a rails 4 confirm dialog with Capybara and Poltergeist?如何使用 Capybara 和 Poltergeist 测试 rails 4 确认对话框?
【发布时间】:2020-06-13 01:24:34
【问题描述】:

我正在尝试测试指向销毁操作的链接是否会引发带有正确消息的本机浏览器 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 功能规范中对其进行测试。

我正在尝试删除浏览器的 confirm 函数,如 herethis gist 中所述,但我无法让它工作。

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 ==)

但是,如果我直接通过page.execute_script 调用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; };
    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)

【问题讨论】:

    标签: ruby-on-rails rspec capybara poltergeist


    【解决方案1】:

    page.driver.browser.accept_js_confirms 已弃用。而是使用

    page.accept_confirm do
      click_link 'Delete'
    end
    

    【讨论】:

    【解决方案2】:

    不幸的是,你 cannot do this,因为 Poltergeist 只在一个窗口中工作。

    对于该特定测试,您将需要使用 Selenium 和此 API:

    page.driver.browser.switch_to.alert.accept
    

    如果您担心想要无头运行测试,可以像这样使用 Xvfb(X 虚拟帧缓冲区):

    Xvfb :1 -screen 0 1024x768x24+32
    

    您也可以使用 capybara-webkit:

    page.driver.browser.accept_js_confirms
    page.driver.browser.reject_js_confirms
    

    但是,我在必要时使用(主要是)Poltergeist 和 Selenium 的混合物获得了最佳体验。

    【讨论】:

    • 感谢您抽出宝贵时间提供帮助。我不是要接受确认,而是要断言它已被抛出。这个问题线程表明它应该是可能的:github.com/teampoltergeist/poltergeist/issues/… - 但我似乎无法让它工作。你能解释一下 Poltegeist 只在一个窗口中工作的意义吗?为什么我概述的测试在我直接从page.execute_script 调用window.confirm() 时起作用,但在我click_link('Delete') 时不起作用。谢谢,汤姆。
    【解决方案3】:

    为了扩展上述内容,在使用 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)
    

    【讨论】:

      【解决方案4】:

      鉴于此 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】:

        这就是我在 Rails 3.2 和 capybara (~&gt; 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 
        

        【讨论】:

          【解决方案6】:

          很难测试 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 是否正常工作,但对于大多数情况来说可能就足够了。 (而且速度很快!)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-28
            • 2013-08-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多