Capybara JavaScript 测试的 XHR 请求存根

发布于 2024-11-28 23:00:25 字数 3013 浏览 1 评论 0原文

我正在尝试编写一个 request_spec 来测试页面的功能,该表单使用执行 ajax 自动完成查找并返回有效结果以激活提交按钮的表单。

我想知道是否有人有同样的问题并找到某种方法或参考资料来通过此测试。

Gemfile

gem 'rake', '0.8.7'
gem 'rails', '2.3.5'
group :test do
  gem "capybara", :git => "git://github.com/jnicklas/capybara.git"
  gem 'rspec', '1.3.1'
  gem 'rspec-core'
  gem 'rspec-rails', '1.3.2'
  gem 'webmock', '1.4.0'
end

HTML

    ...
    <fieldset>
      <label>Enter a Destination</label>
      <%= text_field_tag :reviewable_name, nil, :id => "destination_autocomplete", :class => 'textfield'  %>
      <ul>
        <li>
          <h3 class="disabled">
            <%= submit_tag "Read reviews", :id => "read_a_destination_review", :name => "agree", :class => "read_review", :disabled => false %>
          </h3>
        </li>
        <li class="or">or</li>
        <li>
          <h3>
            <%= submit_tag "Write review", :id => "write_a_destination_review", :name => "agree", :class => "write_review", :disabled => false %>
          </h3>
        </li>
      </ul>
    </fieldset>
    ...

JavaScript (jQuery 1.4.4)

  ...
  $("#hotel_autocomplete, #destination_autocomplete").autocomplete({
    source: function(request, response){
      $.getJSON('/ajax/search_reviewable?type=destination&q=' + request.term,
        function(results, status){
          if(status == 'success'){
            //make it regex safe
            var term = request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1");
            term = term.split(' ').join('|');
            for(var i = 0; i < results.length; i++){
              results[i].value = results[i].label;
              results[i].label = results[i].value.replace(new RegExp("("+term+")", "gi"),'<strong>$1</strong>');
            }
            response(results);
          }
        }
      );
    },
    minLength: 3,
    delay: 500,
    select: function( event, ui ) {...}
  });
  ...

JSON 响应

/ajax/search_reviewable?type=destination&q=florida

[{"label":"Florida","id":124}]

RSpec 测试

    it "should activate submit button", :js => true do
      stub_request(:get, "/ajax/search_reviewable/type=destination&q=florida").to_return(:body => %Q{[{"label":"Florida","id":124}]}, :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"})
      fill_in("destination_autocomplete", :with => "florida")
      page.execute_script(%Q{$("#destination_autocomplete").trigger("keyup");})
      find(".ui-menu-item a").click
      # should post to '/review/new', :id => 124
      page.should have_content("Write a Destination Review")
    end

测试失败,因为此规范无法在 JavaScript 中存根 XHR 请求。

我感谢您的评论回复和帮助。

I'm trying to write a request_spec that tests the functionality of a page with a form that does a ajax autocomplete lookup and returns valid results to then activate the submit button.

I'm wondering if anybody has has the same issue and found someway or references to get this test passing.

Gemfile

gem 'rake', '0.8.7'
gem 'rails', '2.3.5'
group :test do
  gem "capybara", :git => "git://github.com/jnicklas/capybara.git"
  gem 'rspec', '1.3.1'
  gem 'rspec-core'
  gem 'rspec-rails', '1.3.2'
  gem 'webmock', '1.4.0'
end

HTML

    ...
    <fieldset>
      <label>Enter a Destination</label>
      <%= text_field_tag :reviewable_name, nil, :id => "destination_autocomplete", :class => 'textfield'  %>
      <ul>
        <li>
          <h3 class="disabled">
            <%= submit_tag "Read reviews", :id => "read_a_destination_review", :name => "agree", :class => "read_review", :disabled => false %>
          </h3>
        </li>
        <li class="or">or</li>
        <li>
          <h3>
            <%= submit_tag "Write review", :id => "write_a_destination_review", :name => "agree", :class => "write_review", :disabled => false %>
          </h3>
        </li>
      </ul>
    </fieldset>
    ...

JavaScript (jQuery 1.4.4)

  ...
  $("#hotel_autocomplete, #destination_autocomplete").autocomplete({
    source: function(request, response){
      $.getJSON('/ajax/search_reviewable?type=destination&q=' + request.term,
        function(results, status){
          if(status == 'success'){
            //make it regex safe
            var term = request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1");
            term = term.split(' ').join('|');
            for(var i = 0; i < results.length; i++){
              results[i].value = results[i].label;
              results[i].label = results[i].value.replace(new RegExp("("+term+")", "gi"),'<strong>$1</strong>');
            }
            response(results);
          }
        }
      );
    },
    minLength: 3,
    delay: 500,
    select: function( event, ui ) {...}
  });
  ...

JSON Response

/ajax/search_reviewable?type=destination&q=florida

[{"label":"Florida","id":124}]

RSpec Test

    it "should activate submit button", :js => true do
      stub_request(:get, "/ajax/search_reviewable/type=destination&q=florida").to_return(:body => %Q{[{"label":"Florida","id":124}]}, :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"})
      fill_in("destination_autocomplete", :with => "florida")
      page.execute_script(%Q{$("#destination_autocomplete").trigger("keyup");})
      find(".ui-menu-item a").click
      # should post to '/review/new', :id => 124
      page.should have_content("Write a Destination Review")
    end

The test fails because this spec is unable to stub the XHR request within the JavaScript.

I thank you for your comments responses and help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小镇女孩 2024-12-05 23:00:25

我设法找到解决这个问题的办法。

实际发生的情况是,AJAX 请求的页面 /ajax/search_reviewable?type=destination&q=$1 正在向另一个服务发出 Net::HTTP 请求。

这个请求需要用我需要的响应来打断。

stub_request(:get, ".../all_by_partial_name/Florida/").to_return({
  :body => %Q{[{"label":"Florida","id":124}]}, 
  :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"}
})

经过一些主要研究后,我发现你必须在 JavaScript 中触发一个事件才能通过测试。

来源。 单击自动完成选项要点

现在规范示例如下所示,

before(:each) do
  stub_request(:get, ".../all_by_partial_name/Florida/").to_return({
    :body => %Q{[{"label":"Florida","id":124}]}, 
    :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"}
  })
end

it "should activate submit button and direct to new review", :js => true do
  fill_in("destination_autocomplete", :with => "florida")
  sleep 2
  page.execute_script(%Q{$(".ui-menu-item a:eq(0)").trigger("mouseenter").click();})
  find_button("write_a_destination_review").click
  page.should have_content("Write a Destination Review")
end

我希望这可以帮助您解决您的问题RSpec JQuery 问题。

I manage to find a solution to this issue.

What was actually happening, The AJAX requested page /ajax/search_reviewable?type=destination&q=$1 was doing a Net::HTTP request to another service.

This request needed to be stubbed with the response I was needing.

stub_request(:get, ".../all_by_partial_name/Florida/").to_return({
  :body => %Q{[{"label":"Florida","id":124}]}, 
  :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"}
})

After some major research, I found that you have to trigger a event in JavaScript to pass the test.

Source. Clicking AutoComplete Options Gist

Now the spec example looks like this

before(:each) do
  stub_request(:get, ".../all_by_partial_name/Florida/").to_return({
    :body => %Q{[{"label":"Florida","id":124}]}, 
    :headers => {"Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"}
  })
end

it "should activate submit button and direct to new review", :js => true do
  fill_in("destination_autocomplete", :with => "florida")
  sleep 2
  page.execute_script(%Q{$(".ui-menu-item a:eq(0)").trigger("mouseenter").click();})
  find_button("write_a_destination_review").click
  page.should have_content("Write a Destination Review")
end

I hope this helps you with resolving your RSpec JQuery issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文