当第一页与第二页具有相同的字段时,等待第二页加载Capybara的正确方法

时间:2014-01-23 16:27:01

标签: rspec capybara rspec2

我遇到的问题是在两个表单上访问两个具有相同字段(“电子邮件”)的表单。如果我不手动睡觉,Capybara似乎在测试的第二部分第一次访问时找到了“电子邮件”字段。

# visit the first form and fill out a subscription
visit new_front_form_subscription_path(@web_form_1.id)
fill_in "Email", with: "subscriber@example.com"
fill_in "Field 1", with: "my first data"
click_button "Subscribe"

# visit the second form and fill out a subscription
visit new_front_form_subscription_path(@web_form_2.id)
sleep 1
fill_in "Email", with: "subscriber@example.com"
fill_in "Field 2", with: "my second data"
click_button "Subscribe"

在那里睡觉,规格通过飞扬的颜色。没有睡眠,第二次表单提交会收到验证错误 - 指责空白的“电子邮件”值。

有没有正确的方法来处理这个问题?我讨厌在我们的规格中引入手动睡眠。我更倾向于告诉Capybara忽略它对页面上已有内容的概念,或类似的内容。

谢谢。

7 个答案:

答案 0 :(得分:7)

以下是一些可以解决问题的方法:

  1. 使用仅在第二页上出现的另一个定位器来选择“电子邮件”字段:

    find('#second_page #email').set('subscriber@example.com')
    
  2. 编写一个语句,等待加载第二页而不是睡眠:

    visit new_front_form_subscription_path(@web_form_2.id)
    expect(page).to have_css('locator_present_only_at_second_page')
    fill_in "Email", with: "subscriber@example.com"
    

答案 1 :(得分:5)

上述答案是正确的,但如果您有一个大型测试套件,则很难实现,因为您必须在每个页面上找到唯一的元素。如果您是迈克尔哈特尔铁路学校的毕业生,有一种简单的方法可以解决这个问题。 Hartl教授为每个控制器动作设置不同的@title实例变量。然后在application.html.erb中使用它为每个页面设置html标题元素。

我当然这样做,并且它允许一种非常简单的方法来修复因为页面未正确加载而失败的所有片状测试。您找不到标题标记,因为它不可见。所以我所做的是放在application.html.erb的底部,代码如下;

<%= content_tag :div, "[#{title}]", class: 'rspec_eyes_only' if Rails.env.test? %>

如果您处于测试模式,则会插入带有标题文本的div,并用方括号括起来。然后我写了一个帮助器,它位于rails_helper.rb

def wait_for_page_load(title)
  find('div.rspec_eyes_only', text: title)
end

我已经有另一个帮手来测试正确的标题,所以我修改它以添加wait_for_page_load,即

def title_is_correct(title)
  full_title = "#{BaseTitle} | #{title}"
  wait_for_page_load "[#{full_title}]"
  expect(page.title).to eq full_title
end

这些简单的修改几乎消除了我所有的片状测试。

答案 2 :(得分:1)

如果您使用上面的Andrey 2),您可能需要查看holdon gem,这将允许您编写一个等待加载元素的块,然后转到{{1}该元素加载后的方法。

答案 3 :(得分:0)

一般来说,可以这样做。例如,要单击加载模式弹出窗口(或其他页面)后找到的按钮,请将以下块添加到宏文件中。

def wait_until_modal
   page.has_css?('.modal')
end

此类类.modal位于弹出页面上。

答案 4 :(得分:0)

尝试在新页面加载之后的第一行添加, wait: 10

visit new_front_form_subscription_path(@web_form_2.id)
fill_in "Email", with: "subscriber@example.com", wait: 10 # <--

我也有类似情况:

visit promo_path
fill_in 'promo_code', with: 'HALFPRICEPROMO'
click_button 'Activate' # onClick does things and eventually loads the next page
assert page.has_content? 'Confirm your email address', wait: 10 # <--

没有上面的wait,所有断言都会失败。我放10使其更加安全; 3似乎是我的最低要求。

我在这里找到了答案:Make capybara wait until Ajax finishes

答案 5 :(得分:0)

借助 SitePrism,您可以使用 wait_until_true 来测试 current_url

new_path = new_front_form_subscription_path(@web_form_2.id)
visit new_path
wait_until_true { current_url.include? new_path }
fill_in "Email", with: "subscriber@example.com"
fill_in "Field 2", with: "my second data"
click_button "Subscribe"

答案 6 :(得分:0)

我用它来进行页面转换:

visit page1

do_something

visit page2

Timeout.timeout(Capybara.default_max_wait_time) do
  sleep(0.1) until current_url.include?(page2)
end

do_something_else