selenium-webdriver 2.47.1 → 2.48.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/CHANGES +18 -0
  2. data/Gemfile.lock +1 -1
  3. data/lib/selenium/client/base.rb +3 -3
  4. data/lib/selenium/client/extensions.rb +15 -18
  5. data/lib/selenium/client/idiomatic.rb +26 -26
  6. data/lib/selenium/client/javascript_expression_builder.rb +8 -8
  7. data/lib/selenium/webdriver/common.rb +1 -1
  8. data/lib/selenium/webdriver/common/driver.rb +5 -1
  9. data/lib/selenium/webdriver/common/error.rb +5 -8
  10. data/lib/selenium/webdriver/common/search_context.rb +6 -0
  11. data/lib/selenium/webdriver/common/target_locator.rb +4 -0
  12. data/lib/selenium/webdriver/common/w3c_error.rb +194 -0
  13. data/lib/selenium/webdriver/firefox.rb +3 -0
  14. data/lib/selenium/webdriver/firefox/binary.rb +13 -0
  15. data/lib/selenium/webdriver/firefox/extension/prefs.json +2 -1
  16. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  17. data/lib/selenium/webdriver/firefox/service.rb +120 -0
  18. data/lib/selenium/webdriver/firefox/w3c_bridge.rb +97 -0
  19. data/lib/selenium/webdriver/remote.rb +3 -0
  20. data/lib/selenium/webdriver/remote/bridge.rb +17 -10
  21. data/lib/selenium/webdriver/remote/capabilities.rb +1 -2
  22. data/lib/selenium/webdriver/remote/commands.rb +5 -0
  23. data/lib/selenium/webdriver/remote/response.rb +5 -6
  24. data/lib/selenium/webdriver/remote/w3c_bridge.rb +676 -0
  25. data/lib/selenium/webdriver/remote/w3c_capabilities.rb +208 -0
  26. data/lib/selenium/webdriver/remote/w3c_commands.rb +133 -0
  27. data/lib/selenium/webdriver/safari/resources/client.js +653 -629
  28. data/selenium-webdriver.gemspec +1 -1
  29. metadata +8 -4
  30. data/lib/selenium/webdriver/common/core_ext/string.rb +0 -24
  31. data/lib/selenium/webdriver/safari/resources/SafariDriver.safariextz +0 -0
data/CHANGES CHANGED
@@ -1,3 +1,21 @@
1
+ 2.48.0 (2015-10-07)
2
+ ===================
3
+
4
+ Firefox:
5
+ * Initial implementation of Mozilla's Wires Driver for Marionette; Supported in version 43 and higher
6
+
7
+ Edge:
8
+ * Fix execution with Remote Server
9
+ * Fix Javascript Execution
10
+ * Implement Alert Handling
11
+ * Implement Window Switching
12
+
13
+ Ruby:
14
+ * Initial implementation of W3C WebDriver syntax to support Mozilla Wires
15
+ * Change to RSpec expect syntax
16
+ * Specs can be run from relative directories
17
+
18
+
1
19
  2.47.1 (2015-07-31)
2
20
  ===================
3
21
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- selenium-webdriver (2.47.1)
4
+ selenium-webdriver (2.48.0.dev)
5
5
  childprocess (~> 0.5)
6
6
  multi_json (~> 1.0)
7
7
  rubyzip (~> 1.0)
@@ -20,7 +20,7 @@
20
20
  module Selenium
21
21
  module Client
22
22
 
23
- # Driver constructor and session management commands
23
+ # Driver constructor and session management commands
24
24
  module Base
25
25
  include Selenium::Client::Protocol
26
26
  include Selenium::Client::GeneratedDriver
@@ -133,7 +133,7 @@ module Selenium
133
133
  end
134
134
 
135
135
  def stop
136
- close_current_browser_session
136
+ close_current_browser_session
137
137
  end
138
138
 
139
139
  def chrome_backend?
@@ -143,7 +143,7 @@ module Selenium
143
143
  def javascript_extension=(new_javascript_extension)
144
144
  @extension_js = new_javascript_extension
145
145
  end
146
- alias :set_extension_js :javascript_extension=
146
+ alias :set_extension_js :javascript_extension=
147
147
 
148
148
  end
149
149
 
@@ -23,22 +23,19 @@ module Selenium
23
23
  # Convenience methods not explicitly part of the protocol
24
24
  module Extensions
25
25
 
26
- # These for all Ajax request to finish (Only works if you are using prototype, the wait happens in the browser)
27
- #
26
+ # These for all Ajax request to finish (Only works if you are using prototype, the wait happens in the browser)
28
27
  def wait_for_ajax(options={})
29
- builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
30
- wait_for_condition builder.no_pending_ajax_requests.script,
31
- options[:timeout_in_seconds]
28
+ builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
29
+ wait_for_condition builder.no_pending_ajax_requests.script, options[:timeout_in_seconds]
32
30
  end
33
31
 
34
- # Wait for all Prototype effects to be processed (the wait happens in the browser).
35
- #
36
- # Credits to http://github.com/brynary/webrat/tree/master
37
- def wait_for_effects(options={})
38
- builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
39
- wait_for_condition builder.no_pending_effects.script,
40
- options[:timeout_in_seconds]
41
- end
32
+ # Wait for all Prototype effects to be processed (the wait happens in the browser).
33
+ #
34
+ # Credits to http://github.com/brynary/webrat/tree/master
35
+ def wait_for_effects(options={})
36
+ builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
37
+ wait_for_condition builder.no_pending_effects.script, options[:timeout_in_seconds]
38
+ end
42
39
 
43
40
  # Wait for an element to be present (the wait happens in the browser).
44
41
  def wait_for_element(locator, options={})
@@ -54,8 +51,8 @@ module Selenium
54
51
  wait_for_condition builder.script, options[:timeout_in_seconds]
55
52
  end
56
53
 
57
- # Wait for some text to be present (the wait is happening browser side).
58
- #
54
+ # Wait for some text to be present (the wait is happening browser side).
55
+ #
59
56
  # wait_for_text will search for the given argument within the innerHTML
60
57
  # of the current DOM. Note that this method treats a single string
61
58
  # as a special case.
@@ -86,7 +83,7 @@ module Selenium
86
83
  #
87
84
  def wait_for_text(pattern, options={})
88
85
  builder = JavascriptExpressionBuilder.new
89
- builder.find_text(pattern, options).append("text_match == true;")
86
+ builder.find_text(pattern, options).append("text_match == true;")
90
87
  wait_for_condition builder.script, options[:timeout_in_seconds]
91
88
  end
92
89
 
@@ -95,7 +92,7 @@ module Selenium
95
92
  # See wait_for_text for usage details.
96
93
  def wait_for_no_text(pattern, options={})
97
94
  builder = JavascriptExpressionBuilder.new
98
- builder.find_text(pattern, options).append("text_match == false;")
95
+ builder.find_text(pattern, options).append("text_match == false;")
99
96
  wait_for_condition builder.script, options[:timeout_in_seconds]
100
97
  end
101
98
 
@@ -132,4 +129,4 @@ module Selenium
132
129
  end
133
130
 
134
131
  end
135
- end
132
+ end
@@ -20,9 +20,9 @@
20
20
  module Selenium
21
21
  module Client
22
22
 
23
- # Provide a more idiomatic API than the generated Ruby driver.
24
- #
25
- # Work in progress...
23
+ # Provide a more idiomatic API than the generated Ruby driver.
24
+ #
25
+ # Work in progress...
26
26
  module Idiomatic
27
27
 
28
28
  # Return the text content of an HTML element (rendered text shown to
@@ -102,31 +102,31 @@ module Selenium
102
102
  def wait_for(options)
103
103
  if options[:wait_for] == :page
104
104
  wait_for_page options[:timeout_in_seconds]
105
- elsif options[:wait_for] == :ajax
106
- wait_for_ajax options
107
- elsif options[:wait_for] == :element
108
- wait_for_element options[:element], options
109
- elsif options[:wait_for] == :no_element
110
- wait_for_no_element options[:element], options
111
- elsif options[:wait_for] == :text
112
- wait_for_text options[:text], options
113
- elsif options[:wait_for] == :no_text
105
+ elsif options[:wait_for] == :ajax
106
+ wait_for_ajax options
107
+ elsif options[:wait_for] == :element
108
+ wait_for_element options[:element], options
109
+ elsif options[:wait_for] == :no_element
110
+ wait_for_no_element options[:element], options
111
+ elsif options[:wait_for] == :text
112
+ wait_for_text options[:text], options
113
+ elsif options[:wait_for] == :no_text
114
114
  wait_for_no_text options[:text], options
115
- elsif options[:wait_for] == :effects
116
- wait_for_effects options
115
+ elsif options[:wait_for] == :effects
116
+ wait_for_effects options
117
117
  elsif options[:wait_for] == :popup
118
- wait_for_popup options[:window], options[:timeout_in_seconds]
119
- select_window options[:window] if options[:select]
118
+ wait_for_popup options[:window], options[:timeout_in_seconds]
119
+ select_window options[:window] if options[:select]
120
120
  elsif options[:wait_for] == :value
121
- wait_for_field_value options[:element], options[:value], options
121
+ wait_for_field_value options[:element], options[:value], options
122
122
  elsif options[:wait_for] == :no_value
123
- wait_for_no_field_value options[:element], options[:value], options
123
+ wait_for_no_field_value options[:element], options[:value], options
124
124
  elsif options[:wait_for] == :visible
125
- wait_for_visible options[:element], options
125
+ wait_for_visible options[:element], options
126
126
  elsif options[:wait_for] == :not_visible
127
- wait_for_not_visible options[:element], options
128
- elsif options[:wait_for] == :condition
129
- wait_for_condition options[:javascript], options[:timeout_in_seconds]
127
+ wait_for_not_visible options[:element], options
128
+ elsif options[:wait_for] == :condition
129
+ wait_for_condition options[:javascript], options[:timeout_in_seconds]
130
130
  end
131
131
  end
132
132
 
@@ -206,7 +206,7 @@ module Selenium
206
206
 
207
207
  # Alias for +field+
208
208
  def value(locator)
209
- field locator
209
+ field locator
210
210
  end
211
211
 
212
212
  # Returns whether a toggle-button (checkbox/radio) is checked.
@@ -397,7 +397,7 @@ module Selenium
397
397
  # the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will usually fail.
398
398
  def create_cookie(name_value_pair, options="")
399
399
  if options.kind_of? Hash
400
- options = options.keys.collect {|key| "#{key}=#{options[key]}" }.sort.join(", ")
400
+ options = options.keys.collect {|key| "#{key}=#{options[key]}" }.sort.join(", ")
401
401
  end
402
402
  remote_control_command "createCookie", [name_value_pair,options,]
403
403
  end
@@ -417,8 +417,8 @@ module Selenium
417
417
  # 'optionsString' is options for the cookie. Currently supported options include 'path', 'domain' and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". The order of options are irrelevant. Note that specifying a domain that isn't a subset of the current domain will usually fail.
418
418
  def delete_cookie(name, options="")
419
419
  if options.kind_of? Hash
420
- ordered_keys = options.keys.sort {|a,b| a.to_s <=> b.to_s }
421
- options = ordered_keys.collect {|key| "#{key}=#{options[key]}" }.join(", ")
420
+ ordered_keys = options.keys.sort {|a,b| a.to_s <=> b.to_s }
421
+ options = ordered_keys.collect {|key| "#{key}=#{options[key]}" }.join(", ")
422
422
  end
423
423
  remote_control_command "deleteCookie", [name,options,]
424
424
  end
@@ -28,18 +28,18 @@ module Selenium
28
28
  @script = ""
29
29
  end
30
30
 
31
- def append(text)
32
- @script << text
33
- self
34
- end
31
+ def append(text)
32
+ @script << text
33
+ self
34
+ end
35
35
 
36
36
  def no_pending_ajax_requests
37
37
  append window_script("#{@framework.ajax_request_tracker} == 0")
38
38
  end
39
39
 
40
- def no_pending_effects
41
- append window_script("Effect.Queue.size() == 0")
42
- end
40
+ def no_pending_effects
41
+ append window_script("Effect.Queue.size() == 0")
42
+ end
43
43
 
44
44
  def visible(locator)
45
45
  append "selenium.isVisible('#{quote_escaped(locator)}')"
@@ -132,4 +132,4 @@ module Selenium
132
132
  end
133
133
  end
134
134
  end
135
- end
135
+ end
@@ -18,8 +18,8 @@
18
18
  # under the License.
19
19
 
20
20
  require 'selenium/webdriver/common/core_ext/dir'
21
- require 'selenium/webdriver/common/core_ext/string'
22
21
  require 'selenium/webdriver/common/core_ext/base64'
22
+ require 'selenium/webdriver/common/w3c_error'
23
23
  require 'selenium/webdriver/common/error'
24
24
  require 'selenium/webdriver/common/platform'
25
25
  require 'selenium/webdriver/common/proxy'
@@ -47,7 +47,11 @@ module Selenium
47
47
 
48
48
  bridge = case browser
49
49
  when :firefox, :ff
50
- Firefox::Bridge.new(opts)
50
+ if Remote::W3CCapabilities.w3c?(opts)
51
+ Firefox::W3CBridge.new(opts)
52
+ else
53
+ Firefox::Bridge.new(opts)
54
+ end
51
55
  when :remote
52
56
  Remote::Bridge.new(opts)
53
57
  when :ie, :internet_explorer
@@ -206,18 +206,15 @@ module Selenium
206
206
  MoveTargetOutOfBoundsError # 34
207
207
  ]
208
208
 
209
- # aliased for backwards compatibility
210
- ObsoleteElementError = StaleElementReferenceError
211
- UnhandledError = UnknownError
212
- UnexpectedJavascriptError = JavascriptError
213
- NoAlertOpenError = NoAlertPresentError
214
- ElementNotDisplayedError = ElementNotVisibleError
215
-
216
209
  class << self
217
210
  def for_code(code)
218
211
  return if [nil, 0].include? code
212
+ return Errors[code - 1] if code.is_a? Fixnum
219
213
 
220
- Errors[code - 1] || WebDriverError
214
+ klass_name = code.split(' ').map(&:capitalize).join
215
+ Error.const_get("#{klass_name}Error")
216
+ rescue NameError
217
+ WebDriverError
221
218
  end
222
219
  end
223
220
 
@@ -59,6 +59,9 @@ module Selenium
59
59
  end
60
60
 
61
61
  bridge.find_element_by by, what.to_s, ref
62
+ rescue Selenium::WebDriver::Error::TimeOutError
63
+ # Implicit Wait times out in Edge
64
+ raise Selenium::WebDriver::Error::NoSuchElementError
62
65
  end
63
66
 
64
67
  #
@@ -79,6 +82,9 @@ module Selenium
79
82
  end
80
83
 
81
84
  bridge.find_elements_by by, what.to_s, ref
85
+ rescue Selenium::WebDriver::Error::TimeOutError
86
+ # Implicit Wait times out in Edge
87
+ []
82
88
  end
83
89
 
84
90
  private
@@ -63,6 +63,10 @@ module Selenium
63
63
  nil
64
64
  end
65
65
 
66
+ unless @bridge.getWindowHandles.include? id
67
+ raise Error::NoSuchWindowError, "The specified identifier '#{id}' is not found in the window handle list"
68
+ end
69
+
66
70
  @bridge.switchToWindow id
67
71
 
68
72
  begin
@@ -0,0 +1,194 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Error
23
+
24
+ class WebDriverError < StandardError; end
25
+
26
+ #
27
+ # An attempt was made to select an element that cannot be selected.
28
+ #
29
+
30
+ class ElementNotSelectableError < WebDriverError; end
31
+
32
+ #
33
+ # An element command could not be completed because the element is
34
+ # not visible on the page.
35
+ #
36
+
37
+ class ElementNotVisibleError < WebDriverError; end
38
+
39
+ #
40
+ # The arguments passed to a command are either invalid or malformed.
41
+ #
42
+
43
+ class InvalidArgumentError < WebDriverError; end
44
+
45
+ #
46
+ # An illegal attempt was made to set a cookie under a different
47
+ # domain than the current page.
48
+ #
49
+
50
+ class InvalidCookieDomainError < WebDriverError; end
51
+
52
+ #
53
+ # The coordinates provided to an interactions operation are invalid.
54
+ #
55
+
56
+ class InvalidElementCoordinatesError < WebDriverError; end
57
+
58
+ #
59
+ # An element command could not be completed because the element is
60
+ # in an invalid state, e.g. attempting to click an element that is no
61
+ # longer attached to the document.
62
+ #
63
+
64
+ class InvalidElementStateError < WebDriverError; end
65
+
66
+ #
67
+ # Argument was an invalid selector.
68
+ #
69
+
70
+ class InvalidSelectorError < WebDriverError; end
71
+
72
+ #
73
+ # Occurs if the given session id is not in the list of active sessions,
74
+ # meaning the session either does not exist or that it’s not active.
75
+ #
76
+
77
+ class InvalidSessionIdError < WebDriverError; end
78
+
79
+ #
80
+ # An error occurred while executing JavaScript supplied by the user.
81
+ #
82
+
83
+ class JavascriptError < WebDriverError; end
84
+
85
+ #
86
+ # The target for mouse interaction is not in the browser’s viewport and
87
+ # cannot be brought into that viewport.
88
+ #
89
+
90
+ class MoveTargetOutOfBoundsError < WebDriverError; end
91
+
92
+ #
93
+ # An attempt was made to operate on a modal dialog when one was not open.
94
+ #
95
+
96
+ class NoSuchAlertError < WebDriverError; end
97
+
98
+ #
99
+ # An element could not be located on the page using the given
100
+ # search parameters.
101
+ #
102
+
103
+ class NoSuchElementError < WebDriverError; end
104
+
105
+ #
106
+ # A request to switch to a frame could not be satisfied because the
107
+ # frame could not be found.
108
+ #
109
+
110
+ class NoSuchFrameError < WebDriverError; end
111
+
112
+ #
113
+ # A request to switch to a window could not be satisfied because the
114
+ # window could not be found.
115
+ #
116
+
117
+ class NoSuchWindowError < WebDriverError; end
118
+
119
+ #
120
+ # A script did not complete before its timeout expired.
121
+ #
122
+
123
+ class ScriptTimeoutError < WebDriverError; end
124
+
125
+ #
126
+ # A new session could not be created.
127
+ #
128
+
129
+ class SessionNotCreatedError < WebDriverError; end
130
+
131
+ #
132
+ # An element command failed because the referenced element is no longer
133
+ # attached to the DOM.
134
+ #
135
+
136
+ class StaleElementReferenceError < WebDriverError; end
137
+
138
+ #
139
+ # An operation did not complete before its timeout expired.
140
+ #
141
+
142
+ class TimeoutError < WebDriverError; end
143
+
144
+ #
145
+ # A request to set a cookie’s value could not be satisfied.
146
+ #
147
+
148
+ class UnableToSetCookieError < WebDriverError; end
149
+
150
+ #
151
+ # A screen capture was made impossible.
152
+ #
153
+
154
+ class UnableToCaptureScreenError < WebDriverError; end
155
+
156
+ #
157
+ # A modal dialog was open, blocking this operation.
158
+ #
159
+
160
+ class UnexpectedAlertOpenError < WebDriverError; end
161
+
162
+ #
163
+ # An unknown error occurred in the remote end while processing
164
+ # the command.
165
+ #
166
+
167
+ class UnknownError < WebDriverError; end
168
+
169
+ #
170
+ # The requested command matched a known URL but did not match a
171
+ # method for that URL.
172
+ #
173
+
174
+ class UnknownMethodError < WebDriverError; end
175
+
176
+ #
177
+ # Indicates that a command that should have executed properly cannot be supported for some reason.
178
+ #
179
+
180
+ class UnsupportedOperationError < WebDriverError; end
181
+
182
+ # aliased for backwards compatibility
183
+ NoAlertPresentError = NoSuchAlertError
184
+ ScriptTimeOutError = ScriptTimeoutError
185
+ ObsoleteElementError = StaleElementReferenceError
186
+ UnhandledError = UnknownError
187
+ UnexpectedJavascriptError = JavascriptError
188
+ NoAlertOpenError = NoAlertPresentError
189
+ ElementNotDisplayedError = ElementNotVisibleError
190
+
191
+
192
+ end # Error
193
+ end # WebDriver
194
+ end # Selenium