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.
Files changed (55) hide show
  1. data/Gemfile +6 -2
  2. data/LICENSE +1 -1
  3. data/Rakefile +7 -8
  4. data/VERSION +1 -1
  5. data/bin/desktopwatir +3 -0
  6. data/bin/operawatir +2 -2
  7. data/lib/operadriver/webdriver-opera.jar +0 -0
  8. data/lib/operawatir.rb +14 -8
  9. data/lib/operawatir/browser.rb +49 -38
  10. data/lib/operawatir/compat/collection.rb +6 -0
  11. data/lib/operawatir/compat/element.rb +5 -2
  12. data/lib/operawatir/compat/element_finders.rb +19 -0
  13. data/lib/operawatir/desktop-waiter.rb +144 -0
  14. data/lib/operawatir/desktop_browser.rb +506 -0
  15. data/lib/operawatir/desktop_common.rb +111 -0
  16. data/lib/operawatir/desktop_container.rb +252 -0
  17. data/lib/operawatir/desktop_enums.rb +42 -0
  18. data/lib/operawatir/desktop_exceptions.rb +16 -0
  19. data/lib/operawatir/element.rb +6 -6
  20. data/lib/operawatir/exceptions.rb +3 -0
  21. data/lib/operawatir/keys.rb +116 -0
  22. data/lib/operawatir/platform.rb +59 -0
  23. data/lib/operawatir/quickwidgets.rb +3 -0
  24. data/lib/operawatir/quickwidgets/quick_addressfield.rb +23 -0
  25. data/lib/operawatir/quickwidgets/quick_button.rb +151 -0
  26. data/lib/operawatir/quickwidgets/quick_checkbox.rb +58 -0
  27. data/lib/operawatir/quickwidgets/quick_dialogtab.rb +23 -0
  28. data/lib/operawatir/quickwidgets/quick_dropdown.rb +27 -0
  29. data/lib/operawatir/quickwidgets/quick_editfield.rb +115 -0
  30. data/lib/operawatir/quickwidgets/quick_label.rb +12 -0
  31. data/lib/operawatir/quickwidgets/quick_radiobutton.rb +11 -0
  32. data/lib/operawatir/quickwidgets/quick_searchfield.rb +25 -0
  33. data/lib/operawatir/quickwidgets/quick_tab.rb +66 -0
  34. data/lib/operawatir/quickwidgets/quick_thumbnail.rb +26 -0
  35. data/lib/operawatir/quickwidgets/quick_toolbar.rb +11 -0
  36. data/lib/operawatir/quickwidgets/quick_treeitem.rb +157 -0
  37. data/lib/operawatir/quickwidgets/quick_treeview.rb +27 -0
  38. data/lib/operawatir/quickwidgets/quick_widget.rb +369 -0
  39. data/lib/operawatir/quickwidgets/quick_window.rb +150 -0
  40. data/lib/operawatir/selector.rb +1 -1
  41. data/lib/operawatir/version.rb +0 -1
  42. data/lib/operawatir/window.rb +9 -0
  43. data/operawatir.gemspec +382 -0
  44. data/spec/new_watirspec/browser_spec.rb +279 -0
  45. data/spec/new_watirspec/clipboard_spec.rb +79 -0
  46. data/spec/new_watirspec/collection_spec.rb +387 -0
  47. data/spec/new_watirspec/element_spec.rb +456 -0
  48. data/spec/new_watirspec/guards.rb +39 -0
  49. data/spec/new_watirspec/keys_spec.rb +206 -0
  50. data/spec/new_watirspec/server.rb +91 -0
  51. data/spec/new_watirspec/watirspec_helper.rb +62 -0
  52. data/spec/new_watirspec/window_spec.rb +370 -0
  53. data/utils/launchers/launcher-mac +0 -0
  54. metadata +191 -28
  55. 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