safariwatir 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/safariwatir.rb CHANGED
@@ -5,33 +5,67 @@ require 'safariwatir/core_ext'
5
5
  module Watir
6
6
  include Watir::Exception
7
7
 
8
- module Clickable
9
- def click
10
- @scripter.highlight(self) do
11
- click_element
12
- end
13
- end
8
+ module PageContainer
9
+ def html
10
+ @scripter.document_html
11
+ end
12
+
13
+ def text
14
+ @scripter.document_text
15
+ end
14
16
  end
15
17
 
16
- module Elements
18
+ module Container
19
+ attr_reader :scripter
20
+ private :scripter
21
+
22
+ module Clickable
23
+ def click
24
+ @scripter.highlight(self) do
25
+ click_element
26
+ end
27
+ end
28
+ end
29
+
17
30
  class AlertWindow
18
- def initialize(scripter)
19
- @scripter = scripter
20
- end
31
+ def_init :scripter
21
32
 
22
33
  def click
23
34
  @scripter.click_alert_ok
24
35
  end
25
36
  end
26
37
 
38
+ class Frame
39
+ include Container
40
+ include PageContainer
41
+
42
+ attr_reader :name
43
+
44
+ def initialize(scripter, name)
45
+ @name = name
46
+ @scripter = scripter.for_frame(self)
47
+ end
48
+ end
49
+
27
50
  class HtmlElement
28
51
  def_init :scripter, :how, :what
29
52
  attr_reader :how, :what
30
53
 
31
- # Hooks for subclasses
32
- def tag; end
33
- def speak; end
54
+ # overridden in derivitives
55
+ def tag
56
+ raise RuntimeError, "tag not provided for #{name}"
57
+ end
34
58
 
59
+ # overridden in derivitives
60
+ def speak
61
+ @scripter.speak("#{name}'s don't know how to speak.")
62
+ end
63
+
64
+ def exists?
65
+ @scripter.element_exists?(self)
66
+ end
67
+ alias :exist? :exists?
68
+
35
69
  def name
36
70
  self.class.name.split("::").last
37
71
  end
@@ -79,12 +113,15 @@ module Watir
79
113
  @scripter.speak_value_of(self)
80
114
  end
81
115
 
82
- # Hooks for subclasses
116
+ def tag; "INPUT"; end
117
+
118
+ # Hook for derivitives
83
119
  def by_value; end
84
120
  end
85
121
 
86
122
  class ContentElement < HtmlElement
87
123
  include Clickable
124
+ include Container
88
125
 
89
126
  def text
90
127
  @scripter.get_text_for(self)
@@ -107,9 +144,12 @@ module Watir
107
144
  end
108
145
 
109
146
  class Div < ContentElement
147
+ def tag; "DIV"; end
110
148
  end
111
149
 
112
150
  class Label < ContentElement
151
+ def tag; "LABEL"; end
152
+
113
153
  protected
114
154
 
115
155
  def operate_by_text(&block)
@@ -117,12 +157,14 @@ module Watir
117
157
  end
118
158
  end
119
159
 
120
- class Link < InputElement
160
+ class Link < ContentElement
121
161
  def click
122
162
  @scripter.highlight(self) do
123
163
  click_link
124
164
  end
125
165
  end
166
+
167
+ def tag; "A"; end
126
168
  end
127
169
 
128
170
  class Radio < Checkbox
@@ -130,23 +172,110 @@ module Watir
130
172
 
131
173
  class SelectList < InputElement
132
174
  def select(label)
133
- @scripter.highlight(self) do
134
- select_option(:text, label)
135
- end
175
+ option(:text, label).select
136
176
  end
137
-
177
+
138
178
  def select_value(value)
139
- @scripter.highlight(self) do
140
- select_option(:value, value)
141
- end
179
+ option(:value, value).select
180
+ end
181
+
182
+ def option(how, what)
183
+ Option.new(@scripter, self, how, what)
142
184
  end
143
185
 
144
186
  def speak
145
187
  @scripter.speak_options_for(self)
146
188
  end
189
+
190
+ def tag; "SELECT"; end
191
+ end
192
+
193
+ class Option < InputElement
194
+ def_init :scripter, :select_list, :how, :what
195
+
196
+ def select
197
+ @scripter.highlight(self) do
198
+ select_option
199
+ end
200
+ end
201
+
202
+ def operate(&block)
203
+ @select_list.operate(&block)
204
+ end
205
+
206
+ def exists?
207
+ @scripter.option_exists?(self)
208
+ end
209
+ alias :exist? :exists?
210
+
211
+ def tag; "OPTION"; end
147
212
  end
148
213
 
149
214
  class Span < ContentElement
215
+ def tag; "SPAN"; end
216
+ end
217
+
218
+ class Table
219
+ def_init :scripter, :how, :what
220
+ attr_reader :how, :what
221
+
222
+ def each
223
+ # TODO
224
+ end
225
+
226
+ def [](index)
227
+ TableRow.new(@scripter, :index, index, self)
228
+ end
229
+
230
+ def row_count
231
+ # TODO
232
+ end
233
+
234
+ def column_count
235
+ # TODO
236
+ end
237
+ end
238
+
239
+ class TableRow
240
+ def initialize(scripter, how, what, table = nil)
241
+ @scripter = scripter
242
+ @how = how
243
+ @what = what
244
+ @table = table
245
+ end
246
+
247
+ attr_reader :table, :how, :what
248
+
249
+ def each
250
+ # TODO
251
+ end
252
+
253
+ def [](index)
254
+ TableCell.new(@scripter, :index, index, self)
255
+ end
256
+
257
+ def column_count
258
+ # TODO
259
+ end
260
+ end
261
+
262
+ class TableCell < ContentElement
263
+ def initialize(scripter, how, what, row = nil)
264
+ @scripter = scripter.for_table(self)
265
+ @how = how
266
+ @what = what
267
+ @row = row
268
+ end
269
+
270
+ attr_reader :how, :what, :row
271
+
272
+ def operate_by_index(&block)
273
+ @scripter.operate_by_table_cell_index(self, &block)
274
+ end
275
+
276
+ def operate(&block)
277
+ @scripter.operate_by_table_cell(self, &block)
278
+ end
150
279
  end
151
280
 
152
281
  class TextField < InputElement
@@ -171,43 +300,18 @@ module Watir
171
300
 
172
301
  class Password < TextField
173
302
  end
174
- end
175
-
176
- class Safari
177
- include Elements
178
303
 
179
- attr_reader :scripter
180
304
 
181
- def self.start(url = nil)
182
- safari = new
183
- safari.goto(url) if url
184
- safari
185
- end
305
+ # Elements
186
306
 
187
- def initialize
188
- @scripter = AppleScripter.new
189
- end
190
-
191
- def close
192
- scripter.close
193
- end
194
-
195
- def quit
196
- scripter.quit
197
- end
198
-
199
- def alert
200
- AlertWindow.new(scripter)
201
- end
202
-
203
- def goto(url)
204
- scripter.navigate_to(url)
205
- end
206
-
207
307
  def button(how, what)
208
308
  Button.new(scripter, how, what)
209
309
  end
210
310
 
311
+ def cell(how, what)
312
+ TableCell.new(scripter, how, what)
313
+ end
314
+
211
315
  def checkbox(how, what, value = nil)
212
316
  Checkbox.new(scripter, how, what, value)
213
317
  end
@@ -220,6 +324,10 @@ module Watir
220
324
  Form.new(scripter, how, what)
221
325
  end
222
326
 
327
+ def frame(name)
328
+ Frame.new(scripter, name)
329
+ end
330
+
223
331
  def image(how, what)
224
332
  Button.new(scripter, how, what)
225
333
  end
@@ -240,6 +348,10 @@ module Watir
240
348
  Radio.new(scripter, how, what, value)
241
349
  end
242
350
 
351
+ def row(how, what)
352
+ TableRow.new(scripter, how, what)
353
+ end
354
+
243
355
  def select_list(how, what)
244
356
  SelectList.new(scripter, how, what)
245
357
  end
@@ -247,21 +359,56 @@ module Watir
247
359
  def span(how, what)
248
360
  Span.new(scripter, how, what)
249
361
  end
362
+
363
+ def table(how, what)
364
+ Table.new(scripter, how, what)
365
+ end
250
366
 
251
367
  def text_field(how, what)
252
368
  TextField.new(scripter, how, what)
253
369
  end
254
370
 
255
371
  def contains_text(what)
256
- text = scripter.document_text
257
372
  case what
258
- when Regexp:
259
- text =~ what
260
- when String:
261
- text.index(what)
262
- else
263
- raise MissingWayOfFindingObjectException
264
- end
373
+ when Regexp:
374
+ text =~ what
375
+ when String:
376
+ text.index(what)
377
+ else
378
+ raise MissingWayOfFindingObjectException
379
+ end
380
+ end
381
+ end
382
+
383
+ class Safari
384
+ include Container
385
+ include PageContainer
386
+
387
+ def self.start(url = nil)
388
+ safari = new
389
+ safari.goto(url) if url
390
+ safari
391
+ end
392
+
393
+ def initialize
394
+ @scripter = AppleScripter.new
395
+ @scripter.ensure_window_ready
396
+ end
397
+
398
+ def close
399
+ scripter.close
400
+ end
401
+
402
+ def quit
403
+ scripter.quit
404
+ end
405
+
406
+ def alert
407
+ AlertWindow.new(scripter)
408
+ end
409
+
410
+ def goto(url)
411
+ scripter.navigate_to(url)
265
412
  end
266
413
  end # class Safari
267
414
  end
@@ -1,38 +1,97 @@
1
+ require File.dirname(__FILE__) + '/core_ext'
2
+ require File.dirname(__FILE__) + '/../watir/exceptions'
3
+
1
4
  module Watir
2
- NOT_FOUND = "__safari_watir_unfound__"
5
+ ELEMENT_NOT_FOUND = "__safari_watir_element_unfound__"
6
+ FRAME_NOT_FOUND = "__safari_watir_frame_unfound__"
3
7
  NO_RESPONSE = "__safari_watir_no_response__"
8
+ TABLE_CELL_NOT_FOUND = "__safari_watir_cell_unfound__"
4
9
 
5
- module JavaScripter
6
- def js_operation(locator, operation)
7
- js_wrapper(%|
10
+ class JavaScripter
11
+ def operate(locator, operation)
12
+ wrap(%|
8
13
  #{locator}
9
14
  if (element) {
10
15
  #{operation}
11
16
  } else {
12
- return '#{NOT_FOUND}';
17
+ return '#{ELEMENT_NOT_FOUND}';
13
18
  }|)
14
19
  end
15
20
 
16
- def js_wrapper(script)
21
+ def wrap(script)
22
+ script.gsub! "DOCUMENT", "document"
17
23
  %|set response to do JavaScript "#{script}" in document 1|
18
24
  end
25
+
26
+ def find_cell(cell)
27
+ return %|getElementById('#{cell.what}')| if cell.how == :id
28
+ raise RuntimeError, "Unable to use #{cell.how} to find TableCell" unless cell.row
29
+
30
+ finder =
31
+ case cell.row.how
32
+ when :id:
33
+ %|getElementById('#{cell.row.what}')|
34
+ when :index:
35
+ case cell.row.table.how
36
+ when :id
37
+ %|getElementById('#{cell.row.table.what}').rows[#{cell.row.what-1}]|
38
+ when :index:
39
+ %|getElementsByTagName('TABLE')[#{cell.row.table.what-1}].rows[#{cell.row.what-1}]|
40
+ else
41
+ raise MissingWayOfFindingObjectException, "Table element does not support #{cell.row.table.how}"
42
+ end
43
+ else
44
+ raise MissingWayOfFindingObjectException, "TableRow element does not support #{cell.row.how}"
45
+ end
46
+
47
+ finder + %|.cells[#{cell.what-1}]|
48
+ end
49
+ end
50
+
51
+ class FrameJavaScripter < JavaScripter
52
+ def initialize(frame)
53
+ @page_container = "parent.#{frame.name}"
54
+ end
55
+
56
+ def wrap(script)
57
+ # add in frame name when referencing parent or document
58
+ script.gsub! "parent", "parent.#{@page_container}"
59
+ script.gsub! "document", "#{@page_container}.document"
60
+ super(script)
61
+ end
62
+ end
63
+
64
+ class TableJavaScripter < JavaScripter
65
+ def_init :cell
66
+
67
+ def wrap(script)
68
+ script.gsub! "document", "document." + find_cell(@cell)
69
+ super(script)
70
+ end
19
71
  end
20
72
 
21
73
  class AppleScripter
22
- include JavaScripter
23
74
  include Watir::Exception
24
75
 
76
+ attr_reader :js
77
+ private :js
78
+
25
79
  TIMEOUT = 10
26
80
 
27
- def initialize
28
- ensure_window_ready
81
+ def initialize(scripter = JavaScripter.new)
82
+ @js = scripter
29
83
  end
30
-
31
- def close
32
- execute(%|close document 1|)
84
+
85
+ def ensure_window_ready
86
+ execute(%|
87
+ activate
88
+ set document_list to every document
89
+ if length of document_list is 0 then
90
+ make new document
91
+ end if|)
33
92
  end
34
93
 
35
- def quit
94
+ def close
36
95
  execute(%|quit|)
37
96
  end
38
97
 
@@ -40,24 +99,25 @@ if (element) {
40
99
  execute_and_wait(%|set URL in document 1 to "#{url}"|)
41
100
  end
42
101
 
43
- def speak_value_of(element = @element)
44
- speak(get_value_for(element))
45
- end
46
-
47
102
  def get_text_for(element = @element)
48
103
  execute(element.operate { %|return element.innerText| }, element)
49
104
  end
50
105
 
51
- def speak_text_of(element = @element)
52
- speak(element.text)
106
+ def operate_by_table_cell(element = @element)
107
+ js.wrap(%|
108
+ var element = document;
109
+ if (element == undefined) {
110
+ return '#{TABLE_CELL_NOT_FOUND}';
111
+ }
112
+ #{yield}|)
53
113
  end
54
-
114
+
55
115
  def get_value_for(element = @element)
56
116
  execute(element.operate { %|return element.value;| }, element)
57
117
  end
58
118
 
59
119
  def document_text
60
- execute(js_wrapper(%|document.getElementsByTagName('BODY').item(0).innerText;|))
120
+ execute(js.wrap(%|document.getElementsByTagName('BODY').item(0).innerText;|))
61
121
  end
62
122
 
63
123
  def highlight(element, &block)
@@ -74,29 +134,38 @@ element.style.backgroundColor = 'yellow';|
74
134
  execute_and_ignore(element.operate { %|element.style.backgroundColor = element.originalColor;| })
75
135
  end
76
136
 
77
- def speak_options_for(element = @element)
78
- values = execute(element.operate do
79
- %|var values = '';
80
- for (var i = 0; i < element.options.length; i++) {
81
- if (element.options[i].selected == true) {
82
- values += ' ' + element.options[i].text;
83
- }
84
- }
85
- return values|
86
- end, element)
87
- speak(values)
137
+ def element_exists?(element = @element, &block)
138
+ block ||= Proc.new {}
139
+ execute(element.operate(&block), element)
140
+ return true
141
+ rescue UnknownObjectException
142
+ return false
88
143
  end
89
144
 
90
- def select_option(option_how, option_what, element = @element)
145
+ def select_option(element = @element)
91
146
  execute(element.operate do
92
- %|for (var i = 0; i < element.options.length; i++) {
93
- if (element.options[i].#{option_how} == '#{option_what}') {
94
- element.options[i].selected = true;
95
- }
96
- }|
147
+ handle_option(element, %|element.options[i].selected = true;|)
97
148
  end, element)
98
149
  end
99
150
 
151
+ def option_exists?(element = @element)
152
+ element_exists?(element) { handle_option(element) }
153
+ end
154
+
155
+ def handle_option(select_list, selection = nil)
156
+ %|var option_found = false;
157
+ for (var i = 0; i < element.options.length; i++) {
158
+ if (element.options[i].#{select_list.how} == '#{select_list.what}') {
159
+ #{selection}
160
+ option_found = true;
161
+ }
162
+ }
163
+ if (!option_found) {
164
+ return '#{ELEMENT_NOT_FOUND}';
165
+ }|
166
+ end
167
+ private :handle_option
168
+
100
169
  def clear_text_input(element = @element)
101
170
  execute(element.operate { %|element.value = '';| }, element)
102
171
  end
@@ -110,29 +179,69 @@ element.setSelectionRange(element.value.length, element.value.length);|
110
179
 
111
180
  # TODO need a better approach for "waiting"
112
181
  def click_element(element = @element)
113
- execute_and_wait(element.operate { %|element.click();| })
182
+ execute_and_wait(element.operate { %|
183
+ if (element.click) {
184
+ element.click();
185
+ } else {
186
+ var event = document.createEvent('MouseEvents');
187
+ event.initEvent('click', true, true);
188
+ element.dispatchEvent(event);
189
+
190
+ if (element.onclick) {
191
+ var event = document.createEvent('HTMLEvents');
192
+ event.initEvent('click', true, true);
193
+ element.onclick(event);
194
+ }
195
+ }| })
114
196
  end
115
197
 
116
198
  def click_link(element = @element)
117
- click = find_link(element) + %|
118
- var click = document.createEvent('HTMLEvents');
199
+ click = %/
200
+ function baseTarget() {
201
+ var bases = document.getElementsByTagName('BASE');
202
+ if (bases.length > 0) {
203
+ return bases[0].target;
204
+ } else {
205
+ return;
206
+ }
207
+ }
208
+ function undefinedTarget(target) {
209
+ return target == undefined || target == '';
210
+ }
211
+ function topTarget(target) {
212
+ return undefinedTarget(target) || target == '_top';
213
+ }
214
+ function nextLocation(element) {
215
+ var target = element.target;
216
+ if (undefinedTarget(target) && baseTarget()) {
217
+ top[baseTarget()].location = element.href;
218
+ } else if (topTarget(target)) {
219
+ top.location = element.href;
220
+ } else {
221
+ top[target].location = element.href;
222
+ }
223
+ }
224
+ var click = DOCUMENT.createEvent('HTMLEvents');
119
225
  click.initEvent('click', true, true);
120
226
  if (element.onclick) {
121
227
  if (false != element.onclick(click)) {
122
- return element.href;
228
+ nextLocation(element);
123
229
  }
124
230
  } else {
125
- return element.href;
126
- }|
127
- execute_and_wait(%|set target to do JavaScript "#{click}" in document 1
128
- set URL in document 1 to target|)
231
+ nextLocation(element);
232
+ }/
233
+ execute_and_wait(js.operate(find_link(element), click))
129
234
  end
130
235
 
131
236
  def operate_on_link(element)
132
- js_operation(find_link(element), yield)
237
+ js.operate(find_link(element), yield)
133
238
  end
134
239
 
135
240
  def find_link(element)
241
+ case element.how
242
+ when :index:
243
+ %|var element = document.getElementsByTagName('A')[#{element.what-1}];|
244
+ else
136
245
  %|var element = undefined;
137
246
  for (var i = 0; i < document.links.length; i++) {
138
247
  if (document.links[i].#{handle_match(element)}) {
@@ -140,6 +249,7 @@ for (var i = 0; i < document.links.length; i++) {
140
249
  break;
141
250
  }
142
251
  }|
252
+ end
143
253
  end
144
254
  private :find_link
145
255
 
@@ -147,15 +257,17 @@ for (var i = 0; i < document.links.length; i++) {
147
257
  how = {:text => "text", :url => "href"}[element.how]
148
258
  case element.what
149
259
  when Regexp:
150
- %|#{how}.match(/#{element.what.source}/)|
260
+ %|#{how}.match(/#{element.what.source}/#{element.what.casefold? ? "i":nil})|
151
261
  when String:
152
262
  %|#{how} == '#{element.what}'|
263
+ else
264
+ raise RuntimeError, "Unable to locate #{element.name} with #{element.how}"
153
265
  end
154
266
  end
155
267
  private :handle_match
156
268
 
157
269
  def operate_by_input_value(element)
158
- js_operation(%|
270
+ js.operate(%|
159
271
  var elements = document.getElementsByTagName('INPUT');
160
272
  var element = undefined;
161
273
  for (var i = 0; i < elements.length; i++) {
@@ -169,7 +281,7 @@ for (var i = 0; i < elements.length; i++) {
169
281
  end
170
282
 
171
283
  def operate_by_name(element)
172
- js_operation(%|
284
+ js.operate(%|
173
285
  var elements = document.getElementsByName('#{element.what}');
174
286
  var element = undefined;
175
287
  for (var i = 0; i < elements.length; i++) {
@@ -192,15 +304,15 @@ for (var i = 0; i < elements.length; i++) {
192
304
  private :handle_form_element_name_match
193
305
 
194
306
  def operate_by_id(element)
195
- js_operation("var element = document.getElementById('#{element.what}');", yield)
307
+ js.operate("var element = document.getElementById('#{element.what}');", yield)
196
308
  end
197
309
 
198
310
  def operate_by_index(element)
199
- js_operation(%|var element = document.getElementsByTagName('#{element.tag}')[#{element.what}];|, yield)
311
+ js.operate(%|var element = document.getElementsByTagName('#{element.tag}')[#{element.what-1}];|, yield)
200
312
  end
201
313
 
202
314
  def operate_on_label(element)
203
- js_operation(%|var elements = document.getElementsByTagName('LABEL');
315
+ js.operate(%|var elements = document.getElementsByTagName('LABEL');
204
316
  var element = undefined;
205
317
  for (var i = 0; i < elements.length; i++) {
206
318
  if (elements[i].innerText == '#{element.what}') {
@@ -223,10 +335,51 @@ tell window 1
223
335
  end tell|)
224
336
  end
225
337
 
338
+ def for_table(element)
339
+ AppleScripter.new(TableJavaScripter.new(element))
340
+ end
341
+
342
+ def for_frame(element)
343
+ # verify the frame exists
344
+ execute(js.wrap(%|
345
+ if (parent.#{element.name} == undefined) {
346
+ return '#{FRAME_NOT_FOUND}';
347
+ }|), element)
348
+ AppleScripter.new(FrameJavaScripter.new(element))
349
+ end
350
+
351
+ def speak_value_of(element = @element)
352
+ speak(get_value_for(element))
353
+ end
354
+
355
+ def speak_text_of(element = @element)
356
+ speak(element.text)
357
+ end
358
+
359
+ def speak_options_for(element = @element)
360
+ values = execute(element.operate do
361
+ %|var values = '';
362
+ for (var i = 0; i < element.options.length; i++) {
363
+ if (element.options[i].selected == true) {
364
+ values += ' ' + element.options[i].text;
365
+ }
366
+ }
367
+ return values|
368
+ end, element)
369
+ speak(values)
370
+ end
371
+
372
+ def speak(string)
373
+ `osascript <<SCRIPT
374
+ say "#{string.quote_safe}"
375
+ SCRIPT`
376
+ nil
377
+ end
378
+
379
+
226
380
  private
227
381
 
228
382
  def execute!(script)
229
- # puts script
230
383
  `osascript <<SCRIPT
231
384
  tell application "Safari"
232
385
  set response to "#{NO_RESPONSE}"
@@ -239,10 +392,14 @@ SCRIPT`.chomp
239
392
  def execute(script, element = nil)
240
393
  response = execute! script
241
394
  case response
242
- when NOT_FOUND:
243
- raise UnknownObjectException, "Unable to locate #{element.name} element with #{element.how} of #{element.what}."
244
395
  when NO_RESPONSE:
245
396
  nil
397
+ when ELEMENT_NOT_FOUND:
398
+ raise UnknownObjectException, "Unable to locate #{element.name} element with #{element.how} of #{element.what}"
399
+ when TABLE_CELL_NOT_FOUND:
400
+ raise UnknownCellException, "Unable to locate a table cell with #{element.how} of #{element.what}"
401
+ when FRAME_NOT_FOUND:
402
+ raise UnknownFrameException, "Unable to locate a frame with name #{element.name}"
246
403
  else
247
404
  response
248
405
  end
@@ -263,33 +420,18 @@ SCRIPT`
263
420
  nil
264
421
  end
265
422
 
266
- def execute_and_wait(script, element = nil)
423
+ def execute_and_wait(script, element = nil)
267
424
  execute(%|
268
425
  #{script}
269
426
  delay 2
270
427
  repeat with i from 1 to #{TIMEOUT}
271
- if (do JavaScript "document.readyState" in document 1) is "complete" then
428
+ #{js.wrap("document.readyState")}
429
+ if (response) is "complete" then
272
430
  exit repeat
273
431
  else
274
432
  delay 1
275
433
  end if
276
434
  end repeat|, element)
277
435
  end
278
-
279
- def ensure_window_ready
280
- execute(%|
281
- activate
282
- set document_list to every document
283
- if length of document_list is 0 then
284
- make new document
285
- end if|)
286
- end
287
-
288
- def speak(string)
289
- `osascript <<SCRIPT
290
- say "#{string.quote_safe}"
291
- SCRIPT`
292
- nil
293
- end
294
436
  end # class AppleScripter
295
437
  end
@@ -3,12 +3,12 @@ require 'safariwatir'
3
3
 
4
4
  # TODO
5
5
  # Need to give feedback when browser dies
6
- # Be more attached to the Safari window, if a different window is selected, the AppleScript executes against it
6
+ # Be more attached to the Safari window. Currently, if a different window is selected, the AppleScript executes against it.
7
7
  # Verify onclick is working for buttons and links
8
8
  # TextFields should not respond to button method, etc.
9
9
 
10
- # Unsupported Elements: UL/OL
11
- # Use dynamic properties for Javascript optimization?
10
+ # Unsupported Elements: Test that P/Div/Span/TD handle link, button, etc., Javascript confirm [OK/CANCEL], Javascript prompt, Javascript popup windows
11
+ # Use dynamic properties for Javascript optimization? Or use global lookup table?
12
12
  # Will I need to push more functionality into AppleScript to speed things up?
13
13
  # Angrez is looking into the Ruby/AppleScript binding
14
14
  # Watir Rails Plugin needed -> Watir test generator, fixtures and AR in-test, Browser Factory
@@ -24,10 +24,12 @@ def safari.google_to_prag
24
24
  goto("http://google.com")
25
25
  text_field(:name, "q").set("pickaxe")
26
26
  button(:name, "btnG").click
27
- link(:text, "The Pragmatic Programmers, LLC: Programming Ruby").click
27
+ link(:text, "Programming Ruby, 2nd Ed.").click
28
28
  link(:url, "http://www.pragmaticprogrammer.com/titles/ruby/code/index.html").click
29
29
  link(:text, "Catalog").click
30
- link(:text, "All Books").click
30
+ # site was down
31
+ # link(:text, "All Books").click
32
+ goto("http://pragmaticprogrammer.com/bookshelf/") # workaround
31
33
  link(:text, /Agile Retrospectives/).click
32
34
  puts "FAILURE prag" unless contains_text("Dave Hoover")
33
35
  end
@@ -46,7 +48,7 @@ def safari.amazon
46
48
  select_list(:name, "url").select_value("index=software")
47
49
  text_field(:name, "keywords").set("Orion")
48
50
  image(:name, "Go").click
49
- puts "FAILURE amazon" unless contains_text("Master of Orion (Original Release) (PC)")
51
+ puts "FAILURE amazon" unless contains_text("Master of Orion")
50
52
  end
51
53
 
52
54
  def safari.google_advanced
@@ -65,7 +67,7 @@ def safari.reddit
65
67
  goto("http://reddit.com/")
66
68
  text_field(:name, "user").set("foo")
67
69
  password(:name, "passwd").set("bar")
68
- form(:index, 1).submit
70
+ form(:index, 2).submit
69
71
  puts "FAILURE reddit" unless contains_text("foo") and contains_text("logout")
70
72
  end
71
73
 
@@ -92,6 +94,34 @@ def safari.redsquirrel
92
94
  end
93
95
  end
94
96
 
97
+ def safari.weinberg
98
+ goto("http://www.geraldmweinberg.com/")
99
+ puts "FAILURE weinberg menu" unless frame("menu").contains_text("Jerry Weinberg's Site")
100
+ frame("menu").link(:text, "Books").click
101
+ frame("menu").link(:text, /psychology/i).click
102
+ puts "FAILURE weinberg content" unless frame("content").contains_text("Silver Anniversary")
103
+ end
104
+
105
+ def safari.tables
106
+ goto("http://basecamphq.com/")
107
+ puts "FAILURE basecamp content" unless table(:index, 1)[1][2].text =~ /What is Basecamp\?/
108
+
109
+ goto("http://www.jimthatcher.com/webcourse9.htm")
110
+ puts "FAILURE thatcher" unless cell(:id, "c5").text == "subtotals"
111
+
112
+ goto("http://amazon.com/")
113
+ if contains_text("If you're not")
114
+ link(:text, "click here").click
115
+ end
116
+
117
+ puts "FAILURE amazon tr" unless row(:id, "twotabtop")[2].text =~ /Your\s+Amazon\.com/
118
+ row(:id, "twotabtop")[2].link(:index, 1).click
119
+ puts "FAILURE amazon link" unless contains_text("personalized recommendations")
120
+
121
+ goto("http://www.dreamweaverresources.com/tutorials/tableborder.htm")
122
+ puts "FAILURE dreamweaver" unless table(:id, "titletable")[1][1].text =~ /CSS/
123
+ end
124
+
95
125
  safari.google_to_prag
96
126
  safari.ala
97
127
  safari.amazon
@@ -99,5 +129,7 @@ safari.google_advanced
99
129
  safari.reddit
100
130
  safari.colbert
101
131
  safari.redsquirrel
132
+ safari.weinberg
133
+ safari.tables
102
134
 
103
135
  safari.close
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: safariwatir
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.1
7
- date: 2006-07-23 00:00:00 -05:00
6
+ version: 0.1.2
7
+ date: 2006-10-12 00:00:00 -05:00
8
8
  summary: Automated testing tool for web applications.
9
9
  require_paths:
10
10
  - .