symbiont 0.1.9 → 0.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.
Files changed (92) hide show
  1. data/Gemfile.lock +22 -7
  2. data/HISTORY.md +6 -0
  3. data/app/public/css/site.css +16 -0
  4. data/app/public/js/site.js +3 -1
  5. data/app/views/comics.erb +23 -1
  6. data/app/views/webobject.erb +1 -1
  7. data/lib/symbiont/data_setter.rb +7 -3
  8. data/lib/symbiont/enclosers.rb +24 -27
  9. data/lib/symbiont/evaluators.rb +52 -23
  10. data/lib/symbiont/factory.rb +19 -75
  11. data/lib/symbiont/generators.rb +172 -44
  12. data/lib/symbiont/platform_watir/platform_object.rb +202 -18
  13. data/lib/symbiont/version.rb +1 -1
  14. data/lib/symbiont/web_objects/button.rb +1 -1
  15. data/lib/symbiont/web_objects/checkbox.rb +1 -1
  16. data/lib/symbiont/web_objects/heading.rb +12 -0
  17. data/lib/symbiont/web_objects/hidden_field.rb +19 -0
  18. data/lib/symbiont/web_objects/label.rb +15 -0
  19. data/lib/symbiont/web_objects/list_item.rb +13 -0
  20. data/lib/symbiont/web_objects/ordered_list.rb +49 -0
  21. data/lib/symbiont/web_objects/radio.rb +1 -1
  22. data/lib/symbiont/web_objects/select_list.rb +1 -1
  23. data/lib/symbiont/web_objects/table.rb +4 -0
  24. data/lib/symbiont/web_objects/table_row.rb +4 -0
  25. data/lib/symbiont/web_objects/text_area.rb +26 -0
  26. data/lib/symbiont/web_objects/unordered_list.rb +49 -0
  27. data/lib/symbiont.rb +7 -0
  28. data/lucid.yml +6 -0
  29. data/spec/spec_helper.rb +70 -16
  30. data/spec/symbiont/data_setter_spec.rb +65 -62
  31. data/spec/symbiont/enclosers_spec.rb +76 -57
  32. data/spec/symbiont/evaluators_spec.rb +95 -75
  33. data/spec/symbiont/factory_spec.rb +174 -122
  34. data/spec/symbiont/generators/button_generators_spec.rb +34 -31
  35. data/spec/symbiont/generators/checkbox_generators_spec.rb +79 -75
  36. data/spec/symbiont/generators/div_generators_spec.rb +56 -52
  37. data/spec/symbiont/generators/hidden_field_generators_spec.rb +65 -0
  38. data/spec/symbiont/generators/link_generators_spec.rb +30 -27
  39. data/spec/symbiont/generators/paragraph_generators_spec.rb +22 -17
  40. data/spec/symbiont/generators/radio_generators_spec.rb +76 -77
  41. data/spec/symbiont/generators/select_list_generators_spec.rb +93 -77
  42. data/spec/symbiont/generators/span_generators_spec.rb +56 -52
  43. data/spec/symbiont/generators/{cell_generators_spec.rb → table_cell_generators_spec.rb} +56 -52
  44. data/spec/symbiont/generators/table_generators_spec.rb +56 -52
  45. data/spec/symbiont/generators/text_area_generators_spec.rb +72 -0
  46. data/spec/symbiont/generators/text_field_generators_spec.rb +30 -27
  47. data/spec/symbiont/generators_spec.rb +38 -28
  48. data/spec/symbiont/locators_spec.rb +68 -68
  49. data/spec/symbiont/platform_object_spec.rb +2 -4
  50. data/spec/symbiont/symbiont_spec.rb +10 -8
  51. data/spec/symbiont/web_object_spec.rb +194 -194
  52. data/spec/symbiont/web_objects/button_spec.rb +38 -30
  53. data/spec/symbiont/web_objects/checkbox_spec.rb +27 -27
  54. data/spec/symbiont/web_objects/div_spec.rb +18 -11
  55. data/spec/symbiont/web_objects/heading_spec.rb +22 -0
  56. data/spec/symbiont/web_objects/hidden_field_spec.rb +18 -0
  57. data/spec/symbiont/web_objects/label_spec.rb +18 -0
  58. data/spec/symbiont/web_objects/link_spec.rb +33 -33
  59. data/spec/symbiont/web_objects/list_item_spec.rb +18 -0
  60. data/spec/symbiont/web_objects/option_spec.rb +9 -9
  61. data/spec/symbiont/web_objects/ordered_list_spec.rb +53 -0
  62. data/spec/symbiont/web_objects/paragraph_spec.rb +9 -2
  63. data/spec/symbiont/web_objects/radio_spec.rb +27 -27
  64. data/spec/symbiont/web_objects/select_list_spec.rb +69 -69
  65. data/spec/symbiont/web_objects/span_spec.rb +18 -11
  66. data/spec/symbiont/web_objects/table_cell_spec.rb +19 -19
  67. data/spec/symbiont/web_objects/table_row_spec.rb +58 -58
  68. data/spec/symbiont/web_objects/table_spec.rb +61 -61
  69. data/spec/symbiont/web_objects/text_area_spec.rb +18 -0
  70. data/spec/symbiont/web_objects/text_field_spec.rb +39 -39
  71. data/spec/symbiont/web_objects/unordered_list_spec.rb +51 -0
  72. data/specs/common/support/browser.rb +25 -0
  73. data/specs/common/support/env.rb +6 -0
  74. data/specs/common/support/events.rb +15 -0
  75. data/specs/enclosers.feature +9 -0
  76. data/specs/evaluators.feature +26 -0
  77. data/specs/pages/characters.rb +22 -0
  78. data/specs/pages/home.rb +9 -0
  79. data/specs/pages/stardate.rb +23 -0
  80. data/specs/pages/web_objects.rb +77 -0
  81. data/specs/select_list.feature +53 -0
  82. data/specs/steps/enclosers_steps.rb +17 -0
  83. data/specs/steps/evaluators_steps.rb +44 -0
  84. data/specs/steps/navigation_steps.rb +14 -0
  85. data/specs/steps/select_list_steps.rb +94 -0
  86. data/specs/steps/table_cell_steps.rb +31 -0
  87. data/specs/steps/table_steps.rb +87 -0
  88. data/specs/table.feature +49 -0
  89. data/specs/table_cell.feature +27 -0
  90. data/symbiont.gemspec +4 -1
  91. metadata +72 -6
  92. data/cucumber.yml +0 -6
@@ -15,7 +15,7 @@ module Symbiont
15
15
 
16
16
  def title_is(title)
17
17
  define_method('has_title?') do
18
- sleep 1
18
+ wait_for_app
19
19
  valid_title = title =~ @browser.title if title.kind_of?(Regexp)
20
20
  valid_title = title == @browser.title if title.kind_of?(String)
21
21
  raise "\n\nExpected title: '#{title}'; Actual title: '#{@browser.title}'" unless valid_title
@@ -23,59 +23,101 @@ module Symbiont
23
23
  end
24
24
  end
25
25
 
26
- def look_for(widget, timeout=5)
26
+ def look_for(widget, timeout=::Symbiont.element_level_wait)
27
27
  define_method('has_object?') do
28
28
  if self.respond_to? "#{widget}_object"
29
29
  self.send("#{widget}_object").when_actionable(timeout)
30
30
  else
31
- puts "The #{widget} object was not declared and could not be checked."
31
+ raise "\n\nThe '#{widget}' object was not declared and could not be checked."
32
32
  end
33
33
  end
34
34
  end
35
35
 
36
- def paragraph(identifier, locator)
36
+ def frame(locator, encloser=nil, &block)
37
+ encloser = [] if encloser.nil?
38
+ encloser << locator
39
+ block.call(encloser)
40
+ end
41
+
42
+ def paragraph(identifier, locator={index: 0}, &block)
37
43
  define_method(identifier) do
38
- platform.paragraph_text_for(locator.clone)
44
+ return platform.paragraph_text_for(locator.clone) unless block_given?
45
+ self.send("#{identifier}_object").text
39
46
  end
40
47
 
41
- common_definition_methods(identifier, locator, 'paragraph_element')
48
+ common_definition_methods(identifier, locator, 'paragraph_element', &block)
42
49
  end
43
50
 
44
51
  alias_method :p, :paragraph
45
52
 
46
- def link(identifier, locator)
53
+ def link(identifier, locator={index: 0}, &block)
47
54
  define_method(identifier) do
48
- platform.click_link_for(locator.clone)
55
+ return platform.click_link_for(locator.clone) unless block_given?
56
+ self.send("#{identifier}_object").click
49
57
  end
50
58
 
51
- common_definition_methods(identifier, locator, 'link_element')
59
+ common_definition_methods(identifier, locator, 'link_element', &block)
52
60
  end
53
61
 
54
62
  alias_method :a, :link
55
63
 
56
- def button(identifier, locator)
64
+ def button(identifier, locator={index: 0}, &block)
57
65
  define_method(identifier) do
58
- platform.click_button_for(locator.clone)
66
+ return platform.click_button_for(locator.clone) unless block_given?
67
+ self.send("#{name}_object").click
59
68
  end
60
69
 
61
- common_definition_methods(identifier, locator, 'button_element')
70
+ common_definition_methods(identifier, locator, 'button_element', &block)
62
71
  end
63
72
 
64
- def text_field(identifier, locator)
73
+ def text_field(identifier, locator={index: 0}, &block)
65
74
  define_method(identifier) do
66
- platform.get_text_field_value_for(locator.clone)
75
+ return platform.get_text_field_value_for(locator.clone) unless block_given?
76
+ self.send("#{identifier}_object").value
67
77
  end
68
78
 
69
79
  define_method("#{identifier}=") do |value|
70
- platform.set_text_field_value_for(locator.clone, value)
80
+ return platform.set_text_field_value_for(locator.clone, value) unless block_given?
81
+ self.send("#{identifier}_object").value = value
71
82
  end
72
83
 
73
- common_definition_methods(identifier, locator, 'text_field_element')
84
+ common_definition_methods(identifier, locator, 'text_field_element', &block)
74
85
  end
75
-
76
- def select_list(identifier, locator)
86
+
87
+ alias_method :textfield, :text_field
88
+ alias_method :text, :text_field
89
+
90
+ def text_area(identifier, locator={index: 0}, &block)
77
91
  define_method(identifier) do
78
- platform.get_select_list_item_for(locator.clone)
92
+ return platform.get_text_area_value_for(locator.clone) unless block_given?
93
+ self.send("#{identifier}_object").value
94
+ end
95
+
96
+ define_method("#{identifier}=") do |value|
97
+ return platform.set_text_area_value_for(locator.clone, value) unless block_given?
98
+ self.send("#{identifier}_object").value = value
99
+ end
100
+
101
+ common_definition_methods(identifier, locator, 'text_area_element', &block)
102
+ end
103
+
104
+ alias_method :textarea, :text_area
105
+
106
+ def hidden_field(identifier, locator={index: 0}, &block)
107
+ define_method(identifier) do
108
+ return platform.get_hidden_field_value_for(locator.clone) unless block_given?
109
+ self.send("#{identifier}_object").value
110
+ end
111
+
112
+ common_definition_methods(identifier, locator, 'hidden_field_element', &block)
113
+ end
114
+
115
+ alias_method :hidden, :hidden_field
116
+
117
+ def select_list(identifier, locator={index: 0}, &block)
118
+ define_method(identifier) do
119
+ return platform.get_select_list_item_for(locator.clone) unless block_given?
120
+ self.send("#{identifier}_object").value
79
121
  end
80
122
 
81
123
  define_method("#{identifier}_option?") do
@@ -88,105 +130,191 @@ module Symbiont
88
130
  end
89
131
 
90
132
  define_method("#{identifier}=") do |value|
91
- platform.set_select_list_value_for(locator.clone, value)
133
+ return platform.set_select_list_value_for(locator.clone, value) unless block_given?
134
+ self.send("#{identifier}_object").select(value)
92
135
  end
93
136
 
94
- common_definition_methods(identifier, locator, 'select_list_element')
137
+ common_definition_methods(identifier, locator, 'select_list_element', &block)
95
138
  end
96
139
 
97
140
  alias_method :select, :select_list
98
141
 
99
- def checkbox(identifier, locator)
142
+ def checkbox(identifier, locator={index: 0}, &block)
100
143
  define_method("check_#{identifier}") do
101
- platform.check_checkbox_for(locator.clone)
144
+ return platform.check_checkbox_for(locator.clone) unless block_given?
145
+ self.send("#{identifier}_object").check
102
146
  end
103
147
 
104
148
  define_method("uncheck_#{identifier}") do
105
- platform.uncheck_checkbox_for(locator.clone)
149
+ return platform.uncheck_checkbox_for(locator.clone) unless block_given?
150
+ self.send("#{identifier}_object").uncheck
106
151
  end
107
152
 
108
153
  define_method("#{identifier}_checked?") do
109
- platform.check_checkbox_for_checked(locator.clone)
154
+ return platform.check_checkbox_for_checked(locator.clone) unless block_given?
155
+ self.send("#{identifier}_object").checked?
110
156
  end
111
157
 
112
- common_definition_methods(identifier, locator, 'checkbox_element')
158
+ common_definition_methods(identifier, locator, 'checkbox_element', &block)
113
159
  end
114
160
 
115
- def radio(identifier, locator)
161
+ def radio(identifier, locator={index: 0}, &block)
116
162
  #alias_method "#{identifier}_radio".to_sym, "#{identifier}_object".to_sym
117
163
  #alias_method "#{identifier}_radio_button".to_sym, "#{identifier}_object".to_sym
118
164
 
119
165
  define_method("#{identifier}_selected?") do
120
- platform.check_radio_for_selected(locator.clone)
166
+ return platform.check_radio_for_selected(locator.clone) unless block_given?
167
+ self.send("#{identifier}_object").selected?
121
168
  end
122
169
 
123
170
  alias_method "#{identifier}_set?".to_sym, "#{identifier}_selected?".to_sym
124
171
 
125
172
  define_method("select_#{identifier}") do
126
- platform.select_radio_for(locator.clone)
173
+ return platform.select_radio_for(locator.clone) unless block_given?
174
+ self.send("#{identifier}_object").select
127
175
  end
128
176
 
129
177
  alias_method "set_#{identifier}".to_sym, "select_#{identifier}".to_sym
130
178
 
131
- common_definition_methods(identifier, locator, 'radio_element')
179
+ common_definition_methods(identifier, locator, 'radio_element', &block)
132
180
  end
133
181
 
134
182
  alias_method :radio_button, :radio
135
183
 
184
+ def table(identifier, locator={index: 0}, &block)
185
+ define_method(identifier) do
186
+ return platform.table_text_for(locator.clone) unless block_given?
187
+ self.send("#{identifier}_object").text
188
+ end
136
189
 
190
+ common_definition_methods(identifier, locator, 'table_element', &block)
191
+ end
192
+
193
+ def cell(identifier, locator={index: 0}, &block)
194
+ define_method(identifier) do
195
+ return platform.get_table_cell_text_for(locator.clone) unless block_given?
196
+ self.send("#{identifier}_object").text
197
+ end
137
198
 
199
+ common_definition_methods(identifier, locator, 'cell_element', &block)
200
+ end
138
201
 
202
+ alias_method :td, :cell
139
203
 
140
- def table(identifier, locator)
204
+ def div(identifier, locator={index: 0}, &block)
141
205
  define_method(identifier) do
142
- platform.table_text_for(locator.clone)
206
+ return platform.div_text_for(locator.clone) unless block_given?
207
+ self.send("#{identifier}_object").text
143
208
  end
144
209
 
145
- common_definition_methods(identifier, locator, 'table_element')
210
+ common_definition_methods(identifier, locator, 'div_element', &block)
146
211
  end
147
212
 
148
- def cell(identifier, locator)
213
+ def span(identifier, locator={index: 0}, &block)
149
214
  define_method(identifier) do
150
- platform.get_table_cell_text_for(locator.clone)
215
+ return platform.span_text_for(locator.clone) unless block_given?
216
+ self.send("#{identifier}_object").text
151
217
  end
152
218
 
153
- common_definition_methods(identifier, locator, 'cell_element')
219
+ common_definition_methods(identifier, locator, 'span_element', &block)
154
220
  end
155
221
 
156
- def div(identifier, locator)
222
+ def h1(identifier, locator={index: 0}, &block)
157
223
  define_method(identifier) do
158
- platform.div_text_for(locator.clone)
224
+ return platform.h1_text_for(locator.clone) unless block_given?
225
+ self.send("#{identifier}_object").text
159
226
  end
160
227
 
161
- common_definition_methods(identifier, locator, 'div_element')
228
+ common_definition_methods(identifier, locator, 'h1_element', &block)
162
229
  end
163
-
164
- def span(identifier, locator)
230
+
231
+ def h2(identifier, locator={index: 0}, &block)
165
232
  define_method(identifier) do
166
- platform.span_text_for(locator.clone)
233
+ return platform.h2_text_for(locator.clone) unless block_given?
234
+ self.send("#{identifier}_object").text
167
235
  end
168
236
 
169
- common_definition_methods(identifier, locator, 'span_element')
237
+ common_definition_methods(identifier, locator, 'h2_element', &block)
238
+ end
239
+
240
+ def label(identifier, locator={index: 0}, &block)
241
+ define_method(identifier) do
242
+ return platform.label_text_for(locator.clone) unless block_given?
243
+ self.send("#{identifier}_object").text
244
+ end
245
+
246
+ common_definition_methods(identifier, locator, 'label_element', &block)
247
+ end
248
+
249
+ def ordered_list(identifier, locator={:index => 0}, &block)
250
+ define_method(identifier) do
251
+ return platform.ordered_list_text_for(locator.clone) unless block_given?
252
+ self.send("#{identifier}_object").text
253
+ end
254
+
255
+ common_definition_methods(identifier, locator, 'ordered_list_element', &block)
256
+ end
257
+
258
+ alias_method :ol, :ordered_list
259
+
260
+ def unordered_list(identifier, locator={:index => 0}, &block)
261
+ define_method(identifier) do
262
+ return platform.unordered_list_text_for(locator.clone) unless block_given?
263
+ self.send("#{identifier}_object").text
264
+ end
265
+
266
+ common_definition_methods(identifier, locator, 'unordered_list_element', &block)
267
+ end
268
+
269
+ alias_method :ul, :unordered_list
270
+
271
+ def list_item(identifier, locator={:index => 0}, &block)
272
+ define_method(identifier) do
273
+ return platform.list_item_text_for(locator.clone) unless block_given?
274
+ self.send("#{identifier}_object").text
275
+ end
276
+
277
+ common_definition_methods(identifier, locator, 'list_item_element', &block)
278
+ end
279
+
280
+ alias_method :li, :list_item
281
+
282
+ ## Multiple Element Handling ##
283
+
284
+ [:unordered_lists, :ordered_lists, :list_items].each do |method|
285
+ define_method(method) do |identifier, *locator, &block|
286
+ define_method("#{identifier}_elements") do
287
+ return process_block(&block) unless block.nil?
288
+ platform_method = "#{method.to_s}_elements"
289
+ puts "*********** #{platform_method}"
290
+ platform.send(platform_method, locator.first.clone)
291
+ end
292
+ end
170
293
  end
171
294
 
172
- def common_definition_methods(identifier, locator, method)
295
+ def common_definition_methods(identifier, locator, method, &block)
173
296
  define_method("#{identifier}_object") do
297
+ return process_block(&block) if block_given?
174
298
  platform.send(method, locator.clone)
175
299
  end
176
300
 
177
301
  define_method("#{identifier}_exists?") do
302
+ return process_block(&block).exists? if block_given?
178
303
  platform.send(method, locator.clone).exists?
179
304
  end
180
305
 
181
306
  define_method("#{identifier}_visible?") do
307
+ return process_block(&block).visible? if block_given?
182
308
  platform.send(method, locator.clone).visible?
183
309
  end
184
310
 
185
311
  define_method("#{identifier}_enabled?") do
312
+ return process_block(&block).enabled? if block_given?
186
313
  platform.send(method, locator.clone).enabled?
187
314
  end
188
315
 
189
316
  define_method("#{identifier}_text") do
317
+ return process_block(&block).text if block_given?
190
318
  platform.send(method, locator.clone).text
191
319
  end
192
320
 
@@ -29,6 +29,18 @@ module Symbiont
29
29
  def back
30
30
  @browser.back
31
31
  end
32
+
33
+ def forward
34
+ @browser.forward
35
+ end
36
+
37
+ def refresh
38
+ @browser.refresh
39
+ end
40
+
41
+ def remove_cookies
42
+ @browser.cookies.clear
43
+ end
32
44
 
33
45
  ## Page-Level Actions ##
34
46
 
@@ -67,30 +79,61 @@ module Symbiont
67
79
  @browser.window(identifier).use(&block)
68
80
  end
69
81
 
82
+ def within_frame(locator, encloser=nil, &block)
83
+ encloser = [] if encloser.nil?
84
+ encloser << locator
85
+ block.call(encloser)
86
+ end
87
+
70
88
  # Platform method to handle an alert message box.
71
89
  # @see Symbiont::Enclosers#will_alert
72
- def will_alert(&block)
73
- @browser.wd.execute_script("window.alert = function(msg) { window.__lastWatirAlert=msg; }")
90
+ def will_alert(encloser=nil, &block)
91
+ switch_to_frame(encloser)
92
+
74
93
  yield
75
- value = @browser.wd.execute_script("return window.__lastWatirAlert")
94
+ value = nil
95
+ if @browser.alert.exists?
96
+ value = @browser.alert.text
97
+ @browser.alert.ok
98
+ end
99
+
100
+ ###
101
+ ##@browser.wd.execute_script("window.alert = function(msg) { window.__lastWatirAlert=msg; }")
102
+ ##yield
103
+ ##value = @browser.wd.execute_script("return window.__lastWatirAlert")
104
+
105
+ switch_to_default_content(encloser)
76
106
  value
77
107
  end
78
108
 
79
109
  # Platform method to handle a confirmation message box
80
110
  # @see Symbiont::Enclosers#will_confirm
81
- def will_confirm(response, &block)
82
- @browser.wd.execute_script("window.confirm = function(msg) { window.__lastWatirConfirm=msg; return #{!!response} }")
111
+ def will_confirm(response, encloser=nil, &block)
112
+ switch_to_frame(encloser)
113
+
83
114
  yield
84
- value = @browser.wd.execute_script("return window.__lastWatirConfirm")
115
+ value = nil
116
+ if @browser.alert.exists?
117
+ value = @browser.alert.text
118
+ response ? @browser.alert.ok : @browser.alert.close
119
+ end
120
+
121
+ ##@browser.wd.execute_script("window.confirm = function(msg) { window.__lastWatirConfirm=msg; return #{!!response} }")
122
+ ##yield
123
+ ##value = @browser.wd.execute_script("return window.__lastWatirConfirm")
124
+
125
+ switch_to_default_content(encloser)
85
126
  value
86
127
  end
87
128
 
88
129
  # Platform method to handle a prompt message box.
89
130
  # @see Symbiont::Enclosers#will_prompt
90
- def will_prompt(response, &block)
131
+ def will_prompt(response, encloser=nil, &block)
132
+ switch_to_frame(encloser)
91
133
  @browser.wd.execute_script("window.prompt = function(text, value) { window.__lastWatirPrompt = { message: text, default_value: value }; return #{!!response}; }")
92
134
  yield
93
135
  result = @browser.wd.execute_script("return window.__lastWatirPrompt")
136
+ switch_to_default_content(encloser)
94
137
  result && result.dup.each_key { |k| result[k.to_sym] = result.delete(k) }
95
138
  result
96
139
  end
@@ -107,6 +150,16 @@ module Symbiont
107
150
  access_web_object("p(locator).text", WebObjects::Paragraph, locator, nil, 'p')
108
151
  end
109
152
 
153
+ ## Labels ##
154
+
155
+ def label_element(locator)
156
+ reference_web_object("label(locator)", WebObjects::Label, locator, 'label')
157
+ end
158
+
159
+ def label_text_for(locator)
160
+ access_web_object("label(locator).text", WebObjects::Label, locator, nil, 'label')
161
+ end
162
+
110
163
  ## Links ##
111
164
 
112
165
  def link_element(locator)
@@ -141,6 +194,30 @@ module Symbiont
141
194
  access_web_object("text_field(locator).set(value)", WebObjects::TextField, locator, value)
142
195
  end
143
196
 
197
+ ## Text Areas ##
198
+
199
+ def text_area_element(locator)
200
+ reference_web_object("text_area(locator)", WebObjects::TextArea, locator)
201
+ end
202
+
203
+ def get_text_area_value_for(locator)
204
+ access_web_object("text_area(locator).value", WebObjects::TextArea, locator)
205
+ end
206
+
207
+ def set_text_area_value_for(locator, value)
208
+ access_web_object("text_area(locator).set(value)", WebObjects::TextArea, locator, value)
209
+ end
210
+
211
+ ## Hidden Fields ##
212
+
213
+ def hidden_field_element(locator)
214
+ reference_web_object("hidden(locator)", WebObjects::HiddenField, locator)
215
+ end
216
+
217
+ def get_hidden_field_value_for(locator)
218
+ access_web_object("hidden(locator).value", WebObjects::HiddenField, locator)
219
+ end
220
+
144
221
  ## Checkboxes ##
145
222
 
146
223
  def checkbox_element(locator)
@@ -167,6 +244,7 @@ module Symbiont
167
244
 
168
245
  def get_select_list_item_for(locator)
169
246
  access_web_object("select_list(locator).selected_options[0].text", WebObjects::SelectList, locator)
247
+ # Should I consider: select_list(identifier).options.find {|o| o.selected?}.text
170
248
  end
171
249
 
172
250
  def get_select_list_value_for(locator)
@@ -191,6 +269,8 @@ module Symbiont
191
269
  access_web_object("radio(locator).set", WebObjects::Radio, locator)
192
270
  end
193
271
 
272
+ ## Table Elements ##
273
+
194
274
  def table_element(locator)
195
275
  reference_web_object("table(locator)", WebObjects::Table, locator, 'table')
196
276
  end
@@ -199,7 +279,6 @@ module Symbiont
199
279
  access_web_object("table(locator).text", WebObjects::Table, locator, nil, 'table')
200
280
  end
201
281
 
202
-
203
282
  def cell_element(locator)
204
283
  reference_web_object("td(locator)", WebObjects::TableCell, locator, 'td')
205
284
  end
@@ -208,6 +287,8 @@ module Symbiont
208
287
  access_web_object("td(locator).text", WebObjects::TableCell, locator, nil, 'td')
209
288
  end
210
289
 
290
+ ## Sectional Elements ##
291
+
211
292
  def div_element(locator)
212
293
  reference_web_object("div(locator)", WebObjects::Div, locator, 'div')
213
294
  end
@@ -224,7 +305,63 @@ module Symbiont
224
305
  access_web_object("span(locator).text", WebObjects::Span, locator, nil, 'span')
225
306
  end
226
307
 
227
- private
308
+ ## Header Elements ##
309
+
310
+ def h1_element(locator)
311
+ reference_web_object("h1(locator)", WebObjects::Heading, locator, 'h1')
312
+ end
313
+
314
+ def h1_text_for(locator)
315
+ access_web_object("h1(locator).text", WebObjects::Heading, locator, nil, 'h1')
316
+ end
317
+
318
+ def h2_element(locator)
319
+ reference_web_object("h2(locator)", WebObjects::Heading, locator, 'h2')
320
+ end
321
+
322
+ def h2_text_for(locator)
323
+ access_web_object("h2(locator).text", WebObjects::Heading, locator, nil, 'h2')
324
+ end
325
+
326
+ ## List Elements ##
327
+
328
+ def ordered_list_element(locator)
329
+ reference_web_object("ol(locator)", WebObjects::OrderedList, locator, 'ol')
330
+ end
331
+
332
+ def ordered_list_text_for(locator)
333
+ access_web_object("ol(locator).text", WebObjects::OrderedList, locator, nil, 'ol')
334
+ end
335
+
336
+ def ordered_lists_elements(locator)
337
+ reference_web_object("ols(locator)", WebObjects::OrderedList, locator, 'ol')
338
+ end
339
+
340
+ def unordered_list_element(locator)
341
+ reference_web_object("ul(locator)", WebObjects::UnorderedList, locator, 'ul')
342
+ end
343
+
344
+ def unordered_list_text_for(locator)
345
+ access_web_object("ul(locator).text", WebObjects::UnorderedList, locator, nil, 'ul')
346
+ end
347
+
348
+ def unordered_lists_elements(locator)
349
+ reference_web_object("uls(locator)", WebObjects::UnorderedList, locator, 'ul')
350
+ end
351
+
352
+ def list_item_element(locator)
353
+ reference_web_object("li(locator)", WebObjects::ListItem, locator, 'li')
354
+ end
355
+
356
+ def list_item_text_for(locator)
357
+ access_web_object("li(locator).text", WebObjects::ListItem, locator, nil, 'li')
358
+ end
359
+
360
+ def list_items_elements(locator)
361
+ reference_web_object("lis(locator)", WebObjects::ListItem, locator, 'li')
362
+ end
363
+
364
+ private
228
365
 
229
366
  # This method is called by any platform methods that require getting
230
367
  # an object reference.
@@ -234,10 +371,11 @@ module Symbiont
234
371
  # @param [Hash] locator the specific web object selector, mainly for parsing
235
372
  # @return [Object] the web object identified by the action
236
373
  def reference_web_object(action, object_type, locator, object_tag=nil)
237
- enclosers = locator.delete(:frame)
238
- locator = object_type.provide_locator_for(locator)
374
+ #puts "[ref_obj] Locator (1): #{locator}"
375
+ locator, enclosers = qualify_locators(locator, object_type, object_tag)
376
+ #puts "[ref_obj] Locator (2): #{locator}"
239
377
  web_object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}"
240
- @browser.wd.switch_to.default_content unless enclosers.nil?
378
+ switch_to_default_content(enclosers)
241
379
  object_type.new(web_object)
242
380
  end
243
381
 
@@ -247,17 +385,50 @@ module Symbiont
247
385
  #
248
386
  # @param [String] action the driver logic to be sent to the browser
249
387
  # @param [Hash] locator the specific web object selector, mainly for parsing
250
- # @param [String] value any specific information that must be sent to the
251
- # web object
388
+ # @param [String] value any specific information that must be sent to the web object
389
+ # @param [String] object_tag the tag that represents the web object in a browser
390
+ #
252
391
  # @return [Any] the information or object returned by the action
253
392
  def access_web_object(action, object_type, locator, value=nil, object_tag=nil)
393
+ #puts "[acc_obj] Locator (1): #{locator}"
394
+ locator, enclosers = qualify_locators(locator, object_type, object_tag)
395
+ #puts "[acc_obj] Locator (2): #{locator}"
396
+ web_object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}"
397
+ switch_to_default_content(enclosers)
398
+ web_object
399
+ end
400
+
401
+ # This method is used to qualify any locators with necessary information that
402
+ # is required to find the web objects during execution.
403
+ #
404
+ # @param [String] locator the locator being used
405
+ # @param [Object] object_type the object type that the locator applies to
406
+ # @param [String] object_tag the tag that represents the web object in a browser
407
+ def qualify_locators(locator, object_type, object_tag=nil)
254
408
  enclosers = locator.delete(:frame)
409
+
410
+ #puts "[qualify] Locator (1): #{locator}"
411
+ locator = use_tagname_for_name(locator, object_tag) if object_tag
412
+ #puts "[qualify] Locator (2): #{locator}"
255
413
  locator = object_type.provide_locator_for(locator)
256
- object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}"
257
- @browser.wd.switch_to.default_content unless enclosers.nil?
258
- object
414
+ #puts "[qualify] Locator (3): #{locator}"
415
+
416
+ return locator, enclosers
259
417
  end
260
-
418
+
419
+ # This method uses an object tag for the locator for a web object
420
+ # if the locator being used was :name.
421
+ #
422
+ # @param [String] locator the locator being used
423
+ # @param [String] object_tag the tag that represents the web object in a browser
424
+ def use_tagname_for_name(locator, object_tag)
425
+ #puts "[use_tagname] Locator (1): #{locator}"
426
+ return locator if locator.length < 2 and not locator[:name]
427
+ locator[:tag_name] = object_tag if locator[:name]
428
+ #puts "[use_tagname] Locator (2): #{locator}"
429
+ locator
430
+ end
431
+
261
432
  # This method is used to wrap a web object locator within the locator for an
262
433
  # enclosing web object. Currently the only enclosing objects this makes sense
263
434
  # for are iframes and frames.
@@ -272,6 +443,19 @@ module Symbiont
272
443
 
273
444
  encloser_locator = "frame(:#{key} => '#{value}')."
274
445
  end
446
+
447
+ def switch_to_default_content(locator)
448
+ @browser.wd.switch_to.default_content unless locator.nil?
449
+ end
450
+
451
+ def switch_to_frame(locator)
452
+ unless locator.nil?
453
+ locator.each do |frame|
454
+ value = frame.values.first
455
+ @browser.wd.switch_to.frame(value)
456
+ end
457
+ end
458
+ end
275
459
  end # class: PlatformObject
276
460
 
277
461
  end # module: WatirWebDriver
@@ -1,3 +1,3 @@
1
1
  module Symbiont
2
- VERSION = "0.1.9"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -8,7 +8,7 @@ module Symbiont
8
8
  end
9
9
 
10
10
  def self.usable_selectors
11
- super + [:value, :text, :src, :alt, :css]
11
+ super + [:value, :text, :src, :alt]
12
12
  end
13
13
 
14
14
  end # class: Button