webrat 0.3.4 → 0.4.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 (63) hide show
  1. data/History.txt +140 -30
  2. data/README.rdoc +85 -0
  3. data/Rakefile +72 -22
  4. data/install.rb +1 -1
  5. data/lib/webrat.rb +12 -17
  6. data/lib/webrat/core.rb +9 -7
  7. data/lib/webrat/core/configuration.rb +87 -0
  8. data/lib/webrat/core/{area.rb → elements/area.rb} +7 -20
  9. data/lib/webrat/core/elements/element.rb +33 -0
  10. data/lib/webrat/core/elements/field.rb +394 -0
  11. data/lib/webrat/core/elements/form.rb +103 -0
  12. data/lib/webrat/core/elements/label.rb +31 -0
  13. data/lib/webrat/core/{link.rb → elements/link.rb} +15 -26
  14. data/lib/webrat/core/elements/select_option.rb +35 -0
  15. data/lib/webrat/core/locators.rb +13 -85
  16. data/lib/webrat/core/locators/area_locator.rb +38 -0
  17. data/lib/webrat/core/locators/button_locator.rb +54 -0
  18. data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  19. data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
  20. data/lib/webrat/core/locators/field_locator.rb +25 -0
  21. data/lib/webrat/core/locators/field_named_locator.rb +41 -0
  22. data/lib/webrat/core/locators/form_locator.rb +19 -0
  23. data/lib/webrat/core/locators/label_locator.rb +34 -0
  24. data/lib/webrat/core/locators/link_locator.rb +66 -0
  25. data/lib/webrat/core/locators/locator.rb +20 -0
  26. data/lib/webrat/core/locators/select_option_locator.rb +59 -0
  27. data/lib/webrat/core/logging.rb +5 -9
  28. data/lib/webrat/core/matchers/have_content.rb +19 -44
  29. data/lib/webrat/core/matchers/have_selector.rb +15 -2
  30. data/lib/webrat/core/matchers/have_tag.rb +15 -2
  31. data/lib/webrat/core/matchers/have_xpath.rb +21 -28
  32. data/lib/webrat/core/methods.rb +32 -15
  33. data/lib/webrat/core/mime.rb +3 -3
  34. data/lib/webrat/core/save_and_open_page.rb +50 -0
  35. data/lib/webrat/core/scope.rb +183 -41
  36. data/lib/webrat/core/session.rb +125 -63
  37. data/lib/webrat/core/xml.rb +115 -0
  38. data/lib/webrat/core/xml/hpricot.rb +19 -0
  39. data/lib/webrat/core/xml/nokogiri.rb +76 -0
  40. data/lib/webrat/core/xml/rexml.rb +24 -0
  41. data/lib/webrat/core_extensions/deprecate.rb +1 -1
  42. data/lib/webrat/mechanize.rb +58 -12
  43. data/lib/webrat/merb.rb +7 -73
  44. data/lib/webrat/merb_session.rb +65 -0
  45. data/lib/webrat/rack.rb +1 -1
  46. data/lib/webrat/rails.rb +56 -55
  47. data/lib/webrat/rspec-rails.rb +13 -0
  48. data/lib/webrat/selenium.rb +92 -1
  49. data/lib/webrat/selenium/matchers.rb +146 -0
  50. data/lib/webrat/selenium/selenium_session.rb +179 -80
  51. data/lib/webrat/sinatra.rb +14 -4
  52. data/vendor/selenium-server.jar +0 -0
  53. metadata +36 -17
  54. data/README.txt +0 -90
  55. data/TODO.txt +0 -10
  56. data/init.rb +0 -3
  57. data/lib/webrat/core/field.rb +0 -332
  58. data/lib/webrat/core/flunk.rb +0 -7
  59. data/lib/webrat/core/form.rb +0 -130
  60. data/lib/webrat/core/label.rb +0 -18
  61. data/lib/webrat/core/nokogiri.rb +0 -44
  62. data/lib/webrat/core/select_option.rb +0 -29
  63. data/lib/webrat/rails/redirect_actions.rb +0 -18
@@ -0,0 +1,103 @@
1
+ require "webrat/core/elements/field"
2
+ require "webrat/core_extensions/blank"
3
+
4
+ require "webrat/core/elements/element"
5
+ require "webrat/core/locators/field_named_locator"
6
+
7
+ module Webrat
8
+ class Form < Element #:nodoc:
9
+ attr_reader :element
10
+
11
+ def self.xpath_search
12
+ ".//form"
13
+ end
14
+
15
+ def fields
16
+ @fields ||= Field.load_all(@session, @element)
17
+ end
18
+
19
+ def submit
20
+ @session.request_page(form_action, form_method, params)
21
+ end
22
+
23
+ def field_named(name, *field_types)
24
+ Webrat::Locators::FieldNamedLocator.new(@session, dom, name, *field_types).locate
25
+ end
26
+
27
+ protected
28
+
29
+ def dom
30
+ Webrat::XML.xpath_at(@session.dom, path)
31
+ end
32
+
33
+ def fields_by_type(field_types)
34
+ if field_types.any?
35
+ fields.select { |f| field_types.include?(f.class) }
36
+ else
37
+ fields
38
+ end
39
+ end
40
+
41
+ def params
42
+ all_params = {}
43
+
44
+ fields.each do |field|
45
+ next if field.to_param.nil?
46
+ merge(all_params, field.to_param)
47
+ end
48
+
49
+ all_params
50
+ end
51
+
52
+ def form_method
53
+ Webrat::XML.attribute(@element, "method").blank? ? :get : Webrat::XML.attribute(@element, "method").downcase
54
+ end
55
+
56
+ def form_action
57
+ Webrat::XML.attribute(@element, "action").blank? ? @session.current_url : Webrat::XML.attribute(@element, "action")
58
+ end
59
+
60
+ def merge(all_params, new_param)
61
+ new_param.each do |key, value|
62
+ case all_params[key]
63
+ when *hash_classes
64
+ merge_hash_values(all_params[key], value)
65
+ when Array
66
+ all_params[key] += value
67
+ else
68
+ all_params[key] = value
69
+ end
70
+ end
71
+ end
72
+
73
+ def merge_hash_values(a, b) # :nodoc:
74
+ a.keys.each do |k|
75
+ if b.has_key?(k)
76
+ case [a[k], b[k]].map{|value| value.class}
77
+ when *hash_classes.zip(hash_classes)
78
+ a[k] = merge_hash_values(a[k], b[k])
79
+ b.delete(k)
80
+ when [Array, Array]
81
+ a[k] += b[k]
82
+ b.delete(k)
83
+ end
84
+ end
85
+ end
86
+ a.merge!(b)
87
+ end
88
+
89
+ def hash_classes
90
+ klasses = [Hash]
91
+
92
+ case Webrat.configuration.mode
93
+ when :rails
94
+ klasses << HashWithIndifferentAccess
95
+ when :merb
96
+ klasses << Mash
97
+ end
98
+
99
+ klasses
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,31 @@
1
+ require "webrat/core/elements/element"
2
+
3
+ module Webrat
4
+ class Label < Element #:nodoc:
5
+
6
+ attr_reader :element
7
+
8
+ def self.xpath_search
9
+ ".//label"
10
+ end
11
+
12
+ def for_id
13
+ Webrat::XML.attribute(@element, "for")
14
+ end
15
+
16
+ def field
17
+ Field.load(@session, field_element)
18
+ end
19
+
20
+ protected
21
+
22
+ def field_element
23
+ if for_id.blank?
24
+ Webrat::XML.xpath_at(@element, *Field.xpath_search)
25
+ else
26
+ Webrat::XML.css_search(@session.dom, "#" + for_id).first
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -1,11 +1,12 @@
1
1
  require "webrat/core_extensions/blank"
2
2
 
3
+ require "webrat/core/elements/element"
4
+
3
5
  module Webrat
4
- class Link #:nodoc:
6
+ class Link < Element #:nodoc:
5
7
 
6
- def initialize(session, element)
7
- @session = session
8
- @element = element
8
+ def self.xpath_search
9
+ ".//a[@href]"
9
10
  end
10
11
 
11
12
  def click(options = {})
@@ -21,40 +22,28 @@ module Webrat
21
22
  end
22
23
  end
23
24
 
24
- def matches_text?(link_text)
25
- html = text.gsub('&#xA0;',' ')
26
-
27
- if link_text.is_a?(Regexp)
28
- matcher = link_text
29
- else
30
- matcher = /#{Regexp.escape(link_text.to_s)}/i
31
- end
32
-
33
- html =~ matcher || title =~ matcher
34
- end
35
-
36
- def text
37
- @element.inner_html
38
- end
39
-
40
25
  protected
41
26
 
27
+ def id
28
+ Webrat::XML.attribute(@element, "id")
29
+ end
30
+
42
31
  def data
43
32
  authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token}
44
33
  end
45
34
 
46
35
  def title
47
- @element['title']
36
+ Webrat::XML.attribute(@element, "title")
48
37
  end
49
38
 
50
39
  def href
51
- @element["href"]
40
+ Webrat::XML.attribute(@element, "href")
52
41
  end
53
42
 
54
43
  def absolute_href
55
44
  if href =~ /^\?/
56
45
  "#{@session.current_url}#{href}"
57
- elsif href !~ %r{^https?://www.example.com(/.*)} && (href !~ /^\//)
46
+ elsif href !~ %r{^https?://} && (href !~ /^\//)
58
47
  "#{@session.current_url}/#{href}"
59
48
  else
60
49
  href
@@ -68,7 +57,7 @@ module Webrat
68
57
  end
69
58
 
70
59
  def onclick
71
- @element["onclick"]
60
+ Webrat::XML.attribute(@element, "onclick")
72
61
  end
73
62
 
74
63
  def http_method
@@ -93,9 +82,9 @@ module Webrat
93
82
  elsif onclick.include?("m.setAttribute('value', 'put')")
94
83
  :put
95
84
  else
96
- raise "No HTTP method for _method param in #{onclick.inspect}"
85
+ raise Webrat::WebratError.new("No HTTP method for _method param in #{onclick.inspect}")
97
86
  end
98
87
  end
99
-
88
+
100
89
  end
101
90
  end
@@ -0,0 +1,35 @@
1
+ require "webrat/core/elements/element"
2
+
3
+ module Webrat
4
+ class SelectOption < Element #:nodoc:
5
+
6
+ def self.xpath_search
7
+ ".//option"
8
+ end
9
+
10
+ def choose
11
+ select.raise_error_if_disabled
12
+ select.set(value)
13
+ end
14
+
15
+ protected
16
+
17
+ def select
18
+ SelectField.load(@session, select_element)
19
+ end
20
+
21
+ def select_element
22
+ parent = @element.parent
23
+
24
+ while parent.respond_to?(:parent)
25
+ return parent if parent.name == 'select'
26
+ parent = parent.parent
27
+ end
28
+ end
29
+
30
+ def value
31
+ Webrat::XML.attribute(@element, "value") || Webrat::XML.inner_html(@element)
32
+ end
33
+
34
+ end
35
+ end
@@ -1,92 +1,20 @@
1
- require "webrat/core_extensions/detect_mapped"
1
+ require "webrat/core/locators/area_locator"
2
+ require "webrat/core/locators/button_locator"
3
+ require "webrat/core/locators/field_labeled_locator"
4
+ require "webrat/core/locators/label_locator"
5
+ require "webrat/core/locators/field_named_locator"
6
+ require "webrat/core/locators/field_by_id_locator"
7
+ require "webrat/core/locators/select_option_locator"
8
+ require "webrat/core/locators/link_locator"
9
+ require "webrat/core/locators/field_locator"
10
+ require "webrat/core/locators/form_locator"
2
11
 
3
12
  module Webrat
4
13
  module Locators
5
-
6
- def field(*args)
7
- # This is the default locator strategy
8
- find_field_with_id(*args) ||
9
- find_field_named(*args) ||
10
- field_labeled(*args) ||
11
- flunk("Could not find field: #{args.inspect}")
12
- end
13
-
14
- def field_labeled(label, *field_types)
15
- find_field_labeled(label, *field_types) ||
16
- flunk("Could not find field labeled #{label.inspect}")
17
- end
18
-
19
- def field_named(name, *field_types)
20
- find_field_named(name, *field_types) ||
21
- flunk("Could not find field named #{name.inspect}")
22
- end
23
-
24
- def field_with_id(id, *field_types)
25
- find_field_with_id(id, *field_types) ||
26
- flunk("Could not find field with id #{id.inspect}")
27
- end
28
-
29
- def find_field_labeled(label, *field_types) #:nodoc:
30
- forms.detect_mapped do |form|
31
- form.field_labeled(label, *field_types)
32
- end
33
- end
34
-
35
- def find_field_named(name, *field_types) #:nodoc:
36
- forms.detect_mapped do |form|
37
- form.field_named(name, *field_types)
38
- end
39
- end
40
-
41
- def find_field_with_id(id, *field_types) #:nodoc:
42
- forms.detect_mapped do |form|
43
- form.field_with_id(id, *field_types)
44
- end
45
- end
46
-
47
- def find_select_option(option_text, id_or_name_or_label) #:nodoc:
48
- if id_or_name_or_label
49
- field = field(id_or_name_or_label, SelectField)
50
- return field.find_option(option_text)
51
- else
52
- select_option = forms.detect_mapped do |form|
53
- form.find_select_option(option_text)
54
- end
55
-
56
- return select_option if select_option
57
- end
58
-
59
- flunk("Could not find option #{option_text.inspect}")
60
- end
61
-
62
- def find_button(value) #:nodoc:
63
- button = forms.detect_mapped do |form|
64
- form.find_button(value)
65
- end
66
-
67
- if button
68
- return button
69
- else
70
- flunk("Could not find button #{value.inspect}")
71
- end
72
- end
73
-
74
- def find_area(area_name) #:nodoc:
75
- areas.detect { |area| area.matches_text?(area_name) } ||
76
- flunk("Could not find area with name #{area_name}")
77
- end
78
14
 
79
- def find_link(text) #:nodoc:
80
- matching_links = links.select do |possible_link|
81
- possible_link.matches_text?(text)
82
- end
83
-
84
- if matching_links.any?
85
- matching_links.min { |a, b| a.text.length <=> b.text.length }
86
- else
87
- flunk("Could not find link with text #{text.inspect}")
88
- end
15
+ def field_by_xpath(xpath)
16
+ Field.load(@session, Webrat::XML.xpath_at(dom, xpath))
89
17
  end
90
18
 
91
19
  end
92
- end
20
+ end
@@ -0,0 +1,38 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class AreaLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ Area.load(@session, area_element)
10
+ end
11
+
12
+ def area_element
13
+ area_elements.detect do |area_element|
14
+ Webrat::XML.attribute(area_element, "title") =~ matcher ||
15
+ Webrat::XML.attribute(area_element, "id") =~ matcher
16
+ end
17
+ end
18
+
19
+ def matcher
20
+ /#{Regexp.escape(@value.to_s)}/i
21
+ end
22
+
23
+ def area_elements
24
+ Webrat::XML.xpath_search(@dom, Area.xpath_search)
25
+ end
26
+
27
+ def error_message
28
+ "Could not find area with name #{@value}"
29
+ end
30
+
31
+ end
32
+
33
+ def find_area(id_or_title) #:nodoc:
34
+ AreaLocator.new(@session, dom, id_or_title).locate!
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class ButtonLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ ButtonField.load(@session, button_element)
10
+ end
11
+
12
+ def button_element
13
+ button_elements.detect do |element|
14
+ @value.nil? ||
15
+ matches_id?(element) ||
16
+ matches_value?(element) ||
17
+ matches_html?(element) ||
18
+ matches_alt?(element)
19
+ end
20
+ end
21
+
22
+ def matches_id?(element)
23
+ (@value.is_a?(Regexp) && Webrat::XML.attribute(element, "id") =~ @value) ||
24
+ (!@value.is_a?(Regexp) && Webrat::XML.attribute(element, "id") == @value.to_s)
25
+ end
26
+
27
+ def matches_value?(element)
28
+ Webrat::XML.attribute(element, "value") =~ /^\W*#{Regexp.escape(@value.to_s)}/i
29
+ end
30
+
31
+ def matches_html?(element)
32
+ Webrat::XML.inner_html(element) =~ /#{Regexp.escape(@value.to_s)}/i
33
+ end
34
+
35
+ def matches_alt?(element)
36
+ Webrat::XML.attribute(element, "alt") =~ /^\W*#{Regexp.escape(@value.to_s)}/i
37
+ end
38
+
39
+ def button_elements
40
+ Webrat::XML.xpath_search(@dom, *ButtonField.xpath_search)
41
+ end
42
+
43
+ def error_message
44
+ "Could not find button #{@value.inspect}"
45
+ end
46
+
47
+ end
48
+
49
+ def find_button(value) #:nodoc:
50
+ ButtonLocator.new(@session, dom, value).locate!
51
+ end
52
+
53
+ end
54
+ end