safariwatir 0.1.1 → 0.1.2

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.
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
  - .