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.
- data/History.txt +140 -30
- data/README.rdoc +85 -0
- data/Rakefile +72 -22
- data/install.rb +1 -1
- data/lib/webrat.rb +12 -17
- data/lib/webrat/core.rb +9 -7
- data/lib/webrat/core/configuration.rb +87 -0
- data/lib/webrat/core/{area.rb → elements/area.rb} +7 -20
- data/lib/webrat/core/elements/element.rb +33 -0
- data/lib/webrat/core/elements/field.rb +394 -0
- data/lib/webrat/core/elements/form.rb +103 -0
- data/lib/webrat/core/elements/label.rb +31 -0
- data/lib/webrat/core/{link.rb → elements/link.rb} +15 -26
- data/lib/webrat/core/elements/select_option.rb +35 -0
- data/lib/webrat/core/locators.rb +13 -85
- data/lib/webrat/core/locators/area_locator.rb +38 -0
- data/lib/webrat/core/locators/button_locator.rb +54 -0
- data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
- data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
- data/lib/webrat/core/locators/field_locator.rb +25 -0
- data/lib/webrat/core/locators/field_named_locator.rb +41 -0
- data/lib/webrat/core/locators/form_locator.rb +19 -0
- data/lib/webrat/core/locators/label_locator.rb +34 -0
- data/lib/webrat/core/locators/link_locator.rb +66 -0
- data/lib/webrat/core/locators/locator.rb +20 -0
- data/lib/webrat/core/locators/select_option_locator.rb +59 -0
- data/lib/webrat/core/logging.rb +5 -9
- data/lib/webrat/core/matchers/have_content.rb +19 -44
- data/lib/webrat/core/matchers/have_selector.rb +15 -2
- data/lib/webrat/core/matchers/have_tag.rb +15 -2
- data/lib/webrat/core/matchers/have_xpath.rb +21 -28
- data/lib/webrat/core/methods.rb +32 -15
- data/lib/webrat/core/mime.rb +3 -3
- data/lib/webrat/core/save_and_open_page.rb +50 -0
- data/lib/webrat/core/scope.rb +183 -41
- data/lib/webrat/core/session.rb +125 -63
- data/lib/webrat/core/xml.rb +115 -0
- data/lib/webrat/core/xml/hpricot.rb +19 -0
- data/lib/webrat/core/xml/nokogiri.rb +76 -0
- data/lib/webrat/core/xml/rexml.rb +24 -0
- data/lib/webrat/core_extensions/deprecate.rb +1 -1
- data/lib/webrat/mechanize.rb +58 -12
- data/lib/webrat/merb.rb +7 -73
- data/lib/webrat/merb_session.rb +65 -0
- data/lib/webrat/rack.rb +1 -1
- data/lib/webrat/rails.rb +56 -55
- data/lib/webrat/rspec-rails.rb +13 -0
- data/lib/webrat/selenium.rb +92 -1
- data/lib/webrat/selenium/matchers.rb +146 -0
- data/lib/webrat/selenium/selenium_session.rb +179 -80
- data/lib/webrat/sinatra.rb +14 -4
- data/vendor/selenium-server.jar +0 -0
- metadata +36 -17
- data/README.txt +0 -90
- data/TODO.txt +0 -10
- data/init.rb +0 -3
- data/lib/webrat/core/field.rb +0 -332
- data/lib/webrat/core/flunk.rb +0 -7
- data/lib/webrat/core/form.rb +0 -130
- data/lib/webrat/core/label.rb +0 -18
- data/lib/webrat/core/nokogiri.rb +0 -44
- data/lib/webrat/core/select_option.rb +0 -29
- 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
|
7
|
-
@
|
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(' ',' ')
|
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
|
36
|
+
Webrat::XML.attribute(@element, "title")
|
48
37
|
end
|
49
38
|
|
50
39
|
def href
|
51
|
-
@element
|
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?://
|
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
|
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
|
data/lib/webrat/core/locators.rb
CHANGED
@@ -1,92 +1,20 @@
|
|
1
|
-
require "webrat/
|
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
|
80
|
-
|
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
|