selenium-webdriver 2.47.1 → 2.48.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.
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