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,37 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class FieldByIdLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ Field.load(@session, field_element)
10
+ end
11
+
12
+ def field_element
13
+ field_elements.detect do |field_element|
14
+ if @value.is_a?(Regexp)
15
+ Webrat::XML.attribute(field_element, "id") =~ @value
16
+ else
17
+ Webrat::XML.attribute(field_element, "id") == @value.to_s
18
+ end
19
+ end
20
+ end
21
+
22
+ def field_elements
23
+ Webrat::XML.xpath_search(@dom, *Field.xpath_search)
24
+ end
25
+
26
+ def error_message
27
+ "Could not find field with id #{@value.inspect}"
28
+ end
29
+
30
+ end
31
+
32
+ def field_with_id(id, *field_types)
33
+ FieldByIdLocator.new(@session, dom, id, *field_types).locate!
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ require "webrat/core_extensions/detect_mapped"
2
+ require "webrat/core/locators/locator"
3
+
4
+ module Webrat
5
+ module Locators
6
+
7
+ class FieldLabeledLocator < Locator # :nodoc:
8
+
9
+ def locate
10
+ matching_labels.any? && matching_labels.detect_mapped { |label| label.field }
11
+ end
12
+
13
+ def matching_labels
14
+ matching_label_elements.sort_by do |label_element|
15
+ text(label_element).length
16
+ end.map do |label_element|
17
+ Label.load(@session, label_element)
18
+ end
19
+ end
20
+
21
+ def matching_label_elements
22
+ label_elements.select do |label_element|
23
+ text(label_element) =~ /^\W*#{Regexp.escape(@value.to_s)}\b/i
24
+ end
25
+ end
26
+
27
+ def label_elements
28
+ Webrat::XML.xpath_search(@dom, Label.xpath_search)
29
+ end
30
+
31
+ def error_message
32
+ "Could not find field labeled #{@value.inspect}"
33
+ end
34
+
35
+ def text(element)
36
+ str = Webrat::XML.all_inner_text(element)
37
+ str.gsub!("\n","")
38
+ str.strip!
39
+ str.squeeze!(" ")
40
+ str
41
+ end
42
+
43
+ end
44
+
45
+ # Locates a form field based on a <tt>label</tt> element in the HTML source.
46
+ # This can be useful in order to verify that a field is pre-filled with the
47
+ # correct value.
48
+ #
49
+ # Example:
50
+ # field_labeled("First name").value.should == "Bryan"
51
+ def field_labeled(label, *field_types)
52
+ FieldLabeledLocator.new(@session, dom, label, *field_types).locate!
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class FieldLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ FieldByIdLocator.new(@session, @dom, @value).locate ||
10
+ FieldNamedLocator.new(@session, @dom, @value, *@field_types).locate ||
11
+ FieldLabeledLocator.new(@session, @dom, @value, *@field_types).locate
12
+ end
13
+
14
+ def error_message
15
+ "Could not find field: #{@value.inspect}"
16
+ end
17
+
18
+ end
19
+
20
+ def field(*args) # :nodoc:
21
+ FieldLocator.new(@session, dom, *args).locate!
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class FieldNamedLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ Field.load(@session, field_element)
10
+ end
11
+
12
+ def field_element
13
+ field_elements.detect do |field_element|
14
+ Webrat::XML.attribute(field_element, "name") == @value.to_s
15
+ end
16
+ end
17
+
18
+ def field_elements
19
+ Webrat::XML.xpath_search(@dom, *xpath_searches)
20
+ end
21
+
22
+ def xpath_searches
23
+ if @field_types.any?
24
+ @field_types.map { |field_type| field_type.xpath_search }.flatten
25
+ else
26
+ Array(Field.xpath_search)
27
+ end
28
+ end
29
+
30
+ def error_message
31
+ "Could not find field named #{@value.inspect}"
32
+ end
33
+
34
+ end
35
+
36
+ def field_named(name, *field_types)
37
+ FieldNamedLocator.new(@session, dom, name, *field_types).locate!
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class FormLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ Form.load(@session, form_element)
10
+ end
11
+
12
+ def form_element
13
+ Webrat::XML.css_at(@dom, "#" + @value)
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ require "webrat/core_extensions/detect_mapped"
2
+ require "webrat/core/locators/locator"
3
+
4
+ module Webrat
5
+ module Locators
6
+
7
+ class LabelLocator < Locator # :nodoc:
8
+
9
+ def locate
10
+ Label.load(@session, label_element)
11
+ end
12
+
13
+ def label_element
14
+ label_elements.detect do |label_element|
15
+ text(label_element) =~ /^\W*#{Regexp.escape(@value.to_s)}\b/i
16
+ end
17
+ end
18
+
19
+ def label_elements
20
+ Webrat::XML.xpath_search(@dom, Label.xpath_search)
21
+ end
22
+
23
+ def text(label_element)
24
+ str = Webrat::XML.all_inner_text(label_element)
25
+ str.gsub!("\n","")
26
+ str.strip!
27
+ str.squeeze!(" ")
28
+ str
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ require "webrat/core/locators/locator"
2
+
3
+ module Webrat
4
+ module Locators
5
+
6
+ class LinkLocator < Locator # :nodoc:
7
+
8
+ def locate
9
+ Link.load(@session, link_element)
10
+ end
11
+
12
+ def link_element
13
+ matching_links.min { |a, b| Webrat::XML.all_inner_text(a).length <=> Webrat::XML.all_inner_text(b).length }
14
+ end
15
+
16
+ def matching_links
17
+ @matching_links ||= link_elements.select do |link_element|
18
+ matches_text?(link_element) ||
19
+ matches_id?(link_element)
20
+ end
21
+ end
22
+
23
+ def matches_text?(link)
24
+ if @value.is_a?(Regexp)
25
+ matcher = @value
26
+ else
27
+ matcher = /#{Regexp.escape(@value.to_s)}/i
28
+ end
29
+
30
+ replace_nbsp(Webrat::XML.all_inner_text(link)) =~ matcher ||
31
+ replace_nbsp_ref(Webrat::XML.inner_html(link)) =~ matcher ||
32
+ Webrat::XML.attribute(link, "title")=~ matcher
33
+ end
34
+
35
+ def matches_id?(link)
36
+ if @value.is_a?(Regexp)
37
+ (Webrat::XML.attribute(link, "id") =~ @value) ? true : false
38
+ else
39
+ (Webrat::XML.attribute(link, "id") == @value) ? true : false
40
+ end
41
+ end
42
+
43
+ def link_elements
44
+ Webrat::XML.xpath_search(@dom, *Link.xpath_search)
45
+ end
46
+
47
+ def replace_nbsp(str)
48
+ str.gsub([0xA0].pack('U'), ' ')
49
+ end
50
+
51
+ def replace_nbsp_ref(str)
52
+ str.gsub('&#xA0;',' ').gsub('&nbsp;', ' ')
53
+ end
54
+
55
+ def error_message
56
+ "Could not find link with text or title or id #{@value.inspect}"
57
+ end
58
+
59
+ end
60
+
61
+ def find_link(text_or_title_or_id) #:nodoc:
62
+ LinkLocator.new(@session, dom, text_or_title_or_id).locate!
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,20 @@
1
+ module Webrat
2
+ module Locators
3
+
4
+ class Locator # :nodoc:
5
+
6
+ def initialize(session, dom, value, *field_types)
7
+ @session = session
8
+ @dom = dom
9
+ @value = value
10
+ @field_types = field_types
11
+ end
12
+
13
+ def locate!
14
+ locate || raise(NotFoundError.new(error_message))
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ require "webrat/core_extensions/detect_mapped"
2
+ require "webrat/core/locators/locator"
3
+
4
+ module Webrat
5
+ module Locators
6
+
7
+ class SelectOptionLocator < Locator # :nodoc:
8
+
9
+ def initialize(session, dom, option_text, id_or_name_or_label)
10
+ @session = session
11
+ @dom = dom
12
+ @option_text = option_text
13
+ @id_or_name_or_label = id_or_name_or_label
14
+ end
15
+
16
+ def locate
17
+ if @id_or_name_or_label
18
+ field = FieldLocator.new(@session, @dom, @id_or_name_or_label, SelectField).locate!
19
+
20
+ field.options.detect do |o|
21
+ if @option_text.is_a?(Regexp)
22
+ Webrat::XML.inner_html(o.element) =~ @option_text
23
+ else
24
+ Webrat::XML.inner_html(o.element) == @option_text.to_s
25
+ end
26
+ end
27
+ else
28
+ option_element = option_elements.detect do |o|
29
+ if @option_text.is_a?(Regexp)
30
+ Webrat::XML.inner_html(o) =~ @option_text
31
+ else
32
+ Webrat::XML.inner_html(o) == @option_text.to_s
33
+ end
34
+ end
35
+
36
+ SelectOption.load(@session, option_element)
37
+ end
38
+ end
39
+
40
+ def option_elements
41
+ Webrat::XML.xpath_search(@dom, *SelectOption.xpath_search)
42
+ end
43
+
44
+ def error_message
45
+ if @id_or_name_or_label
46
+ "The '#{@option_text}' option was not found in the #{@id_or_name_or_label.inspect} select box"
47
+ else
48
+ "Could not find option #{@option_text.inspect}"
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ def select_option(option_text, id_or_name_or_label = nil) #:nodoc:
55
+ SelectOptionLocator.new(@session, dom, option_text, id_or_name_or_label).locate!
56
+ end
57
+
58
+ end
59
+ end
@@ -1,10 +1,5 @@
1
1
  module Webrat
2
2
  module Logging #:nodoc:
3
-
4
- def warn_log(message) # :nodoc:
5
- return unless logger
6
- logger.warn message
7
- end
8
3
 
9
4
  def debug_log(message) # :nodoc:
10
5
  return unless logger
@@ -12,10 +7,11 @@ module Webrat
12
7
  end
13
8
 
14
9
  def logger # :nodoc:
15
- if defined? RAILS_DEFAULT_LOGGER
16
- RAILS_DEFAULT_LOGGER
17
- elsif defined? Merb
18
- Merb.logger
10
+ case Webrat.configuration.mode
11
+ when :rails
12
+ defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER : nil
13
+ when :merb
14
+ Merb.logger
19
15
  else
20
16
  nil
21
17
  end
@@ -7,28 +7,13 @@ module Webrat
7
7
  end
8
8
 
9
9
  def matches?(stringlike)
10
- if defined?(Nokogiri::XML)
11
- matches_nokogiri?(stringlike)
10
+ if Webrat.configuration.parse_with_nokogiri?
11
+ @document = Webrat.nokogiri_document(stringlike)
12
12
  else
13
- matches_rexml?(stringlike)
13
+ @document = Webrat.hpricot_document(stringlike)
14
14
  end
15
- end
16
-
17
- def matches_rexml?(stringlike)
18
- @document = rexml_document(stringlike)
19
- @element = @document.inner_text
20
-
21
- case @content
22
- when String
23
- @element.include?(@content)
24
- when Regexp
25
- @element.match(@content)
26
- end
27
- end
28
-
29
- def matches_nokogiri?(stringlike)
30
- @document = Webrat.nokogiri_document(stringlike)
31
- @element = @document.inner_text
15
+
16
+ @element = Webrat::XML.inner_text(@document)
32
17
 
33
18
  case @content
34
19
  when String
@@ -37,27 +22,6 @@ module Webrat
37
22
  @element.match(@content)
38
23
  end
39
24
  end
40
-
41
- def rexml_document(stringlike)
42
- stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
43
-
44
- case stringlike
45
- when REXML::Document
46
- stringlike.root
47
- when REXML::Node
48
- stringlike
49
- when StringIO, String
50
- begin
51
- REXML::Document.new(stringlike.to_s).root
52
- rescue REXML::ParseException => e
53
- if e.message.include?("second root element")
54
- REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
55
- else
56
- raise e
57
- end
58
- end
59
- end
60
- end
61
25
 
62
26
  # ==== Returns
63
27
  # String:: The failure message.
@@ -83,12 +47,23 @@ module Webrat
83
47
 
84
48
  # Matches the contents of an HTML document with
85
49
  # whatever string is supplied
86
- #
87
- # ---
88
- # @api public
89
50
  def contain(content)
90
51
  HasContent.new(content)
91
52
  end
92
53
 
54
+ # Asserts that the body of the response contain
55
+ # the supplied string or regexp
56
+ def assert_contain(content)
57
+ hc = HasContent.new(content)
58
+ assert hc.matches?(response_body), hc.failure_message
59
+ end
60
+
61
+ # Asserts that the body of the response
62
+ # does not contain the supplied string or regepx
63
+ def assert_not_contain(content)
64
+ hc = HasContent.new(content)
65
+ assert !hc.matches?(response_body), hc.negative_failure_message
66
+ end
67
+
93
68
  end
94
69
  end