Подтвердить что ты не робот

Как я могу проверить диалог подтверждения рельсов 4 с Capybara и Poltergeist?

Я пытаюсь проверить, что ссылка на действие destroy выдает собственный браузер confirm с правильным сообщением.

Ссылка создается с использованием рельсов 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, как описано здесь, и в этот смысл, однако я не могу заставить его работать.

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.

My Gemfile.lock показывает, что у меня есть следующие версии:

rails (4.1.4)
poltergeist (1.5.1)
capybara (2.4.1)
4b9b3361

Ответ 1

page.driver.browser.accept_js_confirms устарел. Вместо этого используйте

page.accept_confirm do
  click_link 'Delete'
end

Ответ 2

К сожалению, вы не можете этого сделать, потому что 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

Однако, я сделал лучший опыт, используя смесь (в основном) Полтергейста и Селена, где это необходимо.

Ответ 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, как проверить наличие предупреждения Я немного изменил его, поместите в свой файл 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. Но если вы хотите проверить сообщение с подтверждением, возможно, проверить тестовый атрибут можно без использования 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 правильно, но этого может быть достаточно для большинства случаев. (И быстро!)

Ответ 5

Учитывая этот 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