druid-ts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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