webrat 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. data/.gitignore +4 -1
  2. data/Gemfile +19 -0
  3. data/History.txt +29 -0
  4. data/Rakefile +27 -63
  5. data/Thorfile +117 -0
  6. data/lib/webrat.rb +11 -3
  7. data/lib/webrat/{mechanize.rb → adapters/mechanize.rb} +0 -0
  8. data/lib/webrat/adapters/merb.rb +11 -0
  9. data/lib/webrat/{rack.rb → adapters/rack.rb} +0 -0
  10. data/lib/webrat/{rails.rb → adapters/rails.rb} +2 -23
  11. data/lib/webrat/{sinatra.rb → adapters/sinatra.rb} +0 -2
  12. data/lib/webrat/core.rb +0 -1
  13. data/lib/webrat/core/configuration.rb +6 -16
  14. data/lib/webrat/core/elements/area.rb +2 -2
  15. data/lib/webrat/core/elements/element.rb +3 -3
  16. data/lib/webrat/core/elements/field.rb +106 -30
  17. data/lib/webrat/core/elements/form.rb +4 -4
  18. data/lib/webrat/core/elements/label.rb +4 -4
  19. data/lib/webrat/core/elements/link.rb +6 -6
  20. data/lib/webrat/core/elements/select_option.rb +15 -2
  21. data/lib/webrat/core/locators.rb +1 -1
  22. data/lib/webrat/core/locators/area_locator.rb +3 -3
  23. data/lib/webrat/core/locators/button_locator.rb +6 -6
  24. data/lib/webrat/core/locators/field_by_id_locator.rb +3 -3
  25. data/lib/webrat/core/locators/field_labeled_locator.rb +2 -2
  26. data/lib/webrat/core/locators/field_named_locator.rb +3 -3
  27. data/lib/webrat/core/locators/form_locator.rb +1 -1
  28. data/lib/webrat/core/locators/label_locator.rb +2 -2
  29. data/lib/webrat/core/locators/link_locator.rb +7 -7
  30. data/lib/webrat/core/locators/select_option_locator.rb +5 -5
  31. data/lib/webrat/core/logging.rb +4 -5
  32. data/lib/webrat/core/matchers/have_content.rb +2 -7
  33. data/lib/webrat/core/matchers/have_xpath.rb +3 -28
  34. data/lib/webrat/core/methods.rb +1 -0
  35. data/lib/webrat/core/scope.rb +17 -2
  36. data/lib/webrat/core/session.rb +2 -1
  37. data/lib/webrat/core/xml.rb +41 -84
  38. data/lib/webrat/integrations/merb.rb +10 -0
  39. data/lib/webrat/integrations/rails.rb +25 -0
  40. data/lib/webrat/integrations/rspec-rails.rb +11 -0
  41. data/lib/webrat/integrations/selenium.rb +11 -0
  42. data/lib/webrat/rspec-rails.rb +2 -10
  43. data/lib/webrat/selenium.rb +0 -10
  44. data/lib/webrat/selenium/application_servers.rb +1 -1
  45. data/lib/webrat/selenium/application_servers/external.rb +1 -1
  46. data/lib/webrat/selenium/location_strategy_javascript/label.js +29 -3
  47. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +1 -0
  48. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +24 -4
  49. data/lib/webrat/selenium/selenium_rc_server.rb +2 -2
  50. data/lib/webrat/selenium/selenium_session.rb +21 -2
  51. data/lib/webrat/selenium/silence_stream.rb +1 -1
  52. data/spec/integration/mechanize/spec/spec_helper.rb +3 -1
  53. data/spec/integration/rails/app/controllers/{application.rb → application_controller.rb} +0 -0
  54. data/spec/integration/rails/app/controllers/webrat_controller.rb +3 -0
  55. data/spec/integration/rails/app/views/buttons/show.html.erb +0 -2
  56. data/spec/integration/rails/app/views/webrat/buttons.html.erb +0 -2
  57. data/spec/integration/rails/app/views/webrat/within.html.erb +3 -0
  58. data/spec/integration/rails/config/environment.rb +1 -1
  59. data/spec/integration/rails/config/routes.rb +1 -0
  60. data/spec/integration/rails/test/integration/button_click_test.rb +12 -26
  61. data/spec/integration/rails/test/integration/fill_in_test.rb +1 -1
  62. data/spec/integration/rails/test/integration/link_click_test.rb +1 -1
  63. data/spec/integration/rails/test/integration/webrat_test.rb +35 -9
  64. data/spec/integration/rails/test/test_helper.rb +1 -0
  65. data/spec/private/core/configuration_spec.rb +2 -31
  66. data/spec/private/core/field_spec.rb +14 -16
  67. data/spec/private/mechanize/mechanize_adapter_spec.rb +0 -2
  68. data/spec/private/nokogiri_spec.rb +2 -2
  69. data/spec/private/rails/rails_adapter_spec.rb +0 -27
  70. data/spec/public/basic_auth_spec.rb +13 -2
  71. data/spec/public/click_button_spec.rb +10 -12
  72. data/spec/public/click_link_spec.rb +21 -0
  73. data/spec/public/fill_in_spec.rb +15 -0
  74. data/spec/public/matchers/have_selector_spec.rb +4 -0
  75. data/spec/public/select_spec.rb +232 -26
  76. data/spec/spec_helper.rb +2 -0
  77. data/webrat.gemspec +305 -313
  78. metadata +21 -25
  79. data/VERSION +0 -1
  80. data/lib/webrat/core/xml/hpricot.rb +0 -19
  81. data/lib/webrat/core/xml/nokogiri.rb +0 -76
  82. data/lib/webrat/core/xml/rexml.rb +0 -24
  83. data/lib/webrat/merb_adapter.rb +0 -82
  84. data/lib/webrat/merb_multipart_support.rb +0 -27
  85. data/spec/private/core/logging_spec.rb +0 -10
  86. data/spec/private/merb/attaches_file_spec.rb +0 -93
  87. data/spec/private/merb/merb_adapter_spec.rb +0 -61
@@ -0,0 +1,10 @@
1
+ module Merb #:nodoc:
2
+ module Test #:nodoc:
3
+ module RequestHelper #:nodoc:
4
+ def request(uri, env = {})
5
+ @_webrat_session ||= Webrat::MerbAdapter.new
6
+ @_webrat_session.response = @_webrat_session.request(uri, env)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ require "action_controller"
2
+ require "action_controller/integration"
3
+
4
+ module ActionController #:nodoc:
5
+ IntegrationTest.class_eval do
6
+ include Webrat::Methods
7
+ include Webrat::Matchers
8
+
9
+ # The Rails version of within supports passing in a model and Webrat
10
+ # will apply a scope based on Rails' dom_id for that model.
11
+ #
12
+ # Example:
13
+ # within User.last do
14
+ # click_link "Delete"
15
+ # end
16
+ def within(selector_or_object, &block)
17
+ if selector_or_object.is_a?(String)
18
+ super
19
+ else
20
+ super('#' + RecordIdentifier.dom_id(selector_or_object), &block)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ # Supports using the matchers in controller, helper, and view specs if you're
2
+ # using rspec-rails. Just add a require statement to spec/spec_helper.rb or env.rb:
3
+ #
4
+ # require 'webrat/integrations/rspec-rails'
5
+ #
6
+ require "nokogiri"
7
+ require "webrat/core/matchers"
8
+
9
+ Spec::Runner.configure do |config|
10
+ config.include(Webrat::Matchers, :type => [:controller, :helper, :view])
11
+ end
@@ -0,0 +1,11 @@
1
+ require "webrat/selenium"
2
+
3
+ if defined?(ActionController::IntegrationTest)
4
+ module ActionController #:nodoc:
5
+ IntegrationTest.class_eval do
6
+ include Webrat::Methods
7
+ include Webrat::Selenium::Methods
8
+ include Webrat::Selenium::Matchers
9
+ end
10
+ end
11
+ end
@@ -1,10 +1,2 @@
1
- # Supports using the matchers in controller, helper, and view specs if you're
2
- # using rspec-rails. Just add a require statement to spec/spec_helper.rb or env.rb:
3
- #
4
- # require 'webrat/rspec-rails'
5
- #
6
- require "webrat/core/matchers"
7
-
8
- Spec::Runner.configure do |config|
9
- config.include(Webrat::Matchers, :type => [:controller, :helper, :view])
10
- end
1
+ warn("Requiring 'webrat/rspec-rails' is deprecated. Please require 'webrat/integrations/rspec-rails' instead")
2
+ require "webrat/integrations/rspec-rails"
@@ -68,13 +68,3 @@ module Webrat
68
68
  end
69
69
  end
70
70
  end
71
-
72
- if defined?(ActionController::IntegrationTest)
73
- module ActionController #:nodoc:
74
- IntegrationTest.class_eval do
75
- include Webrat::Methods
76
- include Webrat::Selenium::Methods
77
- include Webrat::Selenium::Matchers
78
- end
79
- end
80
- end
@@ -2,4 +2,4 @@ require "webrat/selenium/application_servers/base"
2
2
  require "webrat/selenium/application_servers/sinatra"
3
3
  require "webrat/selenium/application_servers/merb"
4
4
  require "webrat/selenium/application_servers/rails"
5
- require "webrat/selenium/application_servers/external"
5
+ require "webrat/selenium/application_servers/external"
@@ -23,4 +23,4 @@ module Webrat
23
23
  end
24
24
  end
25
25
  end
26
- end
26
+ end
@@ -1,16 +1,42 @@
1
+ // Credit to: http://simonwillison.net/2006/Jan/20/escape/
2
+ RegExp.escape = function(text) {
3
+ if (!arguments.callee.sRE) {
4
+ var specials = [
5
+ '/', '.', '*', '+', '?', '|',
6
+ '(', ')', '[', ']', '{', '}', '\\'
7
+ ];
8
+ arguments.callee.sRE = new RegExp(
9
+ '(\\' + specials.join('|\\') + ')', 'g'
10
+ );
11
+ }
12
+ return text.replace(arguments.callee.sRE, '\\$1');
13
+ }
14
+
1
15
  var allLabels = inDocument.getElementsByTagName("label");
16
+ var regExp = new RegExp('^\\W*' + RegExp.escape(locator) + '(\\b|$)', 'i');
17
+
2
18
  var candidateLabels = $A(allLabels).select(function(candidateLabel){
3
- var regExp = new RegExp('^' + locator + '\\b', 'i');
4
19
  var labelText = getText(candidateLabel).strip();
5
20
  return (labelText.search(regExp) >= 0);
6
21
  });
22
+
7
23
  if (candidateLabels.length == 0) {
8
24
  return null;
9
25
  }
10
- candidateLabels = candidateLabels.sortBy(function(s) { return s.length * -1; }); //reverse length sort
26
+
27
+ //reverse length sort
28
+ candidateLabels = candidateLabels.sortBy(function(s) {
29
+ return s.length * -1;
30
+ });
31
+
11
32
  var locatedLabel = candidateLabels.first();
12
33
  var labelFor = locatedLabel.getAttribute('for');
34
+
13
35
  if ((labelFor == null) && (locatedLabel.hasChildNodes())) {
14
- return locatedLabel.firstChild; //TODO: should find the first form field, not just any node
36
+ return locatedLabel.getElementsByTagName('button')[0]
37
+ || locatedLabel.getElementsByTagName('input')[0]
38
+ || locatedLabel.getElementsByTagName('textarea')[0]
39
+ || locatedLabel.getElementsByTagName('select')[0];
15
40
  }
41
+
16
42
  return selenium.browserbot.locationStrategies['id'].call(this, labelFor, inDocument, inWindow);
@@ -1,4 +1,5 @@
1
1
  var locationStrategies = selenium.browserbot.locationStrategies;
2
+
2
3
  return locationStrategies['id'].call(this, locator, inDocument, inWindow)
3
4
  || locationStrategies['name'].call(this, locator, inDocument, inWindow)
4
5
  || locationStrategies['label'].call(this, locator, inDocument, inWindow)
@@ -1,12 +1,32 @@
1
1
  var links = inDocument.getElementsByTagName('a');
2
+
2
3
  var candidateLinks = $A(links).select(function(candidateLink) {
3
- var textMatched = PatternMatcher.matches(locator, getText(candidateLink));
4
- var idMatched = PatternMatcher.matches(locator, candidateLink.id);
5
- var titleMatched = PatternMatcher.matches(locator, candidateLink.title);
4
+ var textMatched = false;
5
+ var titleMatched = false;
6
+ var idMatched = false;
7
+
8
+ if (getText(candidateLink).toLowerCase().indexOf(locator.toLowerCase()) != -1) {
9
+ textMatched = true;
10
+ }
11
+
12
+ if (candidateLink.title.toLowerCase().indexOf(locator.toLowerCase()) != -1) {
13
+ titleMatched = true;
14
+ }
15
+
16
+ if (candidateLink.id.toLowerCase().indexOf(locator.toLowerCase()) != -1) {
17
+ idMatched = true;
18
+ }
19
+
6
20
  return textMatched || idMatched || titleMatched;
7
21
  });
22
+
8
23
  if (candidateLinks.length == 0) {
9
24
  return null;
10
25
  }
11
- candidateLinks = candidateLinks.sortBy(function(s) { return s.length * -1; }); //reverse length sort
26
+
27
+ //reverse length sort
28
+ candidateLinks = candidateLinks.sortBy(function(s) {
29
+ return s.length * -1;
30
+ });
31
+
12
32
  return candidateLinks.first();
@@ -74,8 +74,8 @@ module Webrat
74
74
 
75
75
  def stop
76
76
  silence_stream(STDOUT) do
77
- ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
78
- Webrat.configuration.selenium_server_port,
77
+ ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
78
+ Webrat.configuration.selenium_server_port,
79
79
  :timeout => 5).stop
80
80
  end
81
81
  end
@@ -3,6 +3,8 @@ require "webrat/selenium/selenium_rc_server"
3
3
  require "webrat/selenium/application_server_factory"
4
4
  require "webrat/selenium/application_servers/base"
5
5
 
6
+ require "selenium"
7
+
6
8
  module Webrat
7
9
  class TimeoutError < WebratError
8
10
  end
@@ -77,7 +79,12 @@ module Webrat
77
79
  webrat_deprecate :clicks_button, :click_button
78
80
 
79
81
  def click_link(link_text_or_regexp, options = {})
80
- pattern = adjust_if_regexp(link_text_or_regexp)
82
+ if link_text_or_regexp.is_a?(Regexp)
83
+ pattern = "evalregex:#{link_text_or_regexp.inspect}"
84
+ else
85
+ pattern = link_text_or_regexp.to_s
86
+ end
87
+
81
88
  locator = "webratlink=#{pattern}"
82
89
  selenium.wait_for_element locator, :timeout_in_seconds => 5
83
90
  selenium.click locator
@@ -162,7 +169,19 @@ module Webrat
162
169
  sleep 0.25
163
170
  end
164
171
 
165
- raise Webrat::TimeoutError.new(message + " (after #{timeout} sec)")
172
+ error_message = "#{message} (after #{timeout} sec)"
173
+
174
+ if $browser
175
+ error_message += <<-EOS
176
+
177
+
178
+ HTML of the page was:
179
+
180
+ #{selenium.get_html_source}"
181
+ EOS
182
+ end
183
+
184
+ raise Webrat::TimeoutError.new(error_message)
166
185
  true
167
186
  end
168
187
 
@@ -15,4 +15,4 @@ module Webrat
15
15
  end
16
16
  end
17
17
  end
18
- end
18
+ end
@@ -21,7 +21,9 @@ Spec::Runner.configure do |config|
21
21
  end
22
22
 
23
23
  config.after :suite do
24
- Process.kill("TERM", File.read("rack.pid").to_i)
24
+ if File.exists?("rack.pid")
25
+ Process.kill("TERM", File.read("rack.pid").to_i)
26
+ end
25
27
  end
26
28
  end
27
29
 
@@ -40,4 +40,7 @@ class WebratController < ApplicationController
40
40
  render :text => params.to_json
41
41
  end
42
42
 
43
+ def within
44
+ end
45
+
43
46
  end
@@ -1,11 +1,9 @@
1
1
  <h1 id='form_title' class='form title'>Webrat Buttons Form</h1>
2
2
 
3
3
  <% form_tag "/buttons" do %>
4
- <input type="button" id="input_button_id" value="input_button_value" />
5
4
  <input type="submit" id="input_submit_id" value="input_submit_value" />
6
5
  <input type="image" id="input_image_id" value="input_image_value" alt="input_image_alt" src="" />
7
6
 
8
- <button type="button" id="button_button_id" value="button_button_value">button_button_text</button>
9
7
  <button type="submit" id="button_submit_id" value="button_submit_value">button_submit_text</button>
10
8
  <button type="image" id="button_image_id" value="button_image_value">button_image_text</button>
11
9
  <% end %>
@@ -1,11 +1,9 @@
1
1
  <h1 id='form_title' class='form title'>Webrat Buttons Form</h1>
2
2
 
3
3
  <% form_tag submit_path do %>
4
- <input type="button" id="input_button_id" value="input_button_value">
5
4
  <input type="submit" id="input_submit_id" value="input_submit_value">
6
5
  <input type="image" id="input_image_id" value="input_image_value" alt="input_image_alt" src="">
7
6
 
8
- <button type="button" id="button_button_id" value="button_button_value">button_button_text</button>
9
7
  <button type="submit" id="button_submit_id" value="button_submit_value">button_submit_text</button>
10
8
  <button type="image" id="button_image_id" value="button_image_value">button_image_text</button>
11
9
  <% end %>
@@ -0,0 +1,3 @@
1
+ <div id="new_object">
2
+ <a href="/">Edit Object</a>
3
+ </div>
@@ -1,4 +1,4 @@
1
- RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION
1
+ # RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION
2
2
 
3
3
  require File.join(File.dirname(__FILE__), 'boot')
4
4
 
@@ -12,6 +12,7 @@ ActionController::Routing::Routes.draw do |map|
12
12
  webrat.before_redirect_form "/before_redirect_form", :action => "before_redirect_form"
13
13
  webrat.redirect_to_show_params "/redirect_to_show_params", :action => "redirect_to_show_params"
14
14
  webrat.show_params "/show_params", :action => "show_params"
15
+ webrat.within "/within", :action => "within"
15
16
 
16
17
  webrat.root :action => "form"
17
18
  end
@@ -1,80 +1,66 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ButtonClickTest < ActionController::IntegrationTest
4
- # <button type="button" ...>
5
- test "should click button with type button by id" do
6
- visit buttons_path
7
- click_button "button_button_id"
8
- end
9
- test "should click button with type button by value" do
10
- visit buttons_path
11
- click_button "button_button_value"
12
- end
13
- test "should click button with type button by html" do
14
- visit buttons_path
15
- click_button "button_button_text"
16
- end
17
-
18
4
  # <button type="submit" ...>
19
5
  test "should click button with type submit by id" do
20
6
  visit buttons_path
21
7
  click_button "button_submit_id"
8
+ assert_contain "success"
22
9
  end
23
10
  test "should click button with type submit by value" do
24
11
  visit buttons_path
25
12
  click_button "button_submit_value"
13
+ assert_contain "success"
26
14
  end
27
15
  test "should click button with type submit by html" do
28
16
  visit buttons_path
29
17
  click_button "button_submit_text"
18
+ assert_contain "success"
30
19
  end
31
20
 
32
21
  # <button type="image" ...>
33
22
  test "should click button with type image by id" do
34
23
  visit buttons_path
35
24
  click_button "button_image_id"
25
+ assert_contain "success"
36
26
  end
37
27
  test "should click button with type image by value" do
38
28
  visit buttons_path
39
29
  click_button "button_image_value"
30
+ assert_contain "success"
40
31
  end
41
32
  test "should click button with type image by html" do
42
33
  visit buttons_path
43
34
  click_button "button_image_text"
44
- end
45
-
46
- # <input type="button" ...>
47
- test "should click image with type button by id" do
48
- visit buttons_path
49
- click_button "input_button_id"
50
- end
51
- test "should click input with type button by value" do
52
- visit buttons_path
53
- click_button "input_button_value"
35
+ assert_contain "success"
54
36
  end
55
37
 
56
38
  # <input type="submit" ...>
57
39
  test "should click input with type submit by id" do
58
40
  visit buttons_path
59
41
  click_button "input_submit_id"
42
+ assert_contain "success"
60
43
  end
61
44
  test "should click input with type submit by value" do
62
45
  visit buttons_path
63
46
  click_button "input_submit_value"
47
+ assert_contain "success"
64
48
  end
65
49
 
66
50
  # <input type="image" ...>
67
51
  test "should click input with type image by id" do
68
52
  visit buttons_path
69
53
  click_button "input_image_id"
54
+ assert_contain "success"
70
55
  end
71
56
  test "should click input with type image by value" do
72
57
  visit buttons_path
73
58
  click_button "input_image_value"
59
+ assert_contain "success"
74
60
  end
75
61
  test "should click input with type image by alt" do
76
62
  visit buttons_path
77
63
  click_button "input_image_alt"
64
+ assert_contain "success"
78
65
  end
79
-
80
- end
66
+ end
@@ -21,4 +21,4 @@ class FillInTest < ActionController::IntegrationTest
21
21
  visit fields_path
22
22
  fill_in "[Field]:", :with => "value"
23
23
  end
24
- end
24
+ end
@@ -24,4 +24,4 @@ class LinkClickTest < ActionController::IntegrationTest
24
24
  click_link "Link With (parens)"
25
25
  assert_contain("Link:link_with_parens")
26
26
  end
27
- end
27
+ end
@@ -22,11 +22,14 @@ class WebratTest < ActionController::IntegrationTest
22
22
  check "TOS"
23
23
  select "January"
24
24
  click_button "Test"
25
+ assert_contain "OK"
25
26
  end
26
27
 
27
28
  test "should check the value of a field" do
28
- visit "/"
29
- assert field_labeled("Prefilled").value, "text"
29
+ webrat.simulate do
30
+ visit "/"
31
+ assert field_labeled("Prefilled").value, "text"
32
+ end
30
33
  end
31
34
 
32
35
  test "should not carry params through redirects" do
@@ -43,20 +46,26 @@ class WebratTest < ActionController::IntegrationTest
43
46
 
44
47
  test "should follow internal redirects" do
45
48
  visit internal_redirect_path
46
- assert !response.redirect?
49
+ webrat.simulate do
50
+ assert !response.redirect?
51
+ end
47
52
  assert response.body.include?("OK")
48
53
  end
49
54
 
50
55
  test "should not follow external redirects" do
51
- visit external_redirect_path
52
- assert response.redirect?
56
+ webrat.simulate do
57
+ visit external_redirect_path
58
+ assert response.redirect?
59
+ end
53
60
  end
54
61
 
55
62
  test "should recognize the host header to follow redirects properly" do
56
- header "Host", "foo.bar"
57
- visit host_redirect_path
58
- assert !response.redirect?
59
- assert response.body.include?("OK")
63
+ webrat.simulate do
64
+ header "Host", "foo.bar"
65
+ visit host_redirect_path
66
+ assert !response.redirect?
67
+ assert response.body.include?("OK")
68
+ end
60
69
  end
61
70
 
62
71
  test "should click link by text" do
@@ -81,6 +90,23 @@ class WebratTest < ActionController::IntegrationTest
81
90
  assert_have_selector "h1"
82
91
  end
83
92
 
93
+ test "should accept an Object argument to #within and translate using dom_id" do
94
+ webrat.simulate do
95
+ visit within_path
96
+
97
+ object = Object.new
98
+ def object.id
99
+ nil
100
+ end
101
+
102
+ within(object) do
103
+ click_link "Edit Object"
104
+ end
105
+
106
+ assert_contain "Webrat Form"
107
+ end
108
+ end
109
+
84
110
  # Firefox detects and prevents infinite redirects under Selenium
85
111
  unless ENV['WEBRAT_INTEGRATION_MODE'] == 'selenium'
86
112
  test "should detect infinite redirects" do