dbrady-webrat 0.4.4
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 +325 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +85 -0
- data/Rakefile +156 -0
- data/install.rb +1 -0
- data/lib/webrat.rb +34 -0
- data/lib/webrat/core.rb +14 -0
- data/lib/webrat/core/configuration.rb +98 -0
- data/lib/webrat/core/elements/area.rb +31 -0
- data/lib/webrat/core/elements/element.rb +33 -0
- data/lib/webrat/core/elements/field.rb +403 -0
- data/lib/webrat/core/elements/form.rb +103 -0
- data/lib/webrat/core/elements/label.rb +31 -0
- data/lib/webrat/core/elements/link.rb +92 -0
- data/lib/webrat/core/elements/select_option.rb +35 -0
- data/lib/webrat/core/locators.rb +20 -0
- 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 +21 -0
- data/lib/webrat/core/matchers.rb +4 -0
- data/lib/webrat/core/matchers/have_content.rb +73 -0
- data/lib/webrat/core/matchers/have_selector.rb +74 -0
- data/lib/webrat/core/matchers/have_tag.rb +21 -0
- data/lib/webrat/core/matchers/have_xpath.rb +147 -0
- data/lib/webrat/core/methods.rb +61 -0
- data/lib/webrat/core/mime.rb +29 -0
- data/lib/webrat/core/save_and_open_page.rb +50 -0
- data/lib/webrat/core/scope.rb +350 -0
- data/lib/webrat/core/session.rb +281 -0
- 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/blank.rb +58 -0
- data/lib/webrat/core_extensions/deprecate.rb +8 -0
- data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
- data/lib/webrat/core_extensions/meta_class.rb +6 -0
- data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
- data/lib/webrat/mechanize.rb +74 -0
- data/lib/webrat/merb.rb +9 -0
- data/lib/webrat/merb_session.rb +65 -0
- data/lib/webrat/rack.rb +24 -0
- data/lib/webrat/rails.rb +105 -0
- data/lib/webrat/rspec-rails.rb +13 -0
- data/lib/webrat/selenium.rb +80 -0
- data/lib/webrat/selenium/location_strategy_javascript/button.js +12 -0
- data/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
- data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +9 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
- data/lib/webrat/selenium/matchers.rb +4 -0
- data/lib/webrat/selenium/matchers/have_content.rb +66 -0
- data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
- data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
- data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
- data/lib/webrat/selenium/selenium_extensions.js +6 -0
- data/lib/webrat/selenium/selenium_session.rb +241 -0
- data/lib/webrat/sinatra.rb +53 -0
- data/vendor/selenium-server.jar +0 -0
- metadata +141 -0
@@ -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_excluding_hidden)
|
25
|
+
else
|
26
|
+
Webrat::XML.css_search(@session.current_dom, "#" + for_id).first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "webrat/core_extensions/blank"
|
2
|
+
|
3
|
+
require "webrat/core/elements/element"
|
4
|
+
|
5
|
+
module Webrat
|
6
|
+
class Link < Element #:nodoc:
|
7
|
+
|
8
|
+
def self.xpath_search
|
9
|
+
".//a[@href]"
|
10
|
+
end
|
11
|
+
|
12
|
+
def click(options = {})
|
13
|
+
method = options[:method] || http_method
|
14
|
+
return if href =~ /^#/ && method == :get
|
15
|
+
|
16
|
+
options[:javascript] = true if options[:javascript].nil?
|
17
|
+
|
18
|
+
if options[:javascript]
|
19
|
+
@session.request_page(absolute_href, method, data)
|
20
|
+
else
|
21
|
+
@session.request_page(absolute_href, :get, {})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def id
|
28
|
+
Webrat::XML.attribute(@element, "id")
|
29
|
+
end
|
30
|
+
|
31
|
+
def data
|
32
|
+
authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token}
|
33
|
+
end
|
34
|
+
|
35
|
+
def title
|
36
|
+
Webrat::XML.attribute(@element, "title")
|
37
|
+
end
|
38
|
+
|
39
|
+
def href
|
40
|
+
Webrat::XML.attribute(@element, "href")
|
41
|
+
end
|
42
|
+
|
43
|
+
def absolute_href
|
44
|
+
if href =~ /^\?/
|
45
|
+
"#{@session.current_url}#{href}"
|
46
|
+
elsif href !~ %r{^https?://} && (href !~ /^\//)
|
47
|
+
"#{@session.current_url}/#{href}"
|
48
|
+
else
|
49
|
+
href
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def authenticity_token
|
54
|
+
return unless onclick && onclick.include?("s.setAttribute('name', 'authenticity_token');") &&
|
55
|
+
onclick =~ /s\.setAttribute\('value', '([a-f0-9]{40})'\);/
|
56
|
+
$LAST_MATCH_INFO.captures.first
|
57
|
+
end
|
58
|
+
|
59
|
+
def onclick
|
60
|
+
Webrat::XML.attribute(@element, "onclick")
|
61
|
+
end
|
62
|
+
|
63
|
+
def http_method
|
64
|
+
if !onclick.blank? && onclick.include?("f.submit()")
|
65
|
+
http_method_from_js_form
|
66
|
+
else
|
67
|
+
:get
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def http_method_from_js_form
|
72
|
+
if onclick.include?("m.setAttribute('name', '_method')")
|
73
|
+
http_method_from_fake_method_param
|
74
|
+
else
|
75
|
+
:post
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def http_method_from_fake_method_param
|
80
|
+
if onclick.include?("m.setAttribute('value', 'delete')")
|
81
|
+
:delete
|
82
|
+
elsif onclick.include?("m.setAttribute('value', 'put')")
|
83
|
+
:put
|
84
|
+
elsif onclick.include?("m.setAttribute('value', 'post')")
|
85
|
+
:post
|
86
|
+
else
|
87
|
+
raise Webrat::WebratError.new("No HTTP method for _method param in #{onclick.inspect}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
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
|
@@ -0,0 +1,20 @@
|
|
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"
|
11
|
+
|
12
|
+
module Webrat
|
13
|
+
module Locators
|
14
|
+
|
15
|
+
def field_by_xpath(xpath)
|
16
|
+
Field.load(@session, Webrat::XML.xpath_at(dom, xpath))
|
17
|
+
end
|
18
|
+
|
19
|
+
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
|
@@ -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
|