druid-ts 1.1.8 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +27 -0
- data/features/bold.feature +21 -0
- data/features/element.feature +7 -0
- data/features/frames.feature +15 -0
- data/features/html/frames.html +3 -3
- data/features/html/iframes.html +2 -2
- data/features/html/multi_elements.html +1 -0
- data/features/html/static_elements.html +25 -8
- data/features/javascript.feature +10 -1
- data/features/link.feature +4 -0
- data/features/multi_elements.feature +6 -0
- data/features/radio_button_group.feature +28 -0
- data/features/section.feature +128 -0
- data/features/select_list.feature +4 -0
- data/features/step_definations/bold_steps.rb +11 -0
- data/features/step_definations/element_steps.rb +8 -0
- data/features/step_definations/frame_steps.rb +53 -11
- data/features/step_definations/javasript_steps.rb +9 -0
- data/features/step_definations/link_steps.rb +8 -0
- data/features/step_definations/multi_elements_steps.rb +13 -0
- data/features/step_definations/radio_button_group_steps.rb +32 -0
- data/features/step_definations/section_steps.rb +262 -0
- data/features/step_definations/table_steps.rb +9 -0
- data/features/support/env.rb +1 -0
- data/features/support/page.rb +16 -5
- data/features/table.feature +18 -14
- data/lib/druid.rb +42 -30
- data/lib/druid/accessors.rb +188 -55
- data/lib/druid/assist.rb +46 -4
- data/lib/druid/elements.rb +1 -0
- data/lib/druid/elements/bold.rb +8 -0
- data/lib/druid/elements/element.rb +16 -3
- data/lib/druid/elements/link.rb +7 -0
- data/lib/druid/elements/radio_button.rb +0 -7
- data/lib/druid/elements/select_list.rb +2 -2
- data/lib/druid/elements/table.rb +7 -0
- data/lib/druid/javascript/angularjs.rb +12 -0
- data/lib/druid/javascript_framework_facade.rb +5 -3
- data/lib/druid/locator_generator.rb +1 -0
- data/lib/druid/page_factory.rb +1 -0
- data/lib/druid/page_populator.rb +10 -1
- data/lib/druid/sections.rb +29 -0
- data/lib/druid/version.rb +1 -1
- data/spec/druid/accessors_spec.rb +79 -13
- data/spec/druid/druid_spec.rb +2 -1
- data/spec/druid/element_locators_spec.rb +26 -4
- data/spec/druid/elements/bold_spec.rb +21 -0
- data/spec/druid/elements/link_spec.rb +1 -1
- data/spec/druid/elements/page_factory_spec.rb +2 -2
- data/spec/druid/elements/radio_button_spec.rb +0 -5
- data/spec/druid/elements/select_list_spec.rb +3 -3
- data/spec/druid/page_factory_spec.rb +15 -15
- data/spec/druid/page_populator_spec.rb +4 -4
- data/spec/druid/page_section_spec.rb +61 -0
- data/spec/spec_helper.rb +1 -0
- metadata +20 -1
data/lib/druid/assist.rb
CHANGED
@@ -81,10 +81,6 @@ module Druid
|
|
81
81
|
process_call("radio(identifier).set", Elements::RadioButton, identifier)
|
82
82
|
end
|
83
83
|
|
84
|
-
def clear_radio identifier
|
85
|
-
process_call("radio(identifier).clear", Elements::RadioButton, identifier)
|
86
|
-
end
|
87
|
-
|
88
84
|
def radio_selected? identifier
|
89
85
|
process_call("radio(identifier).set?", Elements::RadioButton, identifier)
|
90
86
|
end
|
@@ -508,6 +504,38 @@ module Druid
|
|
508
504
|
find_elements("element(identifier)", Elements::Element, identifier)
|
509
505
|
end
|
510
506
|
|
507
|
+
#
|
508
|
+
# method to retrieve the text for a b
|
509
|
+
#
|
510
|
+
def b_text_for(identifier)
|
511
|
+
process_call("b(identifier).text", Elements::Bold, identifier, nil, 'b')
|
512
|
+
end
|
513
|
+
|
514
|
+
def b_for(identifier)
|
515
|
+
find_element("b(identifier)", Elements::Bold, identifier, 'b')
|
516
|
+
end
|
517
|
+
|
518
|
+
#
|
519
|
+
# method to retrieve all b elements
|
520
|
+
#
|
521
|
+
def bs_for(identifier)
|
522
|
+
find_elements("bs(identifier)", Elements::Bold, identifier, 'b')
|
523
|
+
end
|
524
|
+
|
525
|
+
#
|
526
|
+
# method to return a Druid rooted at an element
|
527
|
+
#
|
528
|
+
def page_for(identifier, section_class)
|
529
|
+
find_page(identifier, section_class)
|
530
|
+
end
|
531
|
+
|
532
|
+
#
|
533
|
+
# method to return a collection of Druids rooted at elements
|
534
|
+
#
|
535
|
+
def pages_for(identifier, section_class)
|
536
|
+
SectionCollection.new(find_pages(identifier, section_class))
|
537
|
+
end
|
538
|
+
|
511
539
|
private
|
512
540
|
|
513
541
|
def find_elements(the_call, type, identifier, tag_name=nil)
|
@@ -524,6 +552,20 @@ module Druid
|
|
524
552
|
type.new(element)
|
525
553
|
end
|
526
554
|
|
555
|
+
def find_pages(identifier, section_class)
|
556
|
+
identifier, frame_identifiers = parse_identifiers(identifier, Elements::Element, 'element')
|
557
|
+
elements = driver.instance_eval "#{nested_frames(frame_identifiers)}elements(identifier)"
|
558
|
+
switch_to_default_content(frame_identifiers)
|
559
|
+
elements.map { |element| section_class.new(element) }
|
560
|
+
end
|
561
|
+
|
562
|
+
def find_page(identifier, section_class)
|
563
|
+
identifier, frame_identifiers = parse_identifiers(identifier, Elements::Element, 'element')
|
564
|
+
element = driver.instance_eval "#{nested_frames(frame_identifiers)}element(identifier)"
|
565
|
+
switch_to_default_content(frame_identifiers)
|
566
|
+
section_class.new(element)
|
567
|
+
end
|
568
|
+
|
527
569
|
def process_call(the_call, type, identifier, value=nil, tag_name=nil)
|
528
570
|
identifier, frame_identifiers = parse_identifiers(identifier, type, tag_name)
|
529
571
|
value = driver.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
|
data/lib/druid/elements.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'watir-webdriver'
|
2
|
+
require 'watir-webdriver/extensions/select_text'
|
1
3
|
require 'druid/nested_elements'
|
2
4
|
require 'druid/assist'
|
3
5
|
module Druid
|
@@ -88,6 +90,13 @@ module Druid
|
|
88
90
|
element.attribute_value attribute_name
|
89
91
|
end
|
90
92
|
|
93
|
+
#
|
94
|
+
# retrieve the class name for an element
|
95
|
+
#
|
96
|
+
def class_name
|
97
|
+
element.class_name
|
98
|
+
end
|
99
|
+
|
91
100
|
#
|
92
101
|
# Click this element
|
93
102
|
#
|
@@ -153,6 +162,10 @@ module Druid
|
|
153
162
|
element.focus
|
154
163
|
end
|
155
164
|
|
165
|
+
def select_text text
|
166
|
+
element.select_text text
|
167
|
+
end
|
168
|
+
|
156
169
|
#
|
157
170
|
# get the id of element
|
158
171
|
#
|
@@ -280,7 +293,7 @@ module Druid
|
|
280
293
|
protected
|
281
294
|
|
282
295
|
def self.have_to_build_xpath(identifier)
|
283
|
-
['table', 'span', 'div', 'td', 'li', 'ol', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'label', 'area', 'canvas', 'audio', 'video'].include? identifier[:tag_name] and identifier[:name]
|
296
|
+
['table', 'span', 'div', 'td', 'li', 'ol', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'label', 'area', 'canvas', 'audio', 'video','b'].include? identifier[:tag_name] and identifier[:name]
|
284
297
|
end
|
285
298
|
|
286
299
|
def self.build_xpath_for identifier
|
@@ -295,14 +308,14 @@ module Druid
|
|
295
308
|
end
|
296
309
|
xpath = ".//button"
|
297
310
|
xpath << "[#{attribute_expression(btn_ident)}]" unless btn_ident.empty?
|
298
|
-
xpath
|
311
|
+
xpath = "(#{xpath})[#{idx+1}]" if idx
|
299
312
|
identifier[:type] = %w[button reset submit image]
|
300
313
|
xpath << " | .//input"
|
301
314
|
else
|
302
315
|
xpath = ".//#{tag_locator}"
|
303
316
|
end
|
304
317
|
xpath << "[#{attribute_expression(identifier)}]" unless identifier.empty?
|
305
|
-
xpath
|
318
|
+
xpath = "(#{xpath})[#{idx+1}]" if idx
|
306
319
|
xpath
|
307
320
|
end
|
308
321
|
|
data/lib/druid/elements/link.rb
CHANGED
data/lib/druid/elements/table.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'druid/javascript/jquery'
|
2
2
|
require 'druid/javascript/prototype'
|
3
3
|
require 'druid/javascript/yui'
|
4
|
+
require 'druid/javascript/angularjs'
|
4
5
|
|
5
6
|
module Druid
|
6
7
|
#
|
@@ -18,8 +19,8 @@ module Druid
|
|
18
19
|
#
|
19
20
|
# Set the framework to use
|
20
21
|
#
|
21
|
-
# @param [Symbol] the framework to use. :jquery and :prototype
|
22
|
-
# are supported
|
22
|
+
# @param [Symbol] the framework to use. :jquery and :prototype, :yui,
|
23
|
+
# and :angularjs are supported
|
23
24
|
#
|
24
25
|
def framework=(framework)
|
25
26
|
initialize_script_builder unless @builder
|
@@ -58,7 +59,8 @@ module Druid
|
|
58
59
|
@builder = {
|
59
60
|
:jquery => Druid::Javascript::JQuery,
|
60
61
|
:prototype => Druid::Javascript::Prototype,
|
61
|
-
:yui => Druid::Javascript::YUI
|
62
|
+
:yui => Druid::Javascript::YUI,
|
63
|
+
:angularjs => Druid::Javascript::AngularJS
|
62
64
|
}
|
63
65
|
end
|
64
66
|
|
data/lib/druid/page_factory.rb
CHANGED
@@ -64,6 +64,7 @@ module Druid
|
|
64
64
|
#
|
65
65
|
def on_page(page_class, params={:using_params => {}}, visit=false, &block)
|
66
66
|
page_class = class_from_string(page_class) if page_class.is_a? String
|
67
|
+
return super(page_class, params, visit, &block) unless page_class.ancestors.include? Druid
|
67
68
|
merged = page_class.params.merge(params[:using_params])
|
68
69
|
page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
|
69
70
|
@current_page = page_class.new(@driver, visit)
|
data/lib/druid/page_populator.rb
CHANGED
@@ -31,6 +31,7 @@ module Druid
|
|
31
31
|
def populate_page_with(data)
|
32
32
|
data.each do |key, value|
|
33
33
|
populate_checkbox(key, value) if is_checkbox?(key) and is_enabled?(key)
|
34
|
+
populate_radiobuttongroup(key, value) if is_radiobuttongroup?(key)
|
34
35
|
populate_radiobutton(key, value) if is_radiobutton?(key) and is_enabled?(key)
|
35
36
|
populate_text(key, value) if is_text?(key) and is_enabled?(key)
|
36
37
|
end
|
@@ -49,7 +50,10 @@ module Druid
|
|
49
50
|
|
50
51
|
def populate_radiobutton(key, value)
|
51
52
|
return self.send "select_#{key}" if value
|
52
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
def populate_radiobuttongroup(key, value)
|
56
|
+
return self.send "select_#{key}", value
|
53
57
|
end
|
54
58
|
|
55
59
|
def is_text?(key)
|
@@ -64,7 +68,12 @@ module Druid
|
|
64
68
|
respond_to?("select_#{key}".to_sym)
|
65
69
|
end
|
66
70
|
|
71
|
+
def is_radiobuttongroup?(key)
|
72
|
+
respond_to?("select_#{key}".to_sym) and respond_to?("#{key}_values")
|
73
|
+
end
|
74
|
+
|
67
75
|
def is_enabled?(key)
|
76
|
+
return false if is_radiobuttongroup?(key)
|
68
77
|
return true if (self.send "#{key}_element").tag_name == "textarea"
|
69
78
|
element = self.send("#{key}_element")
|
70
79
|
element.enabled? and element.visible?
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Druid
|
2
|
+
class SectionCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize sections
|
6
|
+
@sections = sections
|
7
|
+
end
|
8
|
+
|
9
|
+
def each &block
|
10
|
+
@sections.each &block
|
11
|
+
end
|
12
|
+
|
13
|
+
def [] index
|
14
|
+
@sections[index]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_by values_hash
|
18
|
+
@sections.find { |section|
|
19
|
+
values_hash.all? { |key, value| value === section.public_send(key) }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def select_by values_hash
|
24
|
+
SectionCollection.new @sections.select { |section|
|
25
|
+
values_hash.all? { |key, value| value === section.public_send(key) }
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/druid/version.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
class GenericPage
|
4
|
+
include Druid
|
5
|
+
|
6
|
+
wait_for_expected_title 'expected title'
|
7
|
+
end
|
8
|
+
|
3
9
|
class AccessorsTestDruid
|
4
10
|
include Druid
|
5
11
|
|
@@ -15,7 +21,7 @@ class AccessorsTestDruid
|
|
15
21
|
div(:message, :id => 'message_id')
|
16
22
|
table(:cart, :id => 'cart_id')
|
17
23
|
cell(:total, :id => 'total')
|
18
|
-
span(:
|
24
|
+
span(:alert_span, :id => 'alert_id')
|
19
25
|
image(:logo, :id => 'logo')
|
20
26
|
hidden_field(:social_security_number, :id => 'ssn')
|
21
27
|
form(:login, :id => 'login')
|
@@ -35,6 +41,7 @@ class AccessorsTestDruid
|
|
35
41
|
canvas(:my_canvas, :id => 'canvas_id')
|
36
42
|
audio(:acdc, :id => 'audio_id')
|
37
43
|
video(:movie, :id => 'video_id')
|
44
|
+
b(:bold, :id => 'bold')
|
38
45
|
end
|
39
46
|
|
40
47
|
class BlockDruid
|
@@ -67,7 +74,7 @@ class BlockDruid
|
|
67
74
|
div :footer do |element|
|
68
75
|
"div"
|
69
76
|
end
|
70
|
-
span :
|
77
|
+
span :alert_span do |element|
|
71
78
|
"span"
|
72
79
|
end
|
73
80
|
table :cart do |element|
|
@@ -127,6 +134,9 @@ class BlockDruid
|
|
127
134
|
video :movie do |element|
|
128
135
|
"video"
|
129
136
|
end
|
137
|
+
b :bold do |element|
|
138
|
+
"b"
|
139
|
+
end
|
130
140
|
end
|
131
141
|
|
132
142
|
class TestDruidBackUp
|
@@ -172,6 +182,10 @@ describe Druid::Accessors do
|
|
172
182
|
expect(driver).not_to receive(:goto)
|
173
183
|
TestDruidBackUp.new(driver,true)
|
174
184
|
end
|
185
|
+
|
186
|
+
it "should provide the page url" do
|
187
|
+
expect(druid.page_url_value).to eql "http://apple.com"
|
188
|
+
end
|
175
189
|
end
|
176
190
|
|
177
191
|
describe "validating the page title" do
|
@@ -562,7 +576,6 @@ describe Druid::Accessors do
|
|
562
576
|
expect(druid).to respond_to :first_element
|
563
577
|
expect(druid).to respond_to :select_first
|
564
578
|
expect(druid).to respond_to :first_selected?
|
565
|
-
expect(druid).to respond_to :clear_first
|
566
579
|
end
|
567
580
|
|
568
581
|
it "should call a block on the element method when present" do
|
@@ -576,11 +589,6 @@ describe Druid::Accessors do
|
|
576
589
|
druid.select_first
|
577
590
|
end
|
578
591
|
|
579
|
-
it "should clear a radio button" do
|
580
|
-
expect(driver).to receive_message_chain(:radio, :clear)
|
581
|
-
druid.clear_first
|
582
|
-
end
|
583
|
-
|
584
592
|
it "should determine if a radio is selected" do
|
585
593
|
expect(driver).to receive_message_chain(:radio, :set?).and_return(true)
|
586
594
|
expect(druid.first_selected?).to be true
|
@@ -665,24 +673,24 @@ describe Druid::Accessors do
|
|
665
673
|
describe "span accessors" do
|
666
674
|
context "when called on a page object" do
|
667
675
|
it "should generate accessor methods" do
|
668
|
-
expect(druid).to respond_to :
|
669
|
-
expect(druid).to respond_to :
|
676
|
+
expect(druid).to respond_to :alert_span
|
677
|
+
expect(druid).to respond_to :alert_span_element
|
670
678
|
end
|
671
679
|
|
672
680
|
it "should call a block on the element method when present" do
|
673
|
-
expect(block_druid.
|
681
|
+
expect(block_druid.alert_span_element).to eql "span"
|
674
682
|
end
|
675
683
|
end
|
676
684
|
|
677
685
|
context "implementation" do
|
678
686
|
it "should retrieve the text from a span" do
|
679
687
|
expect(driver).to receive_message_chain(:span, :text).and_return('Alert')
|
680
|
-
expect(druid.
|
688
|
+
expect(druid.alert_span).to eql 'Alert'
|
681
689
|
end
|
682
690
|
|
683
691
|
it "should retrieve the span element from the page" do
|
684
692
|
expect(driver).to receive(:span)
|
685
|
-
expect(druid.
|
693
|
+
expect(druid.alert_span_element).to be_instance_of Druid::Elements::Span
|
686
694
|
end
|
687
695
|
end
|
688
696
|
end
|
@@ -1112,4 +1120,62 @@ describe Druid::Accessors do
|
|
1112
1120
|
end
|
1113
1121
|
end
|
1114
1122
|
end
|
1123
|
+
|
1124
|
+
describe "b accessors" do
|
1125
|
+
context "when called on a page object" do
|
1126
|
+
it "should generate accessor methods" do
|
1127
|
+
expect(druid).to respond_to(:bold)
|
1128
|
+
expect(druid).to respond_to(:bold_element)
|
1129
|
+
expect(druid).to respond_to(:bold?)
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
it "should call a block on the element method when present" do
|
1133
|
+
expect(block_druid.bold_element).to eql "b"
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
it "should retrieve the text from the b" do
|
1138
|
+
expect(driver).to receive(:b).and_return(driver)
|
1139
|
+
expect(driver).to receive(:text).and_return("value")
|
1140
|
+
expect(druid.bold).to eql "value"
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
it "should retrieve the element from the page" do
|
1144
|
+
expect(driver).to receive(:b).and_return(driver)
|
1145
|
+
element = druid.bold_element
|
1146
|
+
expect(element).to be_instance_of Druid::Elements::Bold
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
describe "accessors" do
|
1152
|
+
let(:driver) { mock_driver }
|
1153
|
+
let(:page) { GenericPage.new driver}
|
1154
|
+
|
1155
|
+
context '#wait_for_expected_title' do
|
1156
|
+
before(:each) do
|
1157
|
+
allow(driver).to receive(:wait_until).and_yield
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
it "true if already there" do
|
1161
|
+
allow(driver).to receive(:title).and_return 'expected title'
|
1162
|
+
expect(page.wait_for_expected_title?).to be_truthy
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
it "does not wait if it already is there" do
|
1166
|
+
allow(driver).to receive(:title).and_return 'expected title'
|
1167
|
+
expect(driver).to_not receive(:wait_until)
|
1168
|
+
expect(page.wait_for_expected_title?).to be_truthy
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
it "errors when it does not match" do
|
1172
|
+
allow(driver).to receive(:title).and_return 'wrong title'
|
1173
|
+
expect { page.wait_for_expected_title? }.to raise_error "Expected title 'expected title' instead of 'wrong title'"
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
it 'pick up when the title changes' do
|
1177
|
+
allow(driver).to receive(:title).and_return 'wrong title', 'expected title'
|
1178
|
+
expect(page.wait_for_expected_title?).to be_truthy
|
1179
|
+
end
|
1180
|
+
end
|
1115
1181
|
end
|