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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +7 -0
  5. data/README.md +11 -0
  6. data/Rakefile +33 -0
  7. data/cucumber.yml +2 -0
  8. data/features/button.feature +38 -0
  9. data/features/checkbox.feature +39 -0
  10. data/features/div.feature +38 -0
  11. data/features/element.feature +114 -0
  12. data/features/form.feature +29 -0
  13. data/features/hidden_field.feature +33 -0
  14. data/features/html/images/circle.png +0 -0
  15. data/features/html/static_elements.html +89 -0
  16. data/features/html/success.html +8 -0
  17. data/features/image.feature +33 -0
  18. data/features/link.feature +39 -0
  19. data/features/list_item.feature +31 -0
  20. data/features/ordered_list.feature +35 -0
  21. data/features/page_level_actions.feature +31 -0
  22. data/features/radio_button.feature +42 -0
  23. data/features/select_list.feature +48 -0
  24. data/features/span.feature +36 -0
  25. data/features/step_definations/button_steps.rb +24 -0
  26. data/features/step_definations/checkbox_steps.rb +31 -0
  27. data/features/step_definations/div_steps.rb +19 -0
  28. data/features/step_definations/element_steps.rb +29 -0
  29. data/features/step_definations/form_steps.rb +11 -0
  30. data/features/step_definations/hidden_field_steps.rb +19 -0
  31. data/features/step_definations/image_steps.rb +19 -0
  32. data/features/step_definations/link_steps.rb +29 -0
  33. data/features/step_definations/list_item_steps.rb +12 -0
  34. data/features/step_definations/ordered_list_steps.rb +33 -0
  35. data/features/step_definations/page_level_actions_steps.rb +48 -0
  36. data/features/step_definations/page_traversal_steps.rb +4 -0
  37. data/features/step_definations/radio_button_steps.rb +23 -0
  38. data/features/step_definations/select_list_steps.rb +42 -0
  39. data/features/step_definations/span_steps.rb +15 -0
  40. data/features/step_definations/table_cell_steps.rb +19 -0
  41. data/features/step_definations/table_steps.rb +38 -0
  42. data/features/step_definations/text_area_steps.rb +19 -0
  43. data/features/step_definations/text_field_steps.rb +23 -0
  44. data/features/step_definations/unordered_list_steps.rb +11 -0
  45. data/features/support/env.rb +17 -0
  46. data/features/support/page.rb +163 -0
  47. data/features/support/url_helper.rb +16 -0
  48. data/features/table.feature +43 -0
  49. data/features/table_cell.feature +36 -0
  50. data/features/text_area.feature +32 -0
  51. data/features/text_field.feature +42 -0
  52. data/features/unordered_list.feature +36 -0
  53. data/lib/druid.rb +80 -0
  54. data/lib/druid/accessors.rb +506 -0
  55. data/lib/druid/elements.rb +19 -0
  56. data/lib/druid/elements/button.rb +11 -0
  57. data/lib/druid/elements/check_box.rb +7 -0
  58. data/lib/druid/elements/div.rb +10 -0
  59. data/lib/druid/elements/element.rb +129 -0
  60. data/lib/druid/elements/form.rb +7 -0
  61. data/lib/druid/elements/hidden_field.rb +11 -0
  62. data/lib/druid/elements/image.rb +7 -0
  63. data/lib/druid/elements/link.rb +16 -0
  64. data/lib/druid/elements/list_item.rb +7 -0
  65. data/lib/druid/elements/ordered_list.rb +30 -0
  66. data/lib/druid/elements/radio_button.rb +7 -0
  67. data/lib/druid/elements/select_list.rb +18 -0
  68. data/lib/druid/elements/span.rb +11 -0
  69. data/lib/druid/elements/table.rb +30 -0
  70. data/lib/druid/elements/table_cell.rb +7 -0
  71. data/lib/druid/elements/table_row.rb +22 -0
  72. data/lib/druid/elements/text_area.rb +11 -0
  73. data/lib/druid/elements/text_field.rb +11 -0
  74. data/lib/druid/elements/unordered_list.rb +28 -0
  75. data/lib/druid/page_factory.rb +58 -0
  76. data/spec/druid/druid_spec.rb +38 -0
  77. data/spec/spec_helper.rb +7 -0
  78. 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,11 @@
1
+ module Druid
2
+ module Elements
3
+ class Button < Element
4
+
5
+ def self.finders
6
+ super + [:text]
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Druid
2
+ module Elements
3
+ class CheckBox < Element
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ module Druid
2
+ module Elements
3
+ class Div < Element
4
+
5
+ def self.finders
6
+ [:class, :id, :index, :xpath]
7
+ end
8
+ end
9
+ end
10
+ end
@@ -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,7 @@
1
+ module Druid
2
+ module Elements
3
+ class Form < Element
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class HiddenField < Element
4
+
5
+ def self.finders
6
+ super + [:tag_name, :text, :css]
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Druid
2
+ module Elements
3
+ class Image < Element
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Druid
2
+ module Elements
3
+ class Link < Element
4
+
5
+ protected
6
+
7
+ def self.finders
8
+ super + [:href, :text]
9
+ end
10
+
11
+ def self.mapping
12
+ super.merge({:link => :text, :link_text => :text})
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Druid
2
+ module Elements
3
+ class ListItem < Element
4
+
5
+ end
6
+ end
7
+ 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,7 @@
1
+ module Druid
2
+ module Elements
3
+ class RadioButton < Element
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ module Druid
2
+ module Elements
3
+ class SelectList < Element
4
+
5
+ def self.finders
6
+ super + [:value, :text]
7
+ end
8
+
9
+ def [](idx)
10
+ element.options[idx]
11
+ end
12
+
13
+ def options
14
+ element.options
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class Span < Element
4
+
5
+ def self.finders
6
+ [:class, :id, :index, :xpath]
7
+ end
8
+
9
+ end
10
+ end
11
+ 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,7 @@
1
+ module Druid
2
+ module Elements
3
+ class TableCell < Element
4
+
5
+ end
6
+ end
7
+ 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,11 @@
1
+ module Druid
2
+ module Elements
3
+ class TextArea < Element
4
+
5
+ def self.finders
6
+ super + [:tag_name, :css]
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class TextField < Element
4
+
5
+ def self.finders
6
+ super + [:css, :tag_name, :text]
7
+ end
8
+
9
+ end
10
+ end
11
+ 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