safariwatir 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/safariwatir.rb +6 -5
- data/safariwatir/scripter.rb +79 -56
- data/safariwatir_script.rb +21 -22
- metadata +13 -5
data/safariwatir.rb
CHANGED
@@ -269,10 +269,6 @@ module Watir
|
|
269
269
|
|
270
270
|
attr_reader :how, :what, :row
|
271
271
|
|
272
|
-
def operate_by_index(&block)
|
273
|
-
@scripter.operate_by_table_cell_index(self, &block)
|
274
|
-
end
|
275
|
-
|
276
272
|
def operate(&block)
|
277
273
|
@scripter.operate_by_table_cell(self, &block)
|
278
274
|
end
|
@@ -294,7 +290,12 @@ module Watir
|
|
294
290
|
|
295
291
|
def verify_contains(expected)
|
296
292
|
actual = getContents
|
297
|
-
expected
|
293
|
+
case expected
|
294
|
+
when Regexp
|
295
|
+
actual.match(expected) != nil
|
296
|
+
else
|
297
|
+
expected == actual
|
298
|
+
end
|
298
299
|
end
|
299
300
|
end
|
300
301
|
|
data/safariwatir/scripter.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/core_ext'
|
2
2
|
require File.dirname(__FILE__) + '/../watir/exceptions'
|
3
|
+
require 'appscript'
|
3
4
|
|
4
5
|
module Watir
|
5
6
|
ELEMENT_NOT_FOUND = "__safari_watir_element_unfound__"
|
@@ -9,20 +10,21 @@ module Watir
|
|
9
10
|
|
10
11
|
class JavaScripter
|
11
12
|
def operate(locator, operation)
|
12
|
-
|
13
|
-
#{locator}
|
13
|
+
%|#{locator}
|
14
14
|
if (element) {
|
15
15
|
#{operation}
|
16
16
|
} else {
|
17
17
|
return '#{ELEMENT_NOT_FOUND}';
|
18
|
-
}|
|
18
|
+
}|
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def wrap(script)
|
22
|
+
# Needed because createEvent must be called on a document, and the JavaScripter sub-classes
|
23
|
+
# do some transformations to lower-case "document" before we get here at runtime.
|
22
24
|
script.gsub! "DOCUMENT", "document"
|
23
|
-
|
25
|
+
script
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
def find_cell(cell)
|
27
29
|
return %|getElementById('#{cell.what}')| if cell.how == :id
|
28
30
|
raise RuntimeError, "Unable to use #{cell.how} to find TableCell" unless cell.row
|
@@ -80,23 +82,28 @@ if (element) {
|
|
80
82
|
|
81
83
|
def initialize(scripter = JavaScripter.new)
|
82
84
|
@js = scripter
|
85
|
+
@app = AS.app("Safari")
|
86
|
+
@document = @app.documents[1]
|
83
87
|
end
|
84
88
|
|
85
89
|
def ensure_window_ready
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
if length of document_list is 0 then
|
90
|
-
make new document
|
91
|
-
end if|)
|
90
|
+
@app.activate
|
91
|
+
@app.make(:new => :document) if @app.documents.get.size == 0
|
92
|
+
@document = @app.documents[1]
|
92
93
|
end
|
93
94
|
|
94
95
|
def close
|
95
|
-
|
96
|
+
@app.quit
|
96
97
|
end
|
97
98
|
|
98
99
|
def navigate_to(url)
|
99
|
-
|
100
|
+
page_load do
|
101
|
+
@document.URL.set(url)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def current_location
|
106
|
+
eval_js("window.location.href")
|
100
107
|
end
|
101
108
|
|
102
109
|
def get_text_for(element = @element)
|
@@ -104,12 +111,11 @@ end if|)
|
|
104
111
|
end
|
105
112
|
|
106
113
|
def operate_by_table_cell(element = @element)
|
107
|
-
|
108
|
-
var element = document;
|
114
|
+
%|var element = document;
|
109
115
|
if (element == undefined) {
|
110
116
|
return '#{TABLE_CELL_NOT_FOUND}';
|
111
117
|
}
|
112
|
-
#{yield}|
|
118
|
+
#{yield}|
|
113
119
|
end
|
114
120
|
|
115
121
|
def get_value_for(element = @element)
|
@@ -117,7 +123,7 @@ if (element == undefined) {
|
|
117
123
|
end
|
118
124
|
|
119
125
|
def document_text
|
120
|
-
execute(
|
126
|
+
execute(%|document.getElementsByTagName('BODY').item(0).innerText;|)
|
121
127
|
end
|
122
128
|
|
123
129
|
def highlight(element, &block)
|
@@ -177,22 +183,23 @@ element.setSelectionRange(element.value.length, element.value.length);|
|
|
177
183
|
end, element)
|
178
184
|
end
|
179
185
|
|
180
|
-
# TODO need a better approach for "waiting"
|
181
186
|
def click_element(element = @element)
|
182
|
-
|
187
|
+
page_load do
|
188
|
+
execute(element.operate { %|
|
183
189
|
if (element.click) {
|
184
190
|
element.click();
|
185
191
|
} else {
|
186
|
-
var event =
|
192
|
+
var event = DOCUMENT.createEvent('MouseEvents');
|
187
193
|
event.initEvent('click', true, true);
|
188
194
|
element.dispatchEvent(event);
|
189
195
|
|
190
196
|
if (element.onclick) {
|
191
|
-
var event =
|
197
|
+
var event = DOCUMENT.createEvent('HTMLEvents');
|
192
198
|
event.initEvent('click', true, true);
|
193
199
|
element.onclick(event);
|
194
200
|
}
|
195
201
|
}| })
|
202
|
+
end
|
196
203
|
end
|
197
204
|
|
198
205
|
def click_link(element = @element)
|
@@ -230,7 +237,9 @@ if (element.onclick) {
|
|
230
237
|
} else {
|
231
238
|
nextLocation(element);
|
232
239
|
}/
|
233
|
-
|
240
|
+
page_load do
|
241
|
+
execute(js.operate(find_link(element), click))
|
242
|
+
end
|
234
243
|
end
|
235
244
|
|
236
245
|
def operate_on_link(element)
|
@@ -271,11 +280,9 @@ for (var i = 0; i < document.links.length; i++) {
|
|
271
280
|
var elements = document.getElementsByTagName('INPUT');
|
272
281
|
var element = undefined;
|
273
282
|
for (var i = 0; i < elements.length; i++) {
|
274
|
-
if (elements[i].
|
275
|
-
|
276
|
-
|
277
|
-
break;
|
278
|
-
}
|
283
|
+
if (elements[i].value == '#{element.what}') {
|
284
|
+
element = elements[i];
|
285
|
+
break;
|
279
286
|
}
|
280
287
|
}|, yield)
|
281
288
|
end
|
@@ -323,7 +330,9 @@ for (var i = 0; i < elements.length; i++) {
|
|
323
330
|
end
|
324
331
|
|
325
332
|
def submit_form(element)
|
326
|
-
|
333
|
+
page_load do
|
334
|
+
execute(element.operate { %|element.submit();| })
|
335
|
+
end
|
327
336
|
end
|
328
337
|
|
329
338
|
def click_alert_ok
|
@@ -341,10 +350,10 @@ end tell|)
|
|
341
350
|
|
342
351
|
def for_frame(element)
|
343
352
|
# verify the frame exists
|
344
|
-
execute(
|
345
|
-
if (parent.#{element.name} == undefined) {
|
353
|
+
execute(
|
354
|
+
%|if (parent.#{element.name} == undefined) {
|
346
355
|
return '#{FRAME_NOT_FOUND}';
|
347
|
-
}
|
356
|
+
}|, element)
|
348
357
|
AppleScripter.new(FrameJavaScripter.new(element))
|
349
358
|
end
|
350
359
|
|
@@ -379,18 +388,8 @@ SCRIPT`
|
|
379
388
|
|
380
389
|
private
|
381
390
|
|
382
|
-
def execute!(script)
|
383
|
-
`osascript <<SCRIPT
|
384
|
-
tell application "Safari"
|
385
|
-
set response to "#{NO_RESPONSE}"
|
386
|
-
#{script}
|
387
|
-
response
|
388
|
-
end tell
|
389
|
-
SCRIPT`.chomp
|
390
|
-
end
|
391
|
-
|
392
391
|
def execute(script, element = nil)
|
393
|
-
response =
|
392
|
+
response = eval_js(script)
|
394
393
|
case response
|
395
394
|
when NO_RESPONSE:
|
396
395
|
nil
|
@@ -406,7 +405,7 @@ SCRIPT`.chomp
|
|
406
405
|
end
|
407
406
|
|
408
407
|
def execute_and_ignore(script)
|
409
|
-
|
408
|
+
eval_js(script)
|
410
409
|
nil
|
411
410
|
end
|
412
411
|
|
@@ -419,19 +418,43 @@ end tell
|
|
419
418
|
SCRIPT`
|
420
419
|
nil
|
421
420
|
end
|
421
|
+
|
422
|
+
def page_load
|
423
|
+
last_location = current_location
|
424
|
+
yield
|
425
|
+
sleep 1
|
426
|
+
return if last_location == current_location
|
427
|
+
|
428
|
+
tries = 0
|
429
|
+
TIMEOUT.times do |tries|
|
430
|
+
if "complete" == eval_js("DOCUMENT.readyState")
|
431
|
+
handle_client_redirect
|
432
|
+
break
|
433
|
+
else
|
434
|
+
sleep 1
|
435
|
+
end
|
436
|
+
end
|
437
|
+
raise "Unable to load page withing #{TIMEOUT} seconds" if tries == TIMEOUT-1
|
438
|
+
end
|
422
439
|
|
423
|
-
def
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
440
|
+
def handle_client_redirect
|
441
|
+
no_redirect_flag = "proceed"
|
442
|
+
redirect = eval_js(
|
443
|
+
%|var elements = DOCUMENT.getElementsByTagName('META');
|
444
|
+
for (var i = 0; i < elements.length; i++) {
|
445
|
+
if ("refresh" == elements[i].httpEquiv && elements[i].content != undefined && elements[i].content.indexOf(";") != "-1") {
|
446
|
+
return elements[i].content;
|
447
|
+
}
|
448
|
+
}
|
449
|
+
return "#{no_redirect_flag}"|)
|
450
|
+
if redirect != no_redirect_flag
|
451
|
+
time_til_redirect = redirect.split(";").first.to_i
|
452
|
+
sleep time_til_redirect
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
def eval_js(script)
|
457
|
+
@app.do_JavaScript(js.wrap(script), :in => @document)
|
435
458
|
end
|
436
459
|
end # class AppleScripter
|
437
460
|
end
|
data/safariwatir_script.rb
CHANGED
@@ -2,16 +2,13 @@ require 'rubygems'
|
|
2
2
|
require 'safariwatir'
|
3
3
|
|
4
4
|
# TODO
|
5
|
-
# Need to give feedback when browser dies
|
6
5
|
# Be more attached to the Safari window. Currently, if a different window is selected, the AppleScript executes against it.
|
7
6
|
# Verify onclick is working for buttons and links
|
8
7
|
# TextFields should not respond to button method, etc.
|
9
8
|
|
10
9
|
# Unsupported Elements: Test that P/Div/Span/TD handle link, button, etc., Javascript confirm [OK/CANCEL], Javascript prompt, Javascript popup windows
|
11
|
-
|
12
|
-
#
|
13
|
-
# Angrez is looking into the Ruby/AppleScript binding
|
14
|
-
# Watir Rails Plugin needed -> Watir test generator, fixtures and AR in-test, Browser Factory
|
10
|
+
|
11
|
+
# Need to find a better way to distinguish between a submit button and a checkbox, re: page_load
|
15
12
|
|
16
13
|
# SAFARI ISSUES
|
17
14
|
# Labels are not clickable
|
@@ -28,8 +25,8 @@ def safari.google_to_prag
|
|
28
25
|
link(:url, "http://www.pragmaticprogrammer.com/titles/ruby/code/index.html").click
|
29
26
|
link(:text, "Catalog").click
|
30
27
|
# site was down
|
31
|
-
|
32
|
-
goto("http://pragmaticprogrammer.com/bookshelf/") # workaround
|
28
|
+
link(:text, "All Books").click
|
29
|
+
# goto("http://pragmaticprogrammer.com/bookshelf/") # workaround
|
33
30
|
link(:text, /Agile Retrospectives/).click
|
34
31
|
puts "FAILURE prag" unless contains_text("Dave Hoover")
|
35
32
|
end
|
@@ -44,9 +41,9 @@ end
|
|
44
41
|
|
45
42
|
def safari.amazon
|
46
43
|
goto("http://amazon.com")
|
47
|
-
select_list(:name, "url").select("
|
48
|
-
select_list(:name, "url").select_value("
|
49
|
-
text_field(:name, "keywords").set("Orion")
|
44
|
+
select_list(:name, "url").select("VHS")
|
45
|
+
select_list(:name, "url").select_value("search-alias=software")
|
46
|
+
text_field(:name, "field-keywords").set("Orion")
|
50
47
|
image(:name, "Go").click
|
51
48
|
puts "FAILURE amazon" unless contains_text("Master of Orion")
|
52
49
|
end
|
@@ -75,7 +72,7 @@ def safari.colbert
|
|
75
72
|
goto("http://www.colbertnation.com/cn/contact.php")
|
76
73
|
text_field(:name, "formmessage").set("Beware the Bear")
|
77
74
|
button(:value, "Send Email").click
|
78
|
-
puts "FAILURE colbert" unless text_field(:name, "formmessage").verify_contains(
|
75
|
+
puts "FAILURE colbert" unless text_field(:name, "formmessage").verify_contains(/Enter message/)
|
79
76
|
end
|
80
77
|
|
81
78
|
def safari.redsquirrel
|
@@ -122,14 +119,16 @@ def safari.tables
|
|
122
119
|
puts "FAILURE dreamweaver" unless table(:id, "titletable")[1][1].text =~ /CSS/
|
123
120
|
end
|
124
121
|
|
125
|
-
|
126
|
-
safari.
|
127
|
-
safari.
|
128
|
-
safari.
|
129
|
-
safari.
|
130
|
-
safari.
|
131
|
-
safari.
|
132
|
-
safari.
|
133
|
-
safari.
|
134
|
-
|
135
|
-
|
122
|
+
begin
|
123
|
+
safari.google_to_prag
|
124
|
+
safari.ala
|
125
|
+
safari.amazon
|
126
|
+
safari.google_advanced
|
127
|
+
safari.reddit
|
128
|
+
safari.colbert
|
129
|
+
safari.redsquirrel
|
130
|
+
safari.weinberg
|
131
|
+
safari.tables
|
132
|
+
ensure
|
133
|
+
safari.close
|
134
|
+
end
|
metadata
CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: safariwatir
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2006-11-22 00:00:00 -06:00
|
8
8
|
summary: Automated testing tool for web applications.
|
9
9
|
require_paths:
|
10
10
|
- .
|
11
11
|
email: dave.hoover@gmail.com
|
12
12
|
homepage: http://safariwatir.rubyforge.org/
|
13
13
|
rubyforge_project: safariwatir
|
14
|
-
description: WATIR stands for "Web Application Testing in Ruby". See WATIR project for more information. This is
|
14
|
+
description: 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.
|
15
15
|
autorequire: safariwatir
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
@@ -46,5 +46,13 @@ extensions: []
|
|
46
46
|
requirements:
|
47
47
|
- Mac OS X running Safari
|
48
48
|
- Some features require you to turn on "Enable access for assistive devices" in System Preferences > Universal Access
|
49
|
-
dependencies:
|
50
|
-
|
49
|
+
dependencies:
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rb-appscript
|
52
|
+
version_requirement:
|
53
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.0.0
|
58
|
+
version:
|