operawatir 0.3-jruby → 0.3.2-jruby
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/Gemfile +6 -2
- data/LICENSE +1 -1
- data/Rakefile +7 -8
- data/VERSION +1 -1
- data/bin/desktopwatir +3 -0
- data/bin/operawatir +2 -2
- data/lib/operadriver/webdriver-opera.jar +0 -0
- data/lib/operawatir.rb +14 -8
- data/lib/operawatir/browser.rb +49 -38
- data/lib/operawatir/compat/collection.rb +6 -0
- data/lib/operawatir/compat/element.rb +5 -2
- data/lib/operawatir/compat/element_finders.rb +19 -0
- data/lib/operawatir/desktop-waiter.rb +144 -0
- data/lib/operawatir/desktop_browser.rb +506 -0
- data/lib/operawatir/desktop_common.rb +111 -0
- data/lib/operawatir/desktop_container.rb +252 -0
- data/lib/operawatir/desktop_enums.rb +42 -0
- data/lib/operawatir/desktop_exceptions.rb +16 -0
- data/lib/operawatir/element.rb +6 -6
- data/lib/operawatir/exceptions.rb +3 -0
- data/lib/operawatir/keys.rb +116 -0
- data/lib/operawatir/platform.rb +59 -0
- data/lib/operawatir/quickwidgets.rb +3 -0
- data/lib/operawatir/quickwidgets/quick_addressfield.rb +23 -0
- data/lib/operawatir/quickwidgets/quick_button.rb +151 -0
- data/lib/operawatir/quickwidgets/quick_checkbox.rb +58 -0
- data/lib/operawatir/quickwidgets/quick_dialogtab.rb +23 -0
- data/lib/operawatir/quickwidgets/quick_dropdown.rb +27 -0
- data/lib/operawatir/quickwidgets/quick_editfield.rb +115 -0
- data/lib/operawatir/quickwidgets/quick_label.rb +12 -0
- data/lib/operawatir/quickwidgets/quick_radiobutton.rb +11 -0
- data/lib/operawatir/quickwidgets/quick_searchfield.rb +25 -0
- data/lib/operawatir/quickwidgets/quick_tab.rb +66 -0
- data/lib/operawatir/quickwidgets/quick_thumbnail.rb +26 -0
- data/lib/operawatir/quickwidgets/quick_toolbar.rb +11 -0
- data/lib/operawatir/quickwidgets/quick_treeitem.rb +157 -0
- data/lib/operawatir/quickwidgets/quick_treeview.rb +27 -0
- data/lib/operawatir/quickwidgets/quick_widget.rb +369 -0
- data/lib/operawatir/quickwidgets/quick_window.rb +150 -0
- data/lib/operawatir/selector.rb +1 -1
- data/lib/operawatir/version.rb +0 -1
- data/lib/operawatir/window.rb +9 -0
- data/operawatir.gemspec +382 -0
- data/spec/new_watirspec/browser_spec.rb +279 -0
- data/spec/new_watirspec/clipboard_spec.rb +79 -0
- data/spec/new_watirspec/collection_spec.rb +387 -0
- data/spec/new_watirspec/element_spec.rb +456 -0
- data/spec/new_watirspec/guards.rb +39 -0
- data/spec/new_watirspec/keys_spec.rb +206 -0
- data/spec/new_watirspec/server.rb +91 -0
- data/spec/new_watirspec/watirspec_helper.rb +62 -0
- data/spec/new_watirspec/window_spec.rb +370 -0
- data/utils/launchers/launcher-mac +0 -0
- metadata +191 -28
- data/.gitmodules +0 -3
@@ -0,0 +1,39 @@
|
|
1
|
+
module WatirSpec
|
2
|
+
class Guard
|
3
|
+
|
4
|
+
attr_accessor :type, :browsers, :data
|
5
|
+
|
6
|
+
def initialize(type, browsers, data={})
|
7
|
+
self.type, self.browsers, self.data = type, browsers, data
|
8
|
+
WatirSpec.guards << self
|
9
|
+
end
|
10
|
+
|
11
|
+
def guarded?(browser)
|
12
|
+
WatirSpec.guarded? || browsers.include?(browser.name)
|
13
|
+
end
|
14
|
+
|
15
|
+
module Helpers
|
16
|
+
def deviates_on(*browsers)
|
17
|
+
guard = WatirSpec::Guard.new :deviation, browsers, :file => caller.first
|
18
|
+
yield unless guard.guarded?(OperaWatir::Helper.browser)
|
19
|
+
end
|
20
|
+
|
21
|
+
def not_compliant_on(*browsers)
|
22
|
+
guard = WatirSpec::Guard.new :non_compliance, browsers, :file => caller.first
|
23
|
+
yield unless guard.guarded?(OperaWatir::Helper.browser)
|
24
|
+
end
|
25
|
+
|
26
|
+
def compliant_on(*browsers)
|
27
|
+
guard = WatirSpec::Guard.new :compliance, browsers, :file => caller.first
|
28
|
+
yield unless guard.guarded?(OperaWatir::Helper.browser)
|
29
|
+
end
|
30
|
+
|
31
|
+
def bug(url, *browsers)
|
32
|
+
guard = WatirSpec::Guard.new :bug, browsers, :file => caller.first, :url => url
|
33
|
+
yield unless guard.guarded?(OperaWatir::Helper.browser)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../watirspec_helper', __FILE__)
|
3
|
+
|
4
|
+
# keyboard input
|
5
|
+
# ---------------
|
6
|
+
describe '#keys' do
|
7
|
+
|
8
|
+
after :each do
|
9
|
+
browser.keys.release
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#send' do
|
13
|
+
before :each do
|
14
|
+
browser.url = fixture('two_input_fields.html')
|
15
|
+
@one = window.find_by_name('one')
|
16
|
+
@two = window.find_by_name('two')
|
17
|
+
@one.click!
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'types a single character' do
|
21
|
+
browser.keys.send 'A'
|
22
|
+
@one.value.should == 'A'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'types a mixed-case string' do
|
26
|
+
browser.keys.send 'ABC abc'
|
27
|
+
@one.value.should == 'ABC abc'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'types a string containing multi-byte characters' do
|
31
|
+
browser.keys.send 'ルビー 水'
|
32
|
+
@one.value.should == 'ルビー 水'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'types many single characters in sequence' do
|
36
|
+
browser.keys.send 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
37
|
+
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
38
|
+
'W', 'X', 'Y', 'Z'
|
39
|
+
@one.value.should == 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'moves the caret using arrow keys' do
|
43
|
+
browser.keys.send 'AC', :left, 'B'
|
44
|
+
@one.value.should == 'ABC'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'switches to a different input element with tab' do
|
48
|
+
browser.keys.send 'AB', :tab, 'C'
|
49
|
+
@one.value.should == 'AB'
|
50
|
+
@two.value.should == 'C'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses modifier keys' do
|
54
|
+
browser.keys.send [:shift, 'a'], 'bc'
|
55
|
+
@one.value.should == 'Abc'
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'uses multiple modifier keys to manipulate selection' do
|
59
|
+
browser.keys.send 'ABC 123'
|
60
|
+
|
61
|
+
# Selection using keys works differently on OS X
|
62
|
+
if Config::CONFIG['host_os'] =~ /darwin|mac os/
|
63
|
+
browser.keys.send [:shift, :alt, :left], :backspace
|
64
|
+
else
|
65
|
+
browser.keys.send [:shift, :control, :left], :backspace
|
66
|
+
end
|
67
|
+
|
68
|
+
@one.value.should == 'ABC '
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'presses an invalid key' do
|
72
|
+
p browser.driver.key('hoobaflooba')
|
73
|
+
browser.keys.send(:hoobaflooba).should raise_error InvalidKeyException
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#down' do
|
78
|
+
it 'types a mixed-case string by holding shift' do
|
79
|
+
browser.url = fixture('two_input_fields.html')
|
80
|
+
window.find_by_name('one').click!
|
81
|
+
browser.keys.send 'a'
|
82
|
+
browser.keys.down :shift
|
83
|
+
browser.keys.send 'b'
|
84
|
+
window.find_by_name('one').value.should == 'aB'
|
85
|
+
browser.keys.up :shift
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'holds down a non-modifier key for one second' do
|
89
|
+
browser.url = fixture('two_input_fields.html')
|
90
|
+
window.find_by_name('one').click!
|
91
|
+
browser.keys.down 'a'
|
92
|
+
sleep 1
|
93
|
+
browser.keys.up 'a'
|
94
|
+
window.find_by_name('one').value.should include 'aa' # Two or more characters are expected.
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'triggers onkeydown' do
|
98
|
+
browser.url = fixture('keys.html')
|
99
|
+
browser.keys.down :shift
|
100
|
+
window.find_by_id('log').text.should include 'down, 16'
|
101
|
+
browser.keys.up :shift
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'does not trigger onkeyup' do
|
105
|
+
browser.url = fixture('keys.html')
|
106
|
+
browser.keys.down :shift
|
107
|
+
window.find_by_id('log').text.should_not include 'up, 16'
|
108
|
+
browser.keys.up :shift
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'presses two buttons at the same time' do
|
112
|
+
browser.url = fixture('keys.html')
|
113
|
+
browser.keys.down :shift, :control
|
114
|
+
window.find_by_id('log').text.should include 'down, 16'
|
115
|
+
window.find_by_id('log').text.should include 'down, 17'
|
116
|
+
browser.keys.up :shift
|
117
|
+
browser.keys.up :control
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'presses an invalid key' do
|
121
|
+
browser.keys.down(:hoobaflooba).should raise_error InvalidKeyException
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'passes an array instead of a string' do
|
125
|
+
browser.keys.down([:shift, :control]).should raise_error NativeException
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#up' do
|
130
|
+
it 'types a mixed-case string by holding shift' do
|
131
|
+
browser.url = fixture('two_input_fields.html')
|
132
|
+
window.find_by_name('one').click!
|
133
|
+
browser.keys.down :shift
|
134
|
+
browser.keys.send 'a'
|
135
|
+
browser.keys.send 'b' # Testing that we do not release prematurely
|
136
|
+
browser.keys.up :shift
|
137
|
+
browser.keys.send 'c'
|
138
|
+
window.find_by_name('one').value.should == 'ABc'
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'holds down a non-modifier key for one second (but no longer)' do
|
142
|
+
browser.url = fixture('two_input_fields.html')
|
143
|
+
window.find_by_name('one').click!
|
144
|
+
browser.keys.down 'a'
|
145
|
+
sleep 1
|
146
|
+
browser.keys.up 'a'
|
147
|
+
result_string = window.find_by_name('one').value
|
148
|
+
sleep 1
|
149
|
+
window.find_by_name('one').value.should == result_string
|
150
|
+
result_string = nil
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'triggers onkeyup' do
|
154
|
+
browser.url = fixture('keys.html')
|
155
|
+
browser.keys.down :shift
|
156
|
+
browser.keys.up :shift
|
157
|
+
window.find_by_id('log').text.should include 'up, 16'
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'presses two buttons, but releases only one' do
|
161
|
+
browser.url = fixture('keys.html')
|
162
|
+
browser.keys.down :shift, :control
|
163
|
+
browser.keys.up :shift
|
164
|
+
window.find_by_id('log').text.should include 'up, 16'
|
165
|
+
window.find_by_id('log').text.should_not include 'up, 17'
|
166
|
+
browser.keys.up :control
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'releases two buttons' do
|
170
|
+
browser.url = fixture('keys.html')
|
171
|
+
browser.keys.down :shift, :control
|
172
|
+
browser.keys.up :shift, :control
|
173
|
+
window.find_by_id('log').text.should include 'up, 16'
|
174
|
+
window.find_by_id('log').text.should include 'up, 17'
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'presses an invalid key' do
|
178
|
+
browser.keys.down(:hoobaflooba).should raise_error InvalidKeyException
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'passes an array instead of a string' do
|
182
|
+
browser.keys.up([:shift, :control]).should raise_error NativeException
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#release' do
|
187
|
+
it 'releases one button' do
|
188
|
+
browser.url = fixture('two_input_fields.html')
|
189
|
+
window.find_by_name('one').click!
|
190
|
+
browser.keys.down :shift
|
191
|
+
browser.keys.send 'a'
|
192
|
+
browser.keys.release
|
193
|
+
browser.keys.send 'b'
|
194
|
+
window.find_by_name('one').value.should == 'Ab'
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'releases two buttons' do
|
198
|
+
browser.url = fixture('keys.html')
|
199
|
+
browser.keys.down :shift, :control
|
200
|
+
browser.keys.release
|
201
|
+
window.find_by_id('log').text.should include 'up, 16'
|
202
|
+
window.find_by_id('log').text.should include 'up, 17'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'sinatra/base'
|
3
|
+
|
4
|
+
class WatirSpec::Server < ::Sinatra::Base
|
5
|
+
|
6
|
+
set :app_file, __FILE__
|
7
|
+
set :root, File.dirname(__FILE__)
|
8
|
+
set :public, lambda { File.join(root, 'fixtures')}
|
9
|
+
set :static, true
|
10
|
+
set :run, false
|
11
|
+
set :environment, :production
|
12
|
+
set :bind, 'localhost'
|
13
|
+
set :port, 2000
|
14
|
+
set :server, %w[thin mongrel webrick]
|
15
|
+
|
16
|
+
get '/' do
|
17
|
+
self.class.name
|
18
|
+
end
|
19
|
+
|
20
|
+
get '/big' do
|
21
|
+
Class.new do
|
22
|
+
def each(&blk)
|
23
|
+
yield "<html><head><title>Big Content</title></head><body>"
|
24
|
+
string = "hello "*205
|
25
|
+
300.times { yield string }
|
26
|
+
yield "</body></html>"
|
27
|
+
end
|
28
|
+
end.new
|
29
|
+
end
|
30
|
+
|
31
|
+
post '/post_to_me' do
|
32
|
+
"You posted the following content:\n#{ env['rack.input'].read }"
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/plain_text' do
|
36
|
+
content_type 'text/plain'
|
37
|
+
'This is text/plain'
|
38
|
+
end
|
39
|
+
|
40
|
+
get '/ajax' do
|
41
|
+
sleep 10
|
42
|
+
"A slooow ajax response"
|
43
|
+
end
|
44
|
+
|
45
|
+
get '/charset_mismatch' do
|
46
|
+
content_type 'text/html; charset=UTF-8'
|
47
|
+
%{
|
48
|
+
<html>
|
49
|
+
<head>
|
50
|
+
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
|
51
|
+
</head>
|
52
|
+
<body>
|
53
|
+
<h1>ø</h1>
|
54
|
+
</body>
|
55
|
+
</html>
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
get '/octet_stream' do
|
60
|
+
content_type 'application/octet-stream'
|
61
|
+
'This is application/octet-stream'
|
62
|
+
end
|
63
|
+
|
64
|
+
get '/set_cookie' do
|
65
|
+
content_type 'text/plain'
|
66
|
+
headers 'Set-Cookie' => "monster=/"
|
67
|
+
|
68
|
+
"C is for cookie, it's good enough for me"
|
69
|
+
end
|
70
|
+
|
71
|
+
get '/header_echo' do
|
72
|
+
content_type 'text/plain'
|
73
|
+
env.inspect
|
74
|
+
end
|
75
|
+
|
76
|
+
get '/authentication' do
|
77
|
+
auth = Rack::Auth::Basic::Request.new(env)
|
78
|
+
|
79
|
+
unless auth.provided? && auth.credentials == %w[foo bar]
|
80
|
+
headers 'WWW-Authenticate' => %(Basic realm="localhost")
|
81
|
+
halt 401, 'Authorization Required'
|
82
|
+
end
|
83
|
+
|
84
|
+
"ok"
|
85
|
+
end
|
86
|
+
|
87
|
+
get '/encodable_<stuff>' do
|
88
|
+
'page with characters in URI that need encoding'
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
require 'guards'
|
7
|
+
require 'server'
|
8
|
+
|
9
|
+
require 'operawatir/helper'
|
10
|
+
|
11
|
+
OperaWatir.api = 2
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.mock_with :rr
|
15
|
+
end
|
16
|
+
|
17
|
+
module WatirSpec
|
18
|
+
extend self
|
19
|
+
|
20
|
+
attr_accessor :args, :guarded
|
21
|
+
|
22
|
+
def host
|
23
|
+
"http://#{Server.bind}:#{Server.port}"
|
24
|
+
end
|
25
|
+
alias_method :files, :host
|
26
|
+
|
27
|
+
def guards
|
28
|
+
@guards ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
def guarded?
|
32
|
+
!!@guarded
|
33
|
+
end
|
34
|
+
|
35
|
+
module Helpers
|
36
|
+
def browser
|
37
|
+
OperaWatir::Helper.browser
|
38
|
+
end
|
39
|
+
|
40
|
+
def window
|
41
|
+
browser.active_window
|
42
|
+
end
|
43
|
+
|
44
|
+
def fixture(*paths)
|
45
|
+
[WatirSpec.host, *paths].join('/')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
include OperaWatir::Exceptions
|
52
|
+
|
53
|
+
include WatirSpec::Guard::Helpers
|
54
|
+
|
55
|
+
RSpec.configure do |config|
|
56
|
+
config.include WatirSpec::Helpers
|
57
|
+
|
58
|
+
config.before(:suite) do
|
59
|
+
Thread.new { WatirSpec::Server.run! }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,370 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../watirspec_helper', __FILE__)
|
3
|
+
|
4
|
+
describe 'Window' do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
browser.url = fixture('non_control_elements.html')
|
8
|
+
end
|
9
|
+
|
10
|
+
# element access
|
11
|
+
# --------------
|
12
|
+
|
13
|
+
describe '#find_by_id' do
|
14
|
+
it 'returns an element with the given ID' do
|
15
|
+
elements = window.find_by_id('header')
|
16
|
+
|
17
|
+
elements.should_not be_empty
|
18
|
+
elements.length.should == 1
|
19
|
+
elements.first.attr(:id).should == 'header'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'finds multiple elements with the same id' do
|
23
|
+
elements = window.find_by_id('lead')
|
24
|
+
elements.length.should == 4
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#find_by_tag' do
|
29
|
+
it 'is not empty if the tag exists' do
|
30
|
+
window.find_by_tag(:div).should_not be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns a collection of elements of the given tag' do
|
34
|
+
uls = window.find_by_tag(:ul)
|
35
|
+
uls.length.should == 2
|
36
|
+
uls.find_by_tag(:li).all? do |element|
|
37
|
+
element.parent.tag_name.match(/ul/i)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO I'm not convinced that we should be able to filter in finders
|
42
|
+
it 'contains only elements restricted by the selector' do
|
43
|
+
window.find_by_tag(:div, :title => 'Lorem ipsum').all? do |element|
|
44
|
+
element.attr(:title) == 'Lorem ipsum' && element.tag_name.match(/div/i)
|
45
|
+
end.should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'empty if the elements do not exist' do
|
49
|
+
window.find_by_tag(:hoobaflooba).should be_empty
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# css
|
55
|
+
# we don't want a complete CSS selector test suite here, so just some common
|
56
|
+
# selectors
|
57
|
+
describe '#find_by_css' do
|
58
|
+
it 'is not empty if an element matches the css selector' do
|
59
|
+
window.find_by_css('#outer_container > div').should_not be_empty
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'contains all elements selected by the selector' do
|
63
|
+
window.find_by_css('#outer_container > div').all? do |element|
|
64
|
+
element.parent.attr(:id).should == 'outer_container'
|
65
|
+
end.should be_true
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'is empty if the selector does not match' do
|
69
|
+
window.find_by_css('#hoobaflooba').should be_empty
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# class
|
74
|
+
describe '#find_by_class' do
|
75
|
+
it 'is not empty if an element matches the class' do
|
76
|
+
window.find_by_class('lead').should_not be_empty
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns a collection of elements with the given class' do
|
80
|
+
window.find_by_class('lead').attrs(:class).should == ['lead','lead','lead','lead']
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'finds elements with multiple classes' do
|
84
|
+
window.find_by_class('one').all? do |element|
|
85
|
+
element.attr(:class).should match /one/
|
86
|
+
end.should be_true
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'is empty if the class does not match' do
|
90
|
+
window.find_by_class('hoobaflooba').should be_empty
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# xpath
|
95
|
+
describe '#find_by_xpath' do
|
96
|
+
before :all do
|
97
|
+
@headers = window.find_by_xpath('//h1')
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'is not empty if elements matches the class' do
|
101
|
+
@headers.should_not be_empty
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'contains all elements with the given query' do
|
105
|
+
@headers.all? do |element|
|
106
|
+
element.tag_name.should match /h1/i
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'is empty if the query does not match' do
|
111
|
+
window.find_by_xpath('//hoobaflooba').should be_empty
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# properties
|
116
|
+
# ----------
|
117
|
+
|
118
|
+
describe '#title' do
|
119
|
+
it 'is the title of the window' do
|
120
|
+
window.title.should == 'Non-control elements'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'changes when the title tag changes' do
|
124
|
+
window.find_by_tag(:title).first.text = 'changed'
|
125
|
+
window.title.should == 'changed'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#html' do
|
130
|
+
it 'is the source of the page' do
|
131
|
+
window.html.should match /<title>Non-control elements<\/title>/i
|
132
|
+
end
|
133
|
+
|
134
|
+
# TODO I'm not sure Watir allows DOM manipulation
|
135
|
+
it 'is the original source' do
|
136
|
+
# window.find_by_tag(:title).first.text = 'changed'
|
137
|
+
window.html.should match /<title>Non-control elements<\/title>/i
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# page management
|
142
|
+
# ---------------
|
143
|
+
|
144
|
+
describe '#url' do
|
145
|
+
it 'is the url of this window' do
|
146
|
+
window.url.should == fixture('non_control_elements.html')
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#url=' do
|
151
|
+
it 'navigates to the given url' do
|
152
|
+
window.url = fixture('forms_with_input_elements.html')
|
153
|
+
window.find_by_tag(:title).first.text.should == 'Forms with input elements'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#back' do
|
158
|
+
# should it raise an exception if it fails instead?
|
159
|
+
it 'is possible to go back' do
|
160
|
+
window.url = fixture('forms_with_input_elements.html')
|
161
|
+
window.back.should be_true
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'is false if there is no page to go back to' do
|
165
|
+
# FIXME: We need to open a new window first
|
166
|
+
window.back.should be_false
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'goes back one page in history' do
|
170
|
+
window.url = fixture('forms_with_input_elements.html')
|
171
|
+
window.back
|
172
|
+
window.url.should == fixture('non_control_elements.html')
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '#forward' do
|
177
|
+
it 'is possible to go forward' do
|
178
|
+
window.url = fixture('forms_with_input_elements.html')
|
179
|
+
window.back
|
180
|
+
window.forward.should be_true
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'there is no page to go forward to' do
|
184
|
+
window.forward.should be_false
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'goes forward one page in history' do
|
188
|
+
window.url = fixture('forms_with_input_elements.html')
|
189
|
+
window.back
|
190
|
+
window.forward
|
191
|
+
window.url.should == fixture('forms_with_input_elements.html')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#refresh' do
|
196
|
+
it 'refreshes the current page' do
|
197
|
+
window.url = fixture('forms_with_input_elements.html')
|
198
|
+
field = window.find_by_id('new_user_first_name').first
|
199
|
+
field.value = 'foobar'
|
200
|
+
field.value.should == 'foobar'
|
201
|
+
|
202
|
+
window.refresh
|
203
|
+
field.value.should be_empty
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# actions
|
208
|
+
# -------
|
209
|
+
|
210
|
+
# click(x,y)
|
211
|
+
|
212
|
+
describe '#type' do
|
213
|
+
it 'types the given characters' do
|
214
|
+
browser.url = fixture('forms_with_input_elements.html')
|
215
|
+
textbox = window.find_by_id('new_user_first_name').first
|
216
|
+
textbox.focus!
|
217
|
+
window.type('test')
|
218
|
+
textbox.attr(:value).should == 'test'
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'sends keypress events' do
|
222
|
+
browser.url = fixture('keys.html')
|
223
|
+
window.type('hello')
|
224
|
+
window.find_by_id('log').text.should include 'press, 104, h,'
|
225
|
+
window.find_by_id('log').text.should include 'down, 69, E,'
|
226
|
+
window.find_by_id('log').text.should include 'up, 79, O,'
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#key' do
|
231
|
+
before :each do
|
232
|
+
browser.url = fixture('keys.html')
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'presses and releases the given key' do
|
236
|
+
# TODO Is this how we should send ctrl/shift/alt?
|
237
|
+
window.key('ctrl')
|
238
|
+
|
239
|
+
window.find_by_id('log').text.should include 'down'
|
240
|
+
window.find_by_id('log').text.should include 'ctrl'
|
241
|
+
window.find_by_id('log').text.should include 'up'
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'can press the home key' do
|
245
|
+
window.key('home')
|
246
|
+
window.find_by_id('log').text.should include 'press, 36'
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'can press the tab key' do
|
250
|
+
window.key('tab')
|
251
|
+
window.find_by_id('log').text.should include 'press, 9'
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'tabs through fields when tab is pressed' do
|
255
|
+
window.url = fixture('forms_with_input_elements.html')
|
256
|
+
window.key('tab')
|
257
|
+
window.find_by_id('new_user_first_name').focused?.should be_true
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'can press the F3 key' do
|
261
|
+
window.key('f3')
|
262
|
+
window.find_by_id('log').text.should include 'press, 114'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe '#key_down' do
|
267
|
+
it 'presses down the given key' do
|
268
|
+
browser.url = fixture('keys.html')
|
269
|
+
window.key_down('ctrl')
|
270
|
+
window.key_down('shift')
|
271
|
+
window.find_by_id('log').text.should include 'ctrl,shift'
|
272
|
+
# Don't leave them pressed down
|
273
|
+
window.key_up('ctrl')
|
274
|
+
window.key_up('shift')
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe '#key_up' do
|
279
|
+
it 'releases the given key' do
|
280
|
+
browser.url = fixture('keys.html')
|
281
|
+
window.key_down('ctrl')
|
282
|
+
window.key_up('ctrl')
|
283
|
+
window.find_by_id('log').text.should include 'up, 17'
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe '#eval_js' do
|
288
|
+
it 'executes Javascript in the page' do
|
289
|
+
window.eval_js('document.title = "test"')
|
290
|
+
window.title.should == 'test'
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'returns an element when the Javascript does' do
|
294
|
+
window.eval_js('document.createElement("div")').tag_name.should match /div/i
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'returns a number when the Javascript does' do
|
298
|
+
window.eval_js('Math.abs(-5)').should == 5
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'returns a boolean when the Javascript does' do
|
302
|
+
window.eval_js('(function(){return true;})()').should be_true
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'returns an array when the Javascript does' do
|
306
|
+
result = window.eval_js('["this", "is", "a", "test"]') # WTR-227
|
307
|
+
result.length.should == 4
|
308
|
+
result[3].should == 'test'
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'returns a string when the result is not one of these types' do
|
312
|
+
window.eval_js('({one:"two"}).toString()').should == '[object Object]'
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
# window management
|
317
|
+
# -----------------
|
318
|
+
|
319
|
+
describe '#maximize' do
|
320
|
+
before :each do
|
321
|
+
# Make sure we aren't already maximized
|
322
|
+
window.restore
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'maximizes the window' do
|
326
|
+
body = window.find_by_tag(:body).first
|
327
|
+
width = body.width
|
328
|
+
window.maximize
|
329
|
+
body.width.should be > width
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '#restore' do
|
334
|
+
it 'restores (unmaximizes) the window' do
|
335
|
+
body = window.find_by_tag(:body).first
|
336
|
+
# Make sure we aren't already restored
|
337
|
+
window.maximize
|
338
|
+
width = body.width
|
339
|
+
window.restore
|
340
|
+
body.width.should be < width
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe '#exists?' do
|
345
|
+
it 'is true if the window exists' do
|
346
|
+
window.exists?.should be_true
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'is false if the window does not exist' do
|
350
|
+
window.close
|
351
|
+
window.exists?.should be_false
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#close' do
|
356
|
+
it 'destroys the window' do
|
357
|
+
window.close
|
358
|
+
window.exists?.should be_false
|
359
|
+
window.find_by_tag(:title).should raise_error
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
describe '#new' do
|
364
|
+
it 'creates a new window' do
|
365
|
+
new_window = browser.url(fixture('non_control_elements.html'))
|
366
|
+
new_window.exists?.should be_true
|
367
|
+
new_window.url.should == fixture('non_control_elements.html')
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|