symbiont 0.1.9 → 0.2.0

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