redsquirrel-safariwatir 0.3.5

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.
@@ -0,0 +1,547 @@
1
+ require 'watir/exceptions'
2
+ require 'safariwatir/scripter'
3
+ require 'safariwatir/core_ext'
4
+
5
+ module Watir
6
+ include Watir::Exception
7
+
8
+ module PageContainer
9
+ def html
10
+ @scripter.document_html
11
+ end
12
+
13
+ def text
14
+ @scripter.document_text
15
+ end
16
+
17
+ def title
18
+ @scripter.document_title
19
+ end
20
+ end
21
+
22
+ module Container
23
+ attr_reader :scripter
24
+ private :scripter
25
+
26
+ DEFAULT_TYPING_LAG = 0.08
27
+
28
+ def set_fast_speed
29
+ @scripter.typing_lag = 0
30
+ end
31
+
32
+ def set_slow_speed
33
+ @scripter.typing_lag = DEFAULT_TYPING_LAG
34
+ end
35
+
36
+ def speed=(how_fast)
37
+ case how_fast
38
+ when :fast : set_fast_speed
39
+ when :slow : set_slow_speed
40
+ else
41
+ raise ArgumentError, "Invalid speed: #{how_fast}"
42
+ end
43
+ end
44
+
45
+ module Clickable
46
+ def click
47
+ @scripter.highlight(self) do
48
+ click_element
49
+ end
50
+ end
51
+ end
52
+
53
+ class AlertWindow
54
+ def_init :scripter
55
+
56
+ def click
57
+ @scripter.click_alert
58
+ end
59
+ end
60
+
61
+ class SecurityWarningWindow
62
+ def initialize(scripter, url)
63
+ @scripter = scripter
64
+ @url = url
65
+ end
66
+
67
+ def continue
68
+ handle_click("Continue")
69
+ end
70
+
71
+ def cancel
72
+ handle_click("Cancel")
73
+ end
74
+
75
+ private
76
+ def handle_click(button)
77
+ if @url
78
+ @scripter.navigate_to(@url) do
79
+ @scripter.click_security_warning(button)
80
+ end
81
+ else
82
+ @scripter.click_security_warning(button)
83
+ end
84
+ end
85
+ end
86
+
87
+ class Frame
88
+ include Container
89
+ include PageContainer
90
+
91
+ attr_reader :name
92
+
93
+ def initialize(scripter, name)
94
+ @name = name
95
+ @scripter = scripter.for_frame(self)
96
+ end
97
+ end
98
+
99
+ class HtmlElement
100
+ def_init :scripter, :how, :what
101
+ attr_reader :how, :what
102
+
103
+ # overridden in derivitives
104
+ def tag
105
+ raise RuntimeError, "tag not provided for #{name}"
106
+ end
107
+
108
+ # overridden in derivitives
109
+ def speak
110
+ @scripter.speak("#{name}'s don't know how to speak.")
111
+ end
112
+
113
+ def exists?
114
+ @scripter.element_exists?(self)
115
+ end
116
+ alias :exist? :exists?
117
+
118
+ def name
119
+ self.class.name.split("::").last
120
+ end
121
+
122
+ def operate(&block)
123
+ scripter_suffix = OPERATIONS[how]
124
+ if scripter_suffix.kind_of? Hash
125
+ scripter_suffix = scripter_suffix[name]
126
+ end
127
+ if scripter_suffix.nil?
128
+ raise "SafariWatir does not currently support finding by #{how}"
129
+ end
130
+ @scripter.send("operate_#{scripter_suffix}", self, &block)
131
+ end
132
+
133
+ OPERATIONS = {
134
+ :id => "by_id",
135
+ :index => "by_index",
136
+ :class => "by_class",
137
+ :name => "by_name",
138
+ :text => { "Link" => "on_link", "Label" => "by_text" },
139
+ :url => "on_link",
140
+ :value => "by_input_value",
141
+ :caption => "by_input_value",
142
+ :src => "by_src",
143
+ }
144
+ end
145
+
146
+ class Form < HtmlElement
147
+ def_init :scripter, :how, :what
148
+
149
+ def submit
150
+ @scripter.submit_form(self)
151
+ end
152
+
153
+ def tag; "FORM"; end
154
+ end
155
+
156
+ class InputElement < HtmlElement
157
+ include Clickable
158
+
159
+ def speak
160
+ @scripter.speak_value_of(self)
161
+ end
162
+
163
+ def tag; "INPUT"; end
164
+
165
+ # Hook for derivitives
166
+ def by_value; end
167
+ end
168
+
169
+ class ContentElement < HtmlElement
170
+ include Clickable
171
+ include Container
172
+
173
+ def html
174
+ @scripter.get_html_for(self)
175
+ end
176
+
177
+ def text
178
+ @scripter.get_text_for(self)
179
+ end
180
+
181
+ def speak
182
+ @scripter.speak_text_of(self)
183
+ end
184
+ end
185
+
186
+ class Image < HtmlElement
187
+ include Clickable
188
+
189
+ def tag; "IMG"; end
190
+ end
191
+
192
+ class Button < InputElement
193
+ end
194
+
195
+ class Checkbox < InputElement
196
+ def_init :scripter, :how, :what, :value
197
+
198
+ def by_value
199
+ @value
200
+ end
201
+
202
+ # Contributed by Kyle Campos
203
+ def checked?
204
+ @scripter.checkbox_is_checked?(self)
205
+ end
206
+
207
+ def set(check_it = true)
208
+ return if check_it && checked?
209
+ return if !check_it && !checked?
210
+ click
211
+ end
212
+ end
213
+
214
+ class Div < ContentElement
215
+ def tag; "DIV"; end
216
+ end
217
+
218
+ class Label < ContentElement
219
+ def tag; "LABEL"; end
220
+ end
221
+
222
+ class Link < ContentElement
223
+ def click
224
+ @scripter.highlight(self) do
225
+ click_link
226
+ end
227
+ end
228
+
229
+ def tag; "A"; end
230
+ end
231
+
232
+ class Radio < Checkbox
233
+ end
234
+
235
+ class SelectList < InputElement
236
+ def select(label)
237
+ option(:text, label).select
238
+ end
239
+
240
+ def select_value(value)
241
+ option(:value, value).select
242
+ end
243
+
244
+ def option(how, what)
245
+ Option.new(@scripter, self, how, what)
246
+ end
247
+
248
+ def selected_values
249
+ values = []
250
+ index = 1
251
+ loop do
252
+ option = option(:index, index)
253
+ break unless option.exists?
254
+ values << option if option.selected?
255
+ index += 1
256
+ end
257
+ values.map {|o| o.text } #TODO?
258
+ end
259
+
260
+ def selected_value
261
+ selected_values.first
262
+ end
263
+
264
+ def speak
265
+ @scripter.speak_options_for(self)
266
+ end
267
+
268
+ def tag; "SELECT"; end
269
+ end
270
+
271
+ class Option < InputElement
272
+ def_init :scripter, :select_list, :how, :what
273
+
274
+ def select
275
+ @scripter.highlight(self) do
276
+ select_option
277
+ end
278
+ end
279
+
280
+ def operate(&block)
281
+ @select_list.operate(&block)
282
+ end
283
+
284
+ def exists?
285
+ @scripter.option_exists?(self)
286
+ end
287
+ alias :exist? :exists?
288
+
289
+ def selected?
290
+ @scripter.option_selected?(self)
291
+ end
292
+
293
+ def text
294
+ @scripter.get_text_for(self)
295
+ end
296
+
297
+ def tag; "OPTION"; end
298
+ end
299
+
300
+ class Span < ContentElement
301
+ def tag; "SPAN"; end
302
+ end
303
+
304
+ class Table
305
+ def_init :scripter, :how, :what
306
+ attr_reader :how, :what
307
+
308
+ def each
309
+ # TODO
310
+ end
311
+
312
+ def [](index)
313
+ TableRow.new(@scripter, :index, index, self)
314
+ end
315
+
316
+ def row_count
317
+ # TODO
318
+ end
319
+
320
+ def column_count
321
+ # TODO
322
+ end
323
+
324
+ def tag; "TABLE"; end
325
+ end
326
+
327
+ class TableRow
328
+ def initialize(scripter, how, what, table = nil)
329
+ @scripter = scripter
330
+ @how = how
331
+ @what = what
332
+ @table = table
333
+ end
334
+
335
+ attr_reader :table, :how, :what
336
+
337
+ def each
338
+ # TODO
339
+ end
340
+
341
+ def [](index)
342
+ TableCell.new(@scripter, :index, index, self)
343
+ end
344
+
345
+ def column_count
346
+ # TODO
347
+ end
348
+
349
+ def tag; "TR"; end
350
+ end
351
+
352
+ class TableCell < ContentElement
353
+ def initialize(scripter, how, what, row = nil)
354
+ @scripter = scripter.for_table(self)
355
+ set_slow_speed # TODO: Need to inherit this somehow
356
+
357
+ @how = how
358
+ @what = what
359
+ @row = row
360
+ end
361
+
362
+ attr_reader :how, :what, :row
363
+
364
+ def operate(&block)
365
+ @scripter.operate_by_table_cell(self, &block)
366
+ end
367
+
368
+ def tag; "TD"; end
369
+ end
370
+
371
+ class TextField < InputElement
372
+ def set(value)
373
+ value = value.to_s
374
+ @scripter.focus(self)
375
+ @scripter.highlight(self) do
376
+ clear_text_input
377
+ value.length.times do |i|
378
+ append_text_input(value[i, 1])
379
+ end
380
+ end
381
+ @scripter.blur(self)
382
+ end
383
+
384
+ def getContents
385
+ @scripter.get_value_for(self)
386
+ end
387
+
388
+ def verify_contains(expected)
389
+ actual = getContents
390
+ case expected
391
+ when Regexp
392
+ actual.match(expected) != nil
393
+ else
394
+ expected == actual
395
+ end
396
+ end
397
+ end
398
+
399
+ class Password < TextField
400
+ end
401
+
402
+
403
+ # Elements
404
+
405
+ def button(how, what)
406
+ Button.new(scripter, how, what)
407
+ end
408
+
409
+ def cell(how, what)
410
+ TableCell.new(scripter, how, what)
411
+ end
412
+
413
+ def checkbox(how, what, value = nil)
414
+ Checkbox.new(scripter, how, what, value)
415
+ end
416
+
417
+ def div(how, what)
418
+ Div.new(scripter, how, what)
419
+ end
420
+
421
+ def form(how, what)
422
+ Form.new(scripter, how, what)
423
+ end
424
+
425
+ def frame(name)
426
+ Frame.new(scripter, name)
427
+ end
428
+
429
+ def image(how, what)
430
+ Image.new(scripter, how, what)
431
+ end
432
+
433
+ def label(how, what)
434
+ Label.new(scripter, how, what)
435
+ end
436
+
437
+ def link(how, what)
438
+ Link.new(scripter, how, what)
439
+ end
440
+
441
+ def password(how, what)
442
+ Password.new(scripter, how, what)
443
+ end
444
+
445
+ def radio(how, what, value = nil)
446
+ Radio.new(scripter, how, what, value)
447
+ end
448
+
449
+ def row(how, what)
450
+ TableRow.new(scripter, how, what)
451
+ end
452
+
453
+ def select_list(how, what)
454
+ SelectList.new(scripter, how, what)
455
+ end
456
+
457
+ def span(how, what)
458
+ Span.new(scripter, how, what)
459
+ end
460
+
461
+ def table(how, what)
462
+ Table.new(scripter, how, what)
463
+ end
464
+
465
+ def text_field(how, what)
466
+ TextField.new(scripter, how, what)
467
+ end
468
+
469
+ def contains_text(what)
470
+ case what
471
+ when Regexp:
472
+ text =~ what
473
+ when String:
474
+ text.index(what)
475
+ else
476
+ raise MissingWayOfFindingObjectException
477
+ end
478
+ end
479
+ end
480
+
481
+ class Safari
482
+ include Container
483
+ include PageContainer
484
+
485
+ def self.start(url = nil)
486
+ safari = new
487
+ safari.goto(url) if url
488
+ safari
489
+ end
490
+
491
+ def initialize
492
+ @scripter = AppleScripter.new(JavaScripter.new)
493
+ @scripter.ensure_window_ready
494
+ set_slow_speed
495
+ end
496
+
497
+ # URL of page
498
+ def url
499
+ scripter.url
500
+ end
501
+
502
+ # Hide's Safari
503
+ def hide
504
+ scripter.hide
505
+ end
506
+
507
+ def close
508
+ scripter.close
509
+ end
510
+
511
+ def quit
512
+ scripter.quit
513
+ end
514
+
515
+ def alert
516
+ AlertWindow.new(scripter)
517
+ end
518
+
519
+ def security_warning
520
+ SecurityWarningWindow.new(scripter)
521
+ end
522
+
523
+ def security_warning_at(url)
524
+ SecurityWarningWindow.new(scripter, url)
525
+ end
526
+
527
+ def goto(url)
528
+ scripter.navigate_to(url)
529
+ end
530
+
531
+ # Reloads the page
532
+ def reload
533
+ scripter.reload
534
+ end
535
+ alias :refresh :reload
536
+ end # class Safari
537
+
538
+
539
+ class WebKit < Safari
540
+ def initialize
541
+ @scripter = AppleScripter.new(JavaScripter.new, :appname => "WebKit")
542
+ @scripter.ensure_window_ready
543
+ set_slow_speed
544
+ end
545
+ end # class WebKit
546
+
547
+ end
@@ -0,0 +1,42 @@
1
+ module Watir
2
+ module Exception
3
+
4
+ # Root class for all Watir Exceptions
5
+ class WatirException < RuntimeError
6
+ def initialize(message="")
7
+ super(message)
8
+ end
9
+ end
10
+
11
+ # This exception is thrown if an attempt is made to access an object that doesn't exist
12
+ class UnknownObjectException < WatirException; end
13
+ # This exception is thrown if an attempt is made to access an object that is in a disabled state
14
+ class ObjectDisabledException < WatirException; end
15
+ # This exception is thrown if an attempt is made to access a frame that cannot be found
16
+ class UnknownFrameException< WatirException; end
17
+ # This exception is thrown if an attempt is made to access a form that cannot be found
18
+ class UnknownFormException< WatirException; end
19
+ # This exception is thrown if an attempt is made to access an object that is in a read only state
20
+ class ObjectReadOnlyException < WatirException; end
21
+ # This exception is thrown if an attempt is made to access an object when the specified value cannot be found
22
+ class NoValueFoundException < WatirException; end
23
+ # This exception gets raised if part of finding an object is missing
24
+ class MissingWayOfFindingObjectException < WatirException; end
25
+ # this exception is raised if an attempt is made to access a table cell that doesnt exist
26
+ class UnknownCellException < WatirException; end
27
+ # This exception is thrown if the window cannot be found
28
+ class NoMatchingWindowFoundException < WatirException; end
29
+ # This exception is thrown if an attemp is made to acces the status bar of the browser when it doesnt exist
30
+ class NoStatusBarException < WatirException; end
31
+ # This exception is thrown if an http error, such as a 404, 500 etc is encountered while navigating
32
+ class NavigationException < WatirException; end
33
+ # This exception is raised if a timeout is exceeded
34
+ class TimeOutException < WatirException
35
+ def initialize(duration, timeout)
36
+ @duration, @timeout = duration, timeout
37
+ end
38
+ attr_reader :duration, :timeout
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{safariwatir}
5
+ s.version = "0.3.5"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Dave Hoover"]
9
+ s.date = %q{2009-02-18}
10
+ s.description = %q{WATIR stands for "Web Application Testing in Ruby". See WATIR project for more information. This is a Safari-version of the original IE-only WATIR.}
11
+ s.email = %q{dave@obtiva.com}
12
+ s.extra_rdoc_files = ["lib/safariwatir/core_ext.rb", "lib/safariwatir/scripter.rb", "lib/safariwatir.rb", "lib/watir/exceptions.rb", "README.rdoc"]
13
+ s.files = ["lib/safariwatir/core_ext.rb", "lib/safariwatir/scripter.rb", "lib/safariwatir.rb", "lib/watir/exceptions.rb", "Manifest", "Rakefile", "README.rdoc", "safariwatir.gemspec", "safariwatir_example.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://safariwatir.rubyforge.org/}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Safariwatir", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{safariwatir}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Automated testing tool for web applications.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<rb-appscript>, [">= 0"])
28
+ else
29
+ s.add_dependency(%q<rb-appscript>, [">= 0"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<rb-appscript>, [">= 0"])
33
+ end
34
+ end