druid-ts 1.1.8 → 1.2.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.
- 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
|