如何在Capybara中测试页面是否*没有重新加载(JavaScript onClick intercept有效)?

时间:2013-11-27 13:00:09

标签: javascript ajax cucumber capybara poltergeist

我正在使用Capybara,Cucumber和Poltergeist。我正在测试一个附加到表单提交按钮的JavaScript函数,该函数用于捕获提交事件并阻止它(在后台执行AJAX请求)。无论是否使用AJAX,页面最终都会看起来相同,但AJAX方法要快得多,并且不会中断浏览体验等。

我可以做些什么来测试表单确实没有提交,并且更改是动态AJAX调用的结果而不是重新加载?

5 个答案:

答案 0 :(得分:3)

@ jules'的修改版本回答:

describe "My page", :js do
  it "reloads when it should" do
    visit "/"

    expect_page_to_reload do
      click_link "Reload me"
    end
  end

  def expect_page_to_reload
    page.evaluate_script "$(document.body).addClass('not-reloaded')"
    yield
    expect(page).not_to have_selector("body.not-reloaded")
  end
end

编辑2017-01-19:

我发现我的这个旧答案奇怪地似乎没有回答实际问题,而是相反(检查页面已重新加载)。这是我们目前在我们的应用中执行的操作,用于检查页面是否重新加载:

def expect_page_not_to_reload
  page.evaluate_script %{$(document.body).addClass("not-reloaded")}
  expect(page).to have_selector("body.not-reloaded")
  yield
  sleep 0.5  # Give it a chance to reload before we check.
  expect(page).to have_selector("body.not-reloaded")
end

这两个答案都依赖于jQuery来添加类。

答案 1 :(得分:2)

我遇到了同样的问题并想出了一个解决方案,可能不是最好的解决方案 - 但它有效:)

#support/reload.rb
def init_reload_check
    page.evaluate_script "window.not_reloaded = 'not reloaded';"
end

def not_reloaded
    page.evaluate_script("window.not_reloaded") == "not reloaded"
end

#Ajax Test
it "should not reload the page", js: true do
    init_reload_check
    click_link "Ajax Link"
    expect(not_reloaded).to be_truthy
end

答案 2 :(得分:1)

这是我的Henrik Nanswer版本。不依赖jQuery或他使用的任何断言库。

def assert_page_reloads(message = "page should reload")
  page.evaluate_script "document.body.classList.add('not-reloaded')"
  yield
  if has_selector? "body.not-reloaded"
    assert false, message
  end
end

def assert_page_does_not_reload(message = "page should not reload")
  page.evaluate_script "document.body.classList.add('not-reloaded')"
  yield
  unless has_selector? "body.not-reloaded"
    assert false, message
  end
  page.evaluate_script "document.body.classList.remove('not-reloaded')"
end

答案 3 :(得分:0)

Capybara旨在用于用户级功能测试。没有一种简单的方法来测试实现细节,例如表单是使用AJAX还是传统表单提交。它鼓励您根据最终用户体验编写测试。

你可以做几件事:

  • Capybara支持查找器和断言的等待时间。有几种方法可以使用Capybara.default_wait_timeCapybara.using_wait_time或将wait选项传递给断言方法来设置它。如果设置的等待时间较短,则可以确保单击提交按钮的结果快速返回。

  • 查看JavaScript单元和集成测试框架,例如Jasmine。这可用于测试设置事件绑定和AJAX调用的JavaScript代码。您可以使用间谍来确保在单击按钮时进行预期的AJAX调用。

答案 4 :(得分:0)

feature "User creates comment", do
  context "with JavaScript enabled", js: true do

    scenario "creates comment via AJAX" do

      initial_page_id = assign_page_id

      # Perform AJAX action
      ...

      page_reloaded = current_page_id != initial_page_id
      expect(page_reloaded).to eq(false)

    end

    def assign_page_id
      page_id = SecureRandom.hex
      page.evaluate_script "window.pageIdForTesting = '#{page_id}'"
    end

    def current_page_id
      page.evaluate_script("window.pageIdForTesting")
    end

  end

  context "without JavaScript" do
    # Can be used if progressively enhancing
    ...
  end
end