redsquirrel-safariwatir 0.3.5

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