safariwatir 0.1.2 → 0.2.0
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 +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:
|