webrat 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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