symbiont 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/Gemfile.lock +10 -39
  2. data/HISTORY.md +6 -0
  3. data/lib/symbiont.rb +8 -4
  4. data/lib/symbiont/enclosers.rb +4 -4
  5. data/lib/symbiont/evaluators.rb +22 -29
  6. data/lib/symbiont/generators.rb +82 -317
  7. data/lib/symbiont/platform_selenium.rb +18 -0
  8. data/lib/symbiont/platform_selenium/platform_object.rb +236 -0
  9. data/lib/symbiont/platform_selenium/web_objects/button.rb +13 -0
  10. data/lib/symbiont/platform_selenium/web_objects/checkbox.rb +21 -0
  11. data/lib/symbiont/platform_selenium/web_objects/common.rb +104 -0
  12. data/lib/symbiont/platform_selenium/web_objects/link.rb +13 -0
  13. data/lib/symbiont/platform_selenium/web_objects/radio.rb +21 -0
  14. data/lib/symbiont/platform_selenium/web_objects/select_list.rb +79 -0
  15. data/lib/symbiont/platform_selenium/web_objects/table.rb +40 -0
  16. data/lib/symbiont/platform_selenium/web_objects/table_row.rb +36 -0
  17. data/lib/symbiont/platform_selenium/web_objects/text_field.rb +14 -0
  18. data/lib/symbiont/platform_watir.rb +13 -4
  19. data/lib/symbiont/platform_watir/platform_object.rb +74 -262
  20. data/lib/symbiont/platform_watir/web_objects/checkbox.rb +21 -0
  21. data/lib/symbiont/platform_watir/web_objects/common.rb +82 -0
  22. data/lib/symbiont/platform_watir/web_objects/radio.rb +21 -0
  23. data/lib/symbiont/platform_watir/web_objects/select_list.rb +67 -0
  24. data/lib/symbiont/platform_watir/web_objects/table.rb +31 -0
  25. data/lib/symbiont/platform_watir/web_objects/table_row.rb +31 -0
  26. data/lib/symbiont/platform_watir/web_objects/text_field.rb +13 -0
  27. data/lib/symbiont/platforms.rb +18 -6
  28. data/lib/symbiont/version.rb +1 -1
  29. data/lib/symbiont/web_objects/_common.rb +53 -74
  30. data/lib/symbiont/web_objects/button.rb +23 -4
  31. data/lib/symbiont/web_objects/checkbox.rb +24 -10
  32. data/lib/symbiont/web_objects/div.rb +9 -1
  33. data/lib/symbiont/web_objects/link.rb +25 -4
  34. data/lib/symbiont/web_objects/paragraph.rb +11 -0
  35. data/lib/symbiont/web_objects/radio.rb +27 -1
  36. data/lib/symbiont/web_objects/select_list.rb +20 -56
  37. data/lib/symbiont/web_objects/span.rb +9 -1
  38. data/lib/symbiont/web_objects/table.rb +19 -22
  39. data/lib/symbiont/web_objects/table_cell.rb +17 -1
  40. data/lib/symbiont/web_objects/table_row.rb +18 -25
  41. data/lib/symbiont/web_objects/text_field.rb +27 -11
  42. data/symbiont.gemspec +3 -8
  43. metadata +29 -122
  44. data/app/Gemfile +0 -4
  45. data/app/app.rb +0 -181
  46. data/app/config/database.rb +0 -9
  47. data/app/models/plan.rb +0 -10
  48. data/app/models/product.rb +0 -10
  49. data/app/models/study.rb +0 -11
  50. data/app/models/user.rb +0 -13
  51. data/app/public/css/style.css +0 -138
  52. data/app/views/create_plan.erb +0 -21
  53. data/app/views/create_product.erb +0 -15
  54. data/app/views/create_study.erb +0 -24
  55. data/app/views/create_user.erb +0 -60
  56. data/app/views/db_plans.erb +0 -31
  57. data/app/views/db_products.erb +0 -29
  58. data/app/views/db_studies.erb +0 -33
  59. data/app/views/db_users.erb +0 -23
  60. data/app/views/entity_list.erb +0 -10
  61. data/app/views/index.erb +0 -8
  62. data/app/views/layout.erb +0 -39
  63. data/app/views/login_page.erb +0 -17
  64. data/app/views/success_1.erb +0 -2
  65. data/app/views/success_2.erb +0 -2
  66. data/app/views/test_database.erb +0 -13
  67. data/app/views/test_events.erb +0 -51
  68. data/app/views/test_login.erb +0 -53
  69. data/app/views/test_login_error.erb +0 -22
  70. data/app/views/test_login_success.erb +0 -22
  71. data/app/views/test_page.erb +0 -184
  72. data/specs/button.feature +0 -44
  73. data/specs/checkbox.feature +0 -40
  74. data/specs/data_setter.feature +0 -29
  75. data/specs/definitions/pages.rb +0 -156
  76. data/specs/div.feature +0 -11
  77. data/specs/evaluators.feature +0 -17
  78. data/specs/events.feature +0 -30
  79. data/specs/frame.feature +0 -5
  80. data/specs/link.feature +0 -42
  81. data/specs/locators.feature +0 -17
  82. data/specs/radio.feature +0 -38
  83. data/specs/select_list.feature +0 -50
  84. data/specs/simple_test.feature +0 -13
  85. data/specs/span.feature +0 -11
  86. data/specs/support/env.rb +0 -20
  87. data/specs/support/hooks.rb +0 -11
  88. data/specs/support/test_steps/action_steps_buttons.rb +0 -70
  89. data/specs/support/test_steps/action_steps_checkboxes.rb +0 -75
  90. data/specs/support/test_steps/action_steps_data_setter.rb +0 -56
  91. data/specs/support/test_steps/action_steps_divs.rb +0 -18
  92. data/specs/support/test_steps/action_steps_evaluators.rb +0 -15
  93. data/specs/support/test_steps/action_steps_events.rb +0 -77
  94. data/specs/support/test_steps/action_steps_frames.rb +0 -13
  95. data/specs/support/test_steps/action_steps_links.rb +0 -61
  96. data/specs/support/test_steps/action_steps_locators.rb +0 -44
  97. data/specs/support/test_steps/action_steps_navigate.rb +0 -25
  98. data/specs/support/test_steps/action_steps_radios.rb +0 -75
  99. data/specs/support/test_steps/action_steps_select_lists.rb +0 -106
  100. data/specs/support/test_steps/action_steps_spans.rb +0 -18
  101. data/specs/support/test_steps/action_steps_tables.rb +0 -82
  102. data/specs/support/test_steps/action_steps_text_fields.rb +0 -107
  103. data/specs/support/test_steps/action_steps_webobjects.rb +0 -31
  104. data/specs/support/test_steps/simple_test_steps.rb +0 -8
  105. data/specs/table.feature +0 -39
  106. data/specs/text_field.feature +0 -47
  107. data/specs/web_object.feature +0 -15
@@ -0,0 +1,18 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+
5
+ def self.create_platform_object_for(browser)
6
+ require_relative 'platform_selenium/platform_object'
7
+ SeleniumWebDriver::PlatformObject.new(browser)
8
+ end
9
+
10
+ def self.works_with(browser)
11
+ browser.is_a?(::Selenium::WebDriver::Driver)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ Symbiont::Platforms.register(:selenium_webdriver, Symbiont::Platforms::SeleniumWebDriver)
@@ -0,0 +1,236 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+
5
+ class PlatformObject
6
+ def initialize(browser)
7
+ @browser = browser
8
+ end
9
+
10
+ ## Browser-Level Actions ##
11
+
12
+ def visit(url)
13
+ @browser.navigate.to(url)
14
+ end
15
+
16
+ def url
17
+ @browser.current_url
18
+ end
19
+
20
+ def screenshot(file)
21
+ @browser.save_screenshot(file)
22
+ end
23
+
24
+ def run_script(script)
25
+ @browser.execute_script(script)
26
+ end
27
+
28
+ def back
29
+ @browser.navigate.back
30
+ end
31
+
32
+ ## Page-Level Actions ##
33
+
34
+ def text
35
+ @browser.find_element(:tag_name, 'body').text
36
+ end
37
+
38
+ def markup
39
+ @browser.page_source
40
+ end
41
+
42
+ def title
43
+ @browser.title
44
+ end
45
+
46
+ def focus
47
+ web_object = @browser.execute_script("return document.activeElement")
48
+ type = web_object.attribute(:type).to_s.downcase if web_object.tag_name.to_sym == :input
49
+ object_class = ::Symbiont::WebObjects.get_class_for(web_object.tag_name, type)
50
+ object_class.new(web_object, :platform => :selenium_webdriver)
51
+ end
52
+
53
+ ## Encloser Methods ##
54
+
55
+ # Platform method to wait for an action to complete in a given time.
56
+ # @see Symbiont::Enclosers#wait_for
57
+ def wait_for(timeout, message="wait condition not found", &block)
58
+ wait = ::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => message})
59
+ wait.until &block
60
+ end
61
+
62
+ ## Generator Methods ##
63
+
64
+ ## Paragraphs **
65
+
66
+ def paragraph_element(locator)
67
+ reference_web_object(locator, WebObjects::Paragraph, 'p')
68
+ end
69
+
70
+ def paragraph_text_for(locator)
71
+ access_web_object(locator, WebObjects::Paragraph, 'p') do |how, what|
72
+ @browser.find_element(how, what).text
73
+ end
74
+ end
75
+
76
+ ## Links ##
77
+
78
+ def link_element(locator)
79
+ reference_web_object(locator, WebObjects::Link, 'a')
80
+ end
81
+
82
+ def click_link_for(locator)
83
+ access_web_object(locator, WebObjects::Link, 'a') do |how, what|
84
+ @browser.find_element(how, what).click
85
+ end
86
+ end
87
+
88
+ ## Buttons ##
89
+
90
+ def button_element(locator)
91
+ reference_web_object(locator, WebObjects::Button, 'input', :type => 'submit')
92
+ end
93
+
94
+ def click_button_for(locator)
95
+ access_web_object(locator, WebObjects::Button, 'input', :type => 'submit') do |how, what|
96
+ @browser.find_element(how, what).click
97
+ end
98
+ end
99
+
100
+ ## Text Fields ##
101
+
102
+ def text_field_element(locator)
103
+ reference_web_object(locator, WebObjects::TextField, 'input', :type => 'text')
104
+ end
105
+
106
+ def get_text_field_value_for(locator)
107
+ access_web_object(locator, WebObjects::TextField, 'input', :type => 'text') do |how, what|
108
+ @browser.find_element(how, what).attribute('value')
109
+ end
110
+ end
111
+
112
+ def set_text_field_value_for(locator, value)
113
+ access_web_object(locator, WebObjects::TextField, 'input', :type => 'text') do |how, what|
114
+ @browser.find_element(how, what).clear
115
+ @browser.find_element(how, what).send_keys(value)
116
+ end
117
+ end
118
+
119
+ ## Checkboxes ##
120
+
121
+ def checkbox_element(locator)
122
+ reference_web_object(locator, WebObjects::CheckBox, 'input', :type => 'checkbox')
123
+ end
124
+
125
+ def check_checkbox_for_checked(locator)
126
+ access_web_object(locator, WebObjects::CheckBox, 'input', :type => 'checkbox') do |how, what|
127
+ @browser.find_element(how, what).selected?
128
+ end
129
+ end
130
+
131
+ def check_checkbox_for(locator)
132
+ access_web_object(locator, WebObjects::CheckBox, 'input', :type => 'checkbox') do |how, what|
133
+ @browser.find_element(how, what).click unless @browser.find_element(how, what).selected?
134
+ end
135
+ end
136
+
137
+ def uncheck_checkbox_for(locator)
138
+ access_web_object(locator, WebObjects::CheckBox, 'input', :type => 'checkbox') do |how, what|
139
+ @browser.find_element(how, what).click if @browser.find_element(how, what).selected?
140
+ end
141
+ end
142
+
143
+ ## Select Lists ##
144
+
145
+ def select_list_element(locator)
146
+ reference_web_object(locator, WebObjects::SelectList, 'select')
147
+ end
148
+
149
+ def get_select_list_item_for(locator)
150
+ access_web_object(locator, WebObjects::SelectList, 'select') do |how, what|
151
+ selected = nil
152
+ @browser.find_element(how, what).find_elements(:tag_name => 'option').each do |o|
153
+ if selected.nil?
154
+ selected = o.text if o.selected?
155
+ end
156
+ end
157
+ selected
158
+ end
159
+ end
160
+
161
+ def get_select_list_value_for(locator)
162
+ access_web_object(locator, WebObjects::SelectList, 'select') do |how, what|
163
+ @browser.find_element(how, what).attribute('value')
164
+ end
165
+ end
166
+
167
+ def set_select_list_value_for(locator, value)
168
+ access_web_object(locator, WebObjects::SelectList, 'select') do |how, what|
169
+ select_list = @browser.find_element(how, what)
170
+ select_list.find_elements(:tag_name => 'option').find do |option|
171
+ option.text == value
172
+ end.click
173
+ end
174
+ end
175
+
176
+ ## Radios ##
177
+
178
+ def radio_element(locator)
179
+ reference_web_object(locator, WebObjects::Radio, 'input', :type => 'radio')
180
+ end
181
+
182
+ def check_radio_for_selected(locator)
183
+ access_web_object(locator, WebObjects::Radio, 'input', :type => 'radio') do |how, what|
184
+ @browser.find_element(how, what).selected?
185
+ end
186
+ end
187
+
188
+ def select_radio_for(locator)
189
+ access_web_object(locator, WebObjects::Radio, 'input', :type => 'radio') do |how, what|
190
+ @browser.find_element(how, what).click unless @browser.find_element(how, what).selected?
191
+ end
192
+ end
193
+
194
+ def div_element(locator)
195
+ reference_web_object(locator, WebObjects::Div, 'div')
196
+ end
197
+
198
+ def span_element(locator)
199
+ reference_web_object(locator, WebObjects::Span, 'span')
200
+ end
201
+
202
+ private
203
+
204
+ def reference_web_object(locator, object_type, object_tag, type=nil)
205
+ enclosers = locator.delete(:frame)
206
+ enter_encloser_context_for(enclosers)
207
+ how, what = object_type.provide_selenium_locator_for(locator)
208
+ web_object = @browser.find_element(how, what)
209
+ object_type.new(web_object, :platform => :selenium_webdriver)
210
+ end
211
+
212
+ def access_web_object(locator, object_type, object_tag, type=nil)
213
+ enclosers = locator.delete(:frame)
214
+ enter_encloser_context_for(enclosers)
215
+ how, what = object_type.provide_selenium_locator_for(locator)
216
+ value = yield how, what
217
+ @browser.switch_to.default_content unless enclosers.nil?
218
+ value
219
+ end
220
+
221
+ def enter_encloser_context_for(enclosers)
222
+ unless enclosers.nil?
223
+ enclosers.each do |encloser|
224
+ value = encloser.values.first
225
+ @browser.switch_to.frame(value)
226
+ end
227
+ end
228
+ end
229
+ end # class: PlatformObject
230
+
231
+ end # module: SeleniumWebDriver
232
+ end # module: Platforms
233
+ end # module: Symbiont
234
+
235
+ require 'symbiont/web_objects'
236
+ Dir["#{File.dirname(__FILE__)}/../web_objects/**/*.rb"].sort.each { |file| require file }
@@ -0,0 +1,13 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module Button
5
+
6
+ def text
7
+ raise "Currently Selenium is not very good at grabbing text from a button."
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module CheckBox
5
+
6
+ def check
7
+ web_object.click unless web_object.selected?
8
+ end
9
+
10
+ def uncheck
11
+ web_object.click if web_object.selected?
12
+ end
13
+
14
+ def checked?
15
+ web_object.selected?
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,104 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module WebObject
5
+
6
+ def visible?
7
+ web_object.displayed?
8
+ end
9
+
10
+ def exists?
11
+ not web_object.nil?
12
+ end
13
+
14
+ def id
15
+ web_object.attribute(:id)
16
+ end
17
+
18
+ def value
19
+ web_object.attribute('value')
20
+ end
21
+
22
+ def tag
23
+ web_object.tag_name
24
+ end
25
+
26
+ def flash
27
+ original_color = attribute('backgroundColor')
28
+ bridge = driver_bridge
29
+ 10.times do |n|
30
+ color = (n % 2 == 0) ? 'red' : original_color
31
+ bridge.executeScript("arguments[0].style.backgroundColor = '#{color}'", web_object)
32
+ end
33
+ end
34
+
35
+ def attribute(name)
36
+ web_object.attribute(name)
37
+ end
38
+
39
+ def focus
40
+ driver_bridge.executeScript("return arguments[0].focus()", web_object)
41
+ end
42
+
43
+ def wait_until(timeout=::Symbiont.element_level_wait, message=nil, &block)
44
+ wait = Object::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => message})
45
+ wait.until &block
46
+ end
47
+
48
+ def when_actionable(timeout=::Symbiont.element_level_wait)
49
+ wait = Object::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => "Object not present in #{timeout} seconds"})
50
+ wait.until do
51
+ self.exists?
52
+ end
53
+ self
54
+ end
55
+
56
+ alias_method :when_present, :when_actionable
57
+
58
+ def when_not_actionable(timeout=::Symbiont.element_level_wait)
59
+ wait = Object::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => "Object still present in #{timeout} seconds"})
60
+ wait.until do
61
+ not_present = false
62
+ begin
63
+ not_present = false if web_object and web_object.displayed?
64
+ rescue Selenium::WebDriver::Error::ObsoleteElementError
65
+ not_present = true
66
+ end
67
+ not_present
68
+ end
69
+ end
70
+
71
+ alias_method :when_not_present, :when_not_actionable
72
+
73
+ def when_visible(timeout=::Symbiont.element_level_wait)
74
+ wait = Object::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => "Object not visible in #{timeout} seconds"})
75
+ wait.until do
76
+ self.visible?
77
+ end
78
+ self
79
+ end
80
+
81
+ def when_not_visible(timeout=::Symbiont.element_level_wait)
82
+ wait = Object::Selenium::WebDriver::Wait.new({:timeout => timeout, :message => "Object still visible in #{timeout} seconds"})
83
+ wait.until do
84
+ not self.visible?
85
+ end
86
+ self
87
+ end
88
+
89
+ alias_method :must_be_visible, :when_visible
90
+ alias_method :must_not_be_visible, :when_not_visible
91
+
92
+ def scroll_into_view(wait=2)
93
+ sleep wait
94
+ web_object.location_once_scrolled_into_view
95
+ end
96
+
97
+ def driver_bridge
98
+ bridge = web_object.instance_variable_get(:@bridge)
99
+ end
100
+
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,13 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module Link
5
+
6
+ def value
7
+ raise "Currently Selenium is not very good at grabbing the value from a link."
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module Radio
5
+
6
+ def select
7
+ web_object.click unless selected?
8
+ end
9
+
10
+ def clear
11
+ web_object.click if selected?
12
+ end
13
+
14
+ def selected?
15
+ web_object.selected?
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,79 @@
1
+ module Symbiont
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ module SelectList
5
+
6
+ # This method is used to return an Option object based on the index provided.
7
+ # @return [Symbiont::WebObjects::Option]
8
+ def [](idx)
9
+ options[idx]
10
+ #::Symbiont::WebObjects::Option.new(options[idx], :platform => :watir_webdriver)
11
+ end
12
+
13
+ # Selects an option from the select list.
14
+ def select(value)
15
+ find_options.find do |option|
16
+ option.text == value
17
+ end.click
18
+ end
19
+
20
+ # Selects the option whose value attribute matches the provided string.
21
+ def select_value(value)
22
+ options = find_options.find_all do |option|
23
+ option.attribute('value') == value
24
+ end
25
+ options.each {|opt| opt.click}
26
+ end
27
+
28
+ # This method returns an array of Option objects that are contained within
29
+ # a select list object.
30
+ # @return [array of Symbiont::WebObjects::Option]
31
+ def options
32
+ find_options.map { |e| ::Symbiont::WebObjects::Option.new(e, :platform => :selenium_webdriver) }
33
+ end
34
+
35
+ # This method returns an array of strings that contain the text of the
36
+ # currently selected options in a select list.
37
+ # @return [Array<String>]
38
+ def selected_options
39
+ find_options.map { |e| e.text if e.selected? }.compact
40
+ end
41
+
42
+ # This method returns an array of strings that contain the values of the
43
+ # currently selected options in a select list.
44
+ # @return [Array<String>]
45
+ def selected_values
46
+ find_options.map { |e| e.attribute('value') if e.selected? }.compact
47
+ end
48
+
49
+ # This method returns true if any of the text or the lable of any option
50
+ # that is selected matches the provided value.
51
+ # @param [String, Regexp] value A value to check for
52
+ # @return [Boolean]
53
+ def selected?(value)
54
+ selected = find_options.select { |e| e if e.selected? }
55
+ selected.any? { |e| e.text == value }
56
+ end
57
+
58
+ # This method checks to see if the select list has one or more options
59
+ # where the text or the label matches the provided value.
60
+ # @param [String, Regexp] value A value to check for.
61
+ # @return [Boolean]
62
+ def include?(value)
63
+ find_options.any? { |e| e.text == value }
64
+ end
65
+
66
+ def clear
67
+ find_options.select { |e| e.selected? }.each { |o| o.click }
68
+ end
69
+
70
+ private
71
+
72
+ def find_options
73
+ web_object.find_elements(:xpath, option_xpath)
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end