druid-ts 0.0.1
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 +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -0
- data/README.md +11 -0
- data/Rakefile +33 -0
- data/cucumber.yml +2 -0
- data/features/button.feature +38 -0
- data/features/checkbox.feature +39 -0
- data/features/div.feature +38 -0
- data/features/element.feature +114 -0
- data/features/form.feature +29 -0
- data/features/hidden_field.feature +33 -0
- data/features/html/images/circle.png +0 -0
- data/features/html/static_elements.html +89 -0
- data/features/html/success.html +8 -0
- data/features/image.feature +33 -0
- data/features/link.feature +39 -0
- data/features/list_item.feature +31 -0
- data/features/ordered_list.feature +35 -0
- data/features/page_level_actions.feature +31 -0
- data/features/radio_button.feature +42 -0
- data/features/select_list.feature +48 -0
- data/features/span.feature +36 -0
- data/features/step_definations/button_steps.rb +24 -0
- data/features/step_definations/checkbox_steps.rb +31 -0
- data/features/step_definations/div_steps.rb +19 -0
- data/features/step_definations/element_steps.rb +29 -0
- data/features/step_definations/form_steps.rb +11 -0
- data/features/step_definations/hidden_field_steps.rb +19 -0
- data/features/step_definations/image_steps.rb +19 -0
- data/features/step_definations/link_steps.rb +29 -0
- data/features/step_definations/list_item_steps.rb +12 -0
- data/features/step_definations/ordered_list_steps.rb +33 -0
- data/features/step_definations/page_level_actions_steps.rb +48 -0
- data/features/step_definations/page_traversal_steps.rb +4 -0
- data/features/step_definations/radio_button_steps.rb +23 -0
- data/features/step_definations/select_list_steps.rb +42 -0
- data/features/step_definations/span_steps.rb +15 -0
- data/features/step_definations/table_cell_steps.rb +19 -0
- data/features/step_definations/table_steps.rb +38 -0
- data/features/step_definations/text_area_steps.rb +19 -0
- data/features/step_definations/text_field_steps.rb +23 -0
- data/features/step_definations/unordered_list_steps.rb +11 -0
- data/features/support/env.rb +17 -0
- data/features/support/page.rb +163 -0
- data/features/support/url_helper.rb +16 -0
- data/features/table.feature +43 -0
- data/features/table_cell.feature +36 -0
- data/features/text_area.feature +32 -0
- data/features/text_field.feature +42 -0
- data/features/unordered_list.feature +36 -0
- data/lib/druid.rb +80 -0
- data/lib/druid/accessors.rb +506 -0
- data/lib/druid/elements.rb +19 -0
- data/lib/druid/elements/button.rb +11 -0
- data/lib/druid/elements/check_box.rb +7 -0
- data/lib/druid/elements/div.rb +10 -0
- data/lib/druid/elements/element.rb +129 -0
- data/lib/druid/elements/form.rb +7 -0
- data/lib/druid/elements/hidden_field.rb +11 -0
- data/lib/druid/elements/image.rb +7 -0
- data/lib/druid/elements/link.rb +16 -0
- data/lib/druid/elements/list_item.rb +7 -0
- data/lib/druid/elements/ordered_list.rb +30 -0
- data/lib/druid/elements/radio_button.rb +7 -0
- data/lib/druid/elements/select_list.rb +18 -0
- data/lib/druid/elements/span.rb +11 -0
- data/lib/druid/elements/table.rb +30 -0
- data/lib/druid/elements/table_cell.rb +7 -0
- data/lib/druid/elements/table_row.rb +22 -0
- data/lib/druid/elements/text_area.rb +11 -0
- data/lib/druid/elements/text_field.rb +11 -0
- data/lib/druid/elements/unordered_list.rb +28 -0
- data/lib/druid/page_factory.rb +58 -0
- data/spec/druid/druid_spec.rb +38 -0
- data/spec/spec_helper.rb +7 -0
- metadata +224 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'druid/elements/element.rb'
|
2
|
+
require 'druid/elements/ordered_list.rb'
|
3
|
+
require 'druid/elements/unordered_list.rb'
|
4
|
+
require 'druid/elements/table.rb'
|
5
|
+
require 'druid/elements/table_row.rb'
|
6
|
+
require 'druid/elements/select_list.rb'
|
7
|
+
require 'druid/elements/link.rb'
|
8
|
+
require 'druid/elements/button.rb'
|
9
|
+
require 'druid/elements/check_box.rb'
|
10
|
+
require 'druid/elements/radio_button.rb'
|
11
|
+
require 'druid/elements/text_field.rb'
|
12
|
+
require 'druid/elements/div.rb'
|
13
|
+
require 'druid/elements/table_cell.rb'
|
14
|
+
require 'druid/elements/image.rb'
|
15
|
+
require 'druid/elements/span.rb'
|
16
|
+
require 'druid/elements/hidden_field.rb'
|
17
|
+
require 'druid/elements/list_item.rb'
|
18
|
+
require 'druid/elements/text_area.rb'
|
19
|
+
require 'druid/elements/form.rb'
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Druid
|
2
|
+
module Elements
|
3
|
+
#
|
4
|
+
# Contains functionality that is common across all elements
|
5
|
+
#
|
6
|
+
class Element
|
7
|
+
attr_accessor :element
|
8
|
+
|
9
|
+
def initialize(element)
|
10
|
+
@element = element
|
11
|
+
end
|
12
|
+
|
13
|
+
# def self.identifier_for identifier
|
14
|
+
# identifier_for_element identifier, finders, mapping
|
15
|
+
# end
|
16
|
+
def self.identifier_for identifier
|
17
|
+
if have_to_build_xpath(identifier)
|
18
|
+
how = :xpath
|
19
|
+
what = build_xpath_for(identifier)
|
20
|
+
return how => what
|
21
|
+
else
|
22
|
+
all_identities = {}
|
23
|
+
identifier.each do |key, value|
|
24
|
+
each = {key => value}
|
25
|
+
ident = identifier_for_element each, finders, mapping
|
26
|
+
all_identities[ident.keys.first] = ident.values.first
|
27
|
+
end
|
28
|
+
all_identities
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.have_to_build_xpath(identifier)
|
33
|
+
['table', 'span', 'div', 'td', 'li', 'ol', 'ul'].include? identifier[:tag_name] and identifier[:name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.build_xpath_for identifier
|
37
|
+
tag_locator = identifier.delete(:tag_name)
|
38
|
+
idx = identifier.delete(:index)
|
39
|
+
identifier.delete(:tag_name)
|
40
|
+
xpath = ".//#{tag_locator}"
|
41
|
+
xpath << "[#{attribute_expression(identifier)}]" unless identifier.empty?
|
42
|
+
xpath << "[#{idx+1}]" if idx
|
43
|
+
xpath
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.attribute_expression(identifier)
|
47
|
+
identifier.map do |key, value|
|
48
|
+
if value.kind_of?(Array)
|
49
|
+
"(" + value.map { |v| equal_pair(key, v) }.join(" or ") + ")"
|
50
|
+
else
|
51
|
+
equal_pair(key, value)
|
52
|
+
end
|
53
|
+
end.join(" and ")
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.equal_pair(key, value)
|
57
|
+
if key == :label
|
58
|
+
"@id=//label[normalize-space()=#{xpath_string(value)}]/@for"
|
59
|
+
else
|
60
|
+
"#{lhs_for(key)}=#{xpath_string(value)}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.lhs_for(key)
|
65
|
+
case key
|
66
|
+
when :text, 'text'
|
67
|
+
'normalize-space()'
|
68
|
+
when :href
|
69
|
+
'normalize-space(@href)'
|
70
|
+
else
|
71
|
+
"@#{key.to_s.gsub("_", "-")}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.xpath_string(value)
|
76
|
+
if value.include? "'"
|
77
|
+
parts = value.split("'", -1).map { |part| "'#{part}'" }
|
78
|
+
string = parts.join(%{,"'",})
|
79
|
+
"concat(#{string})"
|
80
|
+
else
|
81
|
+
"'#{value}'"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.identifier_for_element identifier, find_by, find_by_mapping
|
86
|
+
how, what = identifier.keys.first, identifier.values.first
|
87
|
+
return how => what if find_by.include? how
|
88
|
+
return find_by_mapping[how] => what if find_by_mapping[how]
|
89
|
+
return nil => what
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.finders
|
93
|
+
[:class, :id, :index, :name, :xpath]
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.mapping
|
97
|
+
{}
|
98
|
+
end
|
99
|
+
|
100
|
+
def text
|
101
|
+
element.text
|
102
|
+
end
|
103
|
+
|
104
|
+
def exist?
|
105
|
+
element.exist?
|
106
|
+
end
|
107
|
+
|
108
|
+
def visible?
|
109
|
+
element.visible?
|
110
|
+
end
|
111
|
+
|
112
|
+
def value
|
113
|
+
element.value
|
114
|
+
end
|
115
|
+
|
116
|
+
def tag_name
|
117
|
+
element.tag_name
|
118
|
+
end
|
119
|
+
|
120
|
+
def attribute_value(attribute_name)
|
121
|
+
element.attribute_value attribute_name
|
122
|
+
end
|
123
|
+
|
124
|
+
def click
|
125
|
+
element.click
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Druid
|
2
|
+
module Elements
|
3
|
+
class OrderedList < Element
|
4
|
+
attr_accessor :li_element
|
5
|
+
|
6
|
+
def self.finders
|
7
|
+
[:class, :id, :index, :xpath]
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](idx)
|
11
|
+
if element.li(:xpath, ".//li[#{idx+1}]").exist?
|
12
|
+
element.li(:xpath, ".//li[#{idx+1}]")
|
13
|
+
else
|
14
|
+
print "the sub element of ol is not li"+"\n"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def items
|
19
|
+
element.lis.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def each
|
23
|
+
for index in 1..self.items do
|
24
|
+
yield self[index-1]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Druid
|
2
|
+
module Elements
|
3
|
+
class Table < Element
|
4
|
+
|
5
|
+
#
|
6
|
+
# Return the Druid::Elements::Table for the index provided. Index
|
7
|
+
# is zero based.
|
8
|
+
#
|
9
|
+
# @return [Druid::Elements::Table]
|
10
|
+
#
|
11
|
+
def [](idx)
|
12
|
+
table_row = element[idx]
|
13
|
+
Druid::Elements::TableRow.new(table_row)
|
14
|
+
end
|
15
|
+
#
|
16
|
+
# Returns the number of rows in the table.
|
17
|
+
#
|
18
|
+
def rows
|
19
|
+
element.rows.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def each
|
23
|
+
for index in 1..self.rows do
|
24
|
+
yield self[index-1]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Druid
|
2
|
+
module Elements
|
3
|
+
class TableRow < Element
|
4
|
+
def [](idx)
|
5
|
+
element[idx]
|
6
|
+
end
|
7
|
+
#
|
8
|
+
# Returns the number of rows in the table.
|
9
|
+
#
|
10
|
+
def columns
|
11
|
+
element.cells.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def each
|
15
|
+
for index in 1..self.columns do
|
16
|
+
yield self[index-1]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Druid
|
2
|
+
module Elements
|
3
|
+
class UnOrderedList < Element
|
4
|
+
|
5
|
+
def self.finders
|
6
|
+
[:class, :id, :index, :xpath]
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](idx)
|
10
|
+
if element.li(:xpath,".//li[#{idx+1}]").exist?
|
11
|
+
element.li(:xpath,".//li[#{idx+1}]")
|
12
|
+
else
|
13
|
+
print "the sub element of ul is not li"+"\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def items
|
18
|
+
element.lis.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def each
|
22
|
+
for index in 1..self.items do
|
23
|
+
yield self[index-1]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Druid
|
2
|
+
#
|
3
|
+
# Module to facilitate to creating of page objects in step definitions. You
|
4
|
+
# can make the methods below available to all of your step definitions by adding
|
5
|
+
# this module to World. This idea was first discussed in Alister Scott's blog
|
6
|
+
# entry http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/.
|
7
|
+
#
|
8
|
+
# @example Making the PageFactory available to your step definitions
|
9
|
+
# World Druid::PageFactory
|
10
|
+
#
|
11
|
+
# @example Visiting a page for the first time in a Scenario
|
12
|
+
# visit_page MyPageObject do |page|
|
13
|
+
# page.name = 'Tim'
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# @example using a page that has already been visited in a Scenario
|
17
|
+
# on_page MyPageObject do |page|
|
18
|
+
# page.name.should == 'Tim'
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
module PageFactory
|
22
|
+
attr_accessor :page
|
23
|
+
#
|
24
|
+
# Create and navigate to a page object. The navigation will only work if the
|
25
|
+
# 'page_url' method was call on the page object.
|
26
|
+
#
|
27
|
+
# @param [page_class] a class that has included the Druid module
|
28
|
+
# @param an optional block to be called
|
29
|
+
# @return [PageObject] the newly created page object
|
30
|
+
#
|
31
|
+
def visit_page(page_class, &block)
|
32
|
+
on_page page_class, true, &block
|
33
|
+
end
|
34
|
+
#
|
35
|
+
# Create a page object.
|
36
|
+
#
|
37
|
+
# @param [page_class] a class that has included the Druid module
|
38
|
+
# @param [Bool] should the page be visited? default is false.
|
39
|
+
# @param an optional block to be called
|
40
|
+
# @return [PageObject] the newly created page object
|
41
|
+
#
|
42
|
+
def on_page(page_class, visit=false, &block)
|
43
|
+
page = page_class.new(@driver, visit)
|
44
|
+
yield page if block_given?
|
45
|
+
page
|
46
|
+
end
|
47
|
+
# def visit_page(page_class, &block)
|
48
|
+
# page = page_class.new(@driver, true)
|
49
|
+
# yield page if block_given?
|
50
|
+
# page
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def on_page(page, &block)
|
54
|
+
# yield page if block_given?
|
55
|
+
# page
|
56
|
+
# end
|
57
|
+
end
|
58
|
+
end
|