kookaburra 0.4.0 → 0.5.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/VERSION +1 -1
- data/kookaburra.gemspec +2 -4
- data/lib/kookaburra/test_data.rb +0 -4
- metadata +4 -6
- data/lib/kookaburra/test_data/factory.rb +0 -18
- data/lib/kookaburra/ui_driver/mixins/has_fields.rb +0 -178
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
data/kookaburra.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "kookaburra"
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.5.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Renewable Funding, LLC"]
|
|
12
|
-
s.date = "2012-01-
|
|
12
|
+
s.date = "2012-01-18"
|
|
13
13
|
s.description = "Cucumber + Capybara = Kookaburra? It made sense at the time."
|
|
14
14
|
s.email = "devteam@renewfund.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -30,10 +30,8 @@ Gem::Specification.new do |s|
|
|
|
30
30
|
"lib/kookaburra/api_driver.rb",
|
|
31
31
|
"lib/kookaburra/given_driver.rb",
|
|
32
32
|
"lib/kookaburra/test_data.rb",
|
|
33
|
-
"lib/kookaburra/test_data/factory.rb",
|
|
34
33
|
"lib/kookaburra/ui_driver.rb",
|
|
35
34
|
"lib/kookaburra/ui_driver/mixins/has_browser.rb",
|
|
36
|
-
"lib/kookaburra/ui_driver/mixins/has_fields.rb",
|
|
37
35
|
"lib/kookaburra/ui_driver/mixins/has_strategies.rb",
|
|
38
36
|
"lib/kookaburra/ui_driver/mixins/has_subcomponents.rb",
|
|
39
37
|
"lib/kookaburra/ui_driver/mixins/has_ui_component.rb",
|
data/lib/kookaburra/test_data.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kookaburra
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 11
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
|
-
-
|
|
8
|
+
- 5
|
|
9
9
|
- 0
|
|
10
|
-
version: 0.
|
|
10
|
+
version: 0.5.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Renewable Funding, LLC
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2012-01-
|
|
18
|
+
date: 2012-01-18 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
|
@@ -175,10 +175,8 @@ files:
|
|
|
175
175
|
- lib/kookaburra/api_driver.rb
|
|
176
176
|
- lib/kookaburra/given_driver.rb
|
|
177
177
|
- lib/kookaburra/test_data.rb
|
|
178
|
-
- lib/kookaburra/test_data/factory.rb
|
|
179
178
|
- lib/kookaburra/ui_driver.rb
|
|
180
179
|
- lib/kookaburra/ui_driver/mixins/has_browser.rb
|
|
181
|
-
- lib/kookaburra/ui_driver/mixins/has_fields.rb
|
|
182
180
|
- lib/kookaburra/ui_driver/mixins/has_strategies.rb
|
|
183
181
|
- lib/kookaburra/ui_driver/mixins/has_subcomponents.rb
|
|
184
182
|
- lib/kookaburra/ui_driver/mixins/has_ui_component.rb
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Factories for setting up attribute hashes
|
|
2
|
-
module Kookaburra
|
|
3
|
-
class TestData
|
|
4
|
-
class Factory
|
|
5
|
-
attr_reader :test_data
|
|
6
|
-
def initialize(test_data)
|
|
7
|
-
@test_data = test_data
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
protected
|
|
11
|
-
def hash_for_merging(overrides = {})
|
|
12
|
-
HashWithIndifferentAccess.new( overrides.with_indifferent_access ).tap do |hash_to_merge|
|
|
13
|
-
yield hash_to_merge if block_given?
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
module Kookaburra
|
|
2
|
-
class UIDriver
|
|
3
|
-
module HasFields
|
|
4
|
-
module ClassMethods
|
|
5
|
-
def submit_button_locator(locator)
|
|
6
|
-
define_method(:submit_button_locator) { locator }
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def has_radio_button_for(*names)
|
|
10
|
-
names.each do |n|
|
|
11
|
-
input_xpath_builder_names[n] = :build_radio_input_xpath
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def has_select_for(*names)
|
|
16
|
-
names.each do |n|
|
|
17
|
-
input_xpath_builder_names[n] = :build_select_input_xpath
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def input_xpath_builder_names
|
|
22
|
-
# Inputs without a type attribute, or with a custom or unknown type are
|
|
23
|
-
# textual, so we need to exclude the types that we don't want.
|
|
24
|
-
@input_xpath_builder_names ||= HashWithIndifferentAccess.new(:build_textual_input_xpath)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def is_select?(name)
|
|
28
|
-
input_xpath_builder_names[name] == :build_select_input_xpath
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
module InstanceMethods
|
|
33
|
-
def build_input_xpath(attribute)
|
|
34
|
-
"(" +
|
|
35
|
-
"(.//textarea)|" +
|
|
36
|
-
"(.//select)|" +
|
|
37
|
-
"(.//input[(not(@type='button')) and (not(@type='reset')) and (not(@type='submit'))])" +
|
|
38
|
-
")[contains(@id,'_#{attribute}')]"
|
|
39
|
-
# TODO: Avoid false positives by matching to the end of the id
|
|
40
|
-
# string for everything but radio buttons and checkboxes
|
|
41
|
-
# ... or something better than that.
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def build_textual_input_xpath(attribute, value=nil)
|
|
45
|
-
# Since the type attribute might not be present or might contain
|
|
46
|
-
# just about any value, check for and exclude nodes with type
|
|
47
|
-
# containing a non-textual value.
|
|
48
|
-
"(" +
|
|
49
|
-
"(.//textarea)|" +
|
|
50
|
-
"(.//input[" +
|
|
51
|
-
"(not(@type='button')) and (not(@type='checkbox')) and (not(@type='radio')) and " +
|
|
52
|
-
"(not(@type='reset')) and (not(@type='submit'))" +
|
|
53
|
-
"])" +
|
|
54
|
-
")[" +
|
|
55
|
-
"substring(@id,string-length(@id)-#{attribute.length-1},#{attribute.length})='#{attribute}'" +
|
|
56
|
-
"]"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def build_radio_input_xpath(attribute, value=nil)
|
|
60
|
-
# The id will be the attribute suffixed by something representative of
|
|
61
|
-
# the button value, with an underscore in between, but we don't necessarily
|
|
62
|
-
# know the correct suffix, so ensure that the "_" is in the id, and then
|
|
63
|
-
# find the correct match using the value attribute.
|
|
64
|
-
xpath = ".//input[@type='radio'][contains(@id, #{attribute}_)]"
|
|
65
|
-
xpath = "(#{xpath})[@value='#{value}']"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def build_select_input_xpath(attribute, value=nil)
|
|
69
|
-
xpath = ".//select[contains(@id, #{attribute})]/option[text()='#{value}']"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Find the specified input by its field name. The value argument is
|
|
73
|
-
# used to find the correct input if (as in the case of a radio button)
|
|
74
|
-
# there might be a separate input element for each value the field might
|
|
75
|
-
# contain. Otherwise, it is ignored. When the name value will be used,
|
|
76
|
-
# its #to_s value must be valid as an xpath string body expression.
|
|
77
|
-
def find_input(attribute, value=nil, nth=1, msg=nil)
|
|
78
|
-
method = self.class.input_xpath_builder_names[attribute]
|
|
79
|
-
#TODO: Build a qualified attribute name, and pass that to the xpath builder
|
|
80
|
-
# to handle forms with multiple models that may have common attribute
|
|
81
|
-
# names.
|
|
82
|
-
xpath = send(method, attribute.to_s, value.to_s)
|
|
83
|
-
xpath = "(#{xpath})[#{nth}]" if nth > 1
|
|
84
|
-
browser.find(:xpath, xpath, :message => msg)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def submit_button_locator
|
|
88
|
-
raise "Subclass responsibility!"
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def submit!
|
|
92
|
-
click_on submit_button_locator
|
|
93
|
-
no_500_error!
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def fill_in_fields(hash, idx = 0)
|
|
97
|
-
@body = nil
|
|
98
|
-
|
|
99
|
-
# If not explicitly ordered, then we must think the fill-in order doesn't
|
|
100
|
-
# matter, so make the order more assuredly arbitrary to find out sooner
|
|
101
|
-
# if that's not a correct thought.
|
|
102
|
-
hash = hash.map.shuffle if Hash === hash && ! ActiveSupport::OrderedHash === hash
|
|
103
|
-
|
|
104
|
-
hash.each do |field, value|
|
|
105
|
-
fill_in_form_element(field, value, idx)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
private
|
|
110
|
-
def fill_in_form_element(attribute, value, idx = 0, opts = {})
|
|
111
|
-
msg = "cannot find the field for '#{attribute}' with value '#{value}' to fill it in."
|
|
112
|
-
input = find_input(attribute, value, idx+1, msg)
|
|
113
|
-
set_value(input, value, attribute)
|
|
114
|
-
end
|
|
115
|
-
def set_value(input, value, attribute)
|
|
116
|
-
if self.class.is_select?(attribute)
|
|
117
|
-
input.select_option
|
|
118
|
-
else
|
|
119
|
-
input.set value
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
public
|
|
123
|
-
|
|
124
|
-
def tag_visible?(css)
|
|
125
|
-
browser.has_css?(css, :visible => true)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def no_tag_visible?(css)
|
|
129
|
-
# use of wait_until is supposed to be redundant with #has_no_css?, but
|
|
130
|
-
# getting intermittent Selenium::WebDriver::Error::StaleElementReferenceError.
|
|
131
|
-
# Just wrapping in an explicit wait_until did not capture the exception,
|
|
132
|
-
# so apparently that one is explicitly passed through rather than being
|
|
133
|
-
# retried.
|
|
134
|
-
browser.wait_until do
|
|
135
|
-
begin
|
|
136
|
-
browser.has_no_css?(css, :visible => true)
|
|
137
|
-
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
|
138
|
-
next false # Keep trying if not yet timed out.
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def find_disableable_inputs(attribute)
|
|
147
|
-
inputs = []
|
|
148
|
-
browser.wait_until do
|
|
149
|
-
inputs = browser.all(:xpath, build_input_xpath(attribute))
|
|
150
|
-
inputs.present?
|
|
151
|
-
end
|
|
152
|
-
inputs
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def form_element_disabled?(attribute, *_)
|
|
156
|
-
# TODO (SLG): this will only check the currently-selected radio button, not all of them
|
|
157
|
-
find_disableable_inputs(attribute).all? { |input| !!input[:disabled] }
|
|
158
|
-
rescue Capybara::TimeoutError
|
|
159
|
-
puts "Timed out trying to find disableable inputs for #{attribute}"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def all_form_elements_disabled?(desc, attr_names, &b)
|
|
163
|
-
errs = attr_names.inject([]) do |mem, attr_name|
|
|
164
|
-
(mem << "#{desc} #{attr_name} is not read-only") unless form_element_disabled?(attr_name)
|
|
165
|
-
mem
|
|
166
|
-
end
|
|
167
|
-
raise errs.join("\n") if errs.present?
|
|
168
|
-
true
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def self.included(receiver)
|
|
173
|
-
receiver.extend ClassMethods
|
|
174
|
-
receiver.send :include, InstanceMethods
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
end
|