selenium-webdriver 4.0.0.alpha5 → 4.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/selenium/devtools.rb +30 -0
  3. data/lib/selenium/server.rb +18 -26
  4. data/lib/selenium/webdriver.rb +1 -3
  5. data/lib/selenium/webdriver/atoms/findElements.js +93 -93
  6. data/lib/selenium/webdriver/atoms/getAttribute.js +75 -59
  7. data/lib/selenium/webdriver/atoms/isDisplayed.js +72 -72
  8. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  9. data/lib/selenium/webdriver/chrome.rb +1 -1
  10. data/lib/selenium/webdriver/chrome/driver.rb +28 -6
  11. data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +6 -8
  12. data/lib/selenium/webdriver/chrome/options.rb +54 -37
  13. data/lib/selenium/webdriver/chrome/profile.rb +6 -3
  14. data/lib/selenium/webdriver/chrome/service.rb +4 -2
  15. data/lib/selenium/webdriver/common.rb +7 -2
  16. data/lib/selenium/webdriver/common/driver.rb +86 -26
  17. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  18. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +6 -1
  19. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  20. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +149 -0
  21. data/lib/selenium/webdriver/{edge_chrome/bridge.rb → common/driver_extensions/has_logs.rb} +7 -7
  22. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  23. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +67 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  26. data/lib/selenium/webdriver/common/element.rb +66 -12
  27. data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
  28. data/lib/selenium/webdriver/common/logger.rb +6 -3
  29. data/lib/selenium/webdriver/common/manager.rb +11 -1
  30. data/lib/selenium/webdriver/common/options.rb +90 -11
  31. data/lib/selenium/webdriver/common/platform.rb +3 -1
  32. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  33. data/lib/selenium/webdriver/common/proxy.rb +4 -1
  34. data/lib/selenium/webdriver/common/search_context.rb +4 -1
  35. data/lib/selenium/webdriver/common/service.rb +13 -114
  36. data/lib/selenium/webdriver/common/service_manager.rb +151 -0
  37. data/lib/selenium/webdriver/common/socket_poller.rb +19 -30
  38. data/lib/selenium/webdriver/common/takes_screenshot.rb +63 -0
  39. data/lib/selenium/webdriver/common/target_locator.rb +4 -4
  40. data/lib/selenium/webdriver/devtools.rb +144 -0
  41. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  42. data/lib/selenium/webdriver/{edge_html/driver.rb → devtools/exception_event.rb} +10 -13
  43. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  44. data/lib/selenium/webdriver/devtools/request.rb +57 -0
  45. data/lib/selenium/webdriver/edge.rb +7 -29
  46. data/lib/selenium/webdriver/{edge_chrome → edge}/driver.rb +10 -4
  47. data/lib/selenium/webdriver/edge/features.rb +39 -0
  48. data/lib/selenium/webdriver/{edge_chrome → edge}/options.rb +12 -3
  49. data/lib/selenium/webdriver/{edge_chrome → edge}/profile.rb +2 -2
  50. data/lib/selenium/webdriver/{edge_chrome → edge}/service.rb +2 -2
  51. data/lib/selenium/webdriver/firefox.rb +5 -1
  52. data/lib/selenium/webdriver/firefox/driver.rb +19 -3
  53. data/lib/selenium/webdriver/firefox/{bridge.rb → features.rb} +3 -3
  54. data/lib/selenium/webdriver/firefox/options.rb +25 -31
  55. data/lib/selenium/webdriver/firefox/profile.rb +12 -2
  56. data/lib/selenium/webdriver/firefox/service.rb +1 -1
  57. data/lib/selenium/webdriver/ie/driver.rb +1 -2
  58. data/lib/selenium/webdriver/ie/options.rb +7 -20
  59. data/lib/selenium/webdriver/ie/service.rb +4 -2
  60. data/lib/selenium/webdriver/remote/bridge.rb +50 -42
  61. data/lib/selenium/webdriver/remote/capabilities.rb +127 -71
  62. data/lib/selenium/webdriver/remote/commands.rb +3 -0
  63. data/lib/selenium/webdriver/remote/driver.rb +10 -3
  64. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  65. data/lib/selenium/webdriver/remote/http/default.rb +8 -7
  66. data/lib/selenium/webdriver/remote/http/persistent.rb +6 -0
  67. data/lib/selenium/webdriver/safari.rb +8 -1
  68. data/lib/selenium/webdriver/safari/driver.rb +3 -4
  69. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
  70. data/lib/selenium/webdriver/safari/options.rb +1 -33
  71. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  72. data/lib/selenium/webdriver/support/color.rb +2 -2
  73. data/lib/selenium/webdriver/support/event_firing_bridge.rb +1 -1
  74. data/lib/selenium/webdriver/support/guards.rb +95 -0
  75. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  76. data/lib/selenium/webdriver/support/guards/guard_condition.rb +52 -0
  77. data/lib/selenium/webdriver/support/select.rb +2 -2
  78. data/lib/selenium/webdriver/version.rb +1 -1
  79. metadata +69 -32
  80. data/CHANGES +0 -1725
  81. data/Gemfile +0 -4
  82. data/LICENSE +0 -202
  83. data/README.md +0 -35
  84. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -65
  85. data/lib/selenium/webdriver/edge_html/options.rb +0 -91
  86. data/lib/selenium/webdriver/edge_html/service.rb +0 -47
  87. data/selenium-webdriver.gemspec +0 -48
@@ -57,10 +57,10 @@ module Selenium
57
57
  def window(id)
58
58
  if block_given?
59
59
  original = begin
60
- @bridge.window_handle
61
- rescue Error::NoSuchWindowError
62
- nil
63
- end
60
+ @bridge.window_handle
61
+ rescue Error::NoSuchWindowError
62
+ nil
63
+ end
64
64
 
65
65
  unless @bridge.window_handles.include? id
66
66
  raise Error::NoSuchWindowError, "The specified identifier '#{id}' is not found in the window handle list"
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
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
+ class DevTools
23
+ autoload :ConsoleEvent, 'selenium/webdriver/devtools/console_event'
24
+ autoload :ExceptionEvent, 'selenium/webdriver/devtools/exception_event'
25
+ autoload :MutationEvent, 'selenium/webdriver/devtools/mutation_event'
26
+ autoload :Request, 'selenium/webdriver/devtools/request'
27
+
28
+ def initialize(url:)
29
+ @messages = []
30
+ @session_id = nil
31
+ @url = url
32
+
33
+ process_handshake
34
+ attach_socket_listener
35
+ start_session
36
+ end
37
+
38
+ def callbacks
39
+ @callbacks ||= Hash.new { |callbacks, event| callbacks[event] = [] }
40
+ end
41
+
42
+ def send_cmd(method, **params)
43
+ id = next_id
44
+ data = {id: id, method: method, params: params.reject { |_, v| v.nil? }}
45
+ data[:sessionId] = @session_id if @session_id
46
+ data = JSON.generate(data)
47
+ WebDriver.logger.debug "DevTools -> #{data}"
48
+
49
+ out_frame = WebSocket::Frame::Outgoing::Client.new(version: ws.version, data: data, type: 'text')
50
+ socket.write(out_frame.to_s)
51
+
52
+ message = wait.until do
53
+ @messages.find { |m| m['id'] == id }
54
+ end
55
+
56
+ raise Error::WebDriverError, error_message(message['error']) if message['error']
57
+
58
+ message
59
+ end
60
+
61
+ def method_missing(method, *_args)
62
+ desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
63
+ return unless Object.const_defined?(desired_class)
64
+
65
+ self.class.class_eval do
66
+ define_method(method) do
67
+ Object.const_get(desired_class).new(self)
68
+ end
69
+ end
70
+
71
+ send(method)
72
+ end
73
+
74
+ def respond_to_missing?(method, *_args)
75
+ desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
76
+ Object.const_defined?(desired_class)
77
+ end
78
+
79
+ private
80
+
81
+ def process_handshake
82
+ socket.print(ws.to_s)
83
+ ws << socket.readpartial(1024)
84
+ end
85
+
86
+ def attach_socket_listener
87
+ socket_listener = Thread.new do
88
+ until socket.eof?
89
+ incoming_frame << socket.readpartial(1024)
90
+
91
+ while (frame = incoming_frame.next)
92
+ # Firefox will periodically fail on unparsable empty frame
93
+ break if frame.to_s.empty?
94
+
95
+ message = JSON.parse(frame.to_s)
96
+ @messages << message
97
+ WebDriver.logger.debug "DevTools <- #{message}"
98
+ next unless message['method']
99
+
100
+ callbacks[message['method']].each do |callback|
101
+ params = message['params'] # take in current thread!
102
+ Thread.new { callback.call(params) }
103
+ end
104
+ end
105
+ end
106
+ end
107
+ socket_listener.abort_on_exception = true
108
+ end
109
+
110
+ def start_session
111
+ targets = target.get_targets.dig('result', 'targetInfos')
112
+ page_target = targets.find { |target| target['type'] == 'page' }
113
+ session = target.attach_to_target(target_id: page_target['targetId'], flatten: true)
114
+ @session_id = session.dig('result', 'sessionId')
115
+ end
116
+
117
+ def incoming_frame
118
+ @incoming_frame ||= WebSocket::Frame::Incoming::Client.new(version: ws.version)
119
+ end
120
+
121
+ def wait
122
+ @wait ||= Wait.new(timeout: 10, interval: 0.1)
123
+ end
124
+
125
+ def socket
126
+ @socket ||= TCPSocket.new(ws.host, ws.port)
127
+ end
128
+
129
+ def ws
130
+ @ws ||= WebSocket::Handshake::Client.new(url: @url)
131
+ end
132
+
133
+ def next_id
134
+ @id ||= 0
135
+ @id += 1
136
+ end
137
+
138
+ def error_message(error)
139
+ [error['code'], error['message'], error['data']].join(': ')
140
+ end
141
+
142
+ end # DevTools
143
+ end # WebDriver
144
+ end # Selenium
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
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
+ class DevTools
23
+ class ConsoleEvent
24
+
25
+ attr_accessor :type, :timestamp, :args
26
+
27
+ def initialize(type:, timestamp:, args:)
28
+ @type = type.to_sym
29
+ @timestamp = Time.at(timestamp / 1000)
30
+ @args = args.map do |arg|
31
+ arg.key?('value') ? arg['value'] : arg
32
+ end
33
+ end
34
+
35
+ end # ConsoleEvent
36
+ end # DevTools
37
+ end # WebDriver
38
+ end # Selenium
@@ -19,21 +19,18 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module EdgeHtml
22
+ class DevTools
23
+ class ExceptionEvent
23
24
 
24
- #
25
- # Driver implementation for Microsoft Edge.
26
- # @api private
27
- #
25
+ attr_accessor :description, :timestamp, :stacktrace
28
26
 
29
- class Driver < WebDriver::Driver
30
- include DriverExtensions::HasWebStorage
31
- include DriverExtensions::TakesScreenshot
32
-
33
- def browser
34
- :edge
27
+ def initialize(description:, timestamp:, stacktrace:)
28
+ @description = description
29
+ @timestamp = Time.at(timestamp / 1000)
30
+ @stacktrace = stacktrace
35
31
  end
36
- end # Driver
37
- end # EdgeHtml
32
+
33
+ end # ExceptionEvent
34
+ end # DevTools
38
35
  end # WebDriver
39
36
  end # Selenium
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
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
+ class DevTools
23
+ class MutationEvent
24
+
25
+ attr_accessor :element, :attribute_name, :current_value, :old_value
26
+
27
+ def initialize(element:, attribute_name:, current_value:, old_value:)
28
+ @element = element
29
+ @attribute_name = attribute_name
30
+ @current_value = current_value
31
+ @old_value = old_value
32
+ end
33
+
34
+ end # MutationEvent
35
+ end # DevTools
36
+ end # WebDriver
37
+ end # Selenium
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
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
+ class DevTools
23
+ class Request
24
+
25
+ attr_reader :url, :method, :headers
26
+
27
+ def initialize(devtools:, id:, url:, method:, headers:)
28
+ @devtools = devtools
29
+ @id = id
30
+ @url = url
31
+ @method = method
32
+ @headers = headers
33
+ end
34
+
35
+ def continue
36
+ @devtools.fetch.continue_request(request_id: @id)
37
+ end
38
+
39
+ def respond(code: 200, headers: {}, body: '')
40
+ @devtools.fetch.fulfill_request(
41
+ request_id: @id,
42
+ body: Base64.strict_encode64(body),
43
+ response_code: code,
44
+ response_headers: headers.map do |k, v|
45
+ {name: k, value: v}
46
+ end
47
+ )
48
+ end
49
+
50
+ def inspect
51
+ %(#<#{self.class.name} @method="#{method}" @url="#{url}")
52
+ end
53
+
54
+ end # Request
55
+ end # DevTools
56
+ end # WebDriver
57
+ end # Selenium
@@ -21,32 +21,12 @@ require 'net/http'
21
21
 
22
22
  module Selenium
23
23
  module WebDriver
24
- module EdgeHtml
25
- autoload :Driver, 'selenium/webdriver/edge_html/driver'
26
- autoload :Options, 'selenium/webdriver/edge_html/options'
27
- autoload :Service, 'selenium/webdriver/edge_html/service'
28
-
29
- def self.driver_path=(path)
30
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path=',
31
- 'Selenium::WebDriver::Edge::Service#driver_path=',
32
- id: :driver_path
33
- Selenium::WebDriver::Edge::Service.driver_path = path
34
- end
35
-
36
- def self.driver_path
37
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path',
38
- 'Selenium::WebDriver::Edge::Service#driver_path',
39
- id: :driver_path
40
- Selenium::WebDriver::Edge::Service.driver_path
41
- end
42
- end # EdgeHtml
43
-
44
- module EdgeChrome
45
- autoload :Bridge, 'selenium/webdriver/edge_chrome/bridge'
46
- autoload :Driver, 'selenium/webdriver/edge_chrome/driver'
47
- autoload :Profile, 'selenium/webdriver/edge_chrome/profile'
48
- autoload :Options, 'selenium/webdriver/edge_chrome/options'
49
- autoload :Service, 'selenium/webdriver/edge_chrome/service'
24
+ module Edge
25
+ autoload :Features, 'selenium/webdriver/edge/features'
26
+ autoload :Driver, 'selenium/webdriver/edge/driver'
27
+ autoload :Profile, 'selenium/webdriver/edge/profile'
28
+ autoload :Options, 'selenium/webdriver/edge/options'
29
+ autoload :Service, 'selenium/webdriver/edge/service'
50
30
 
51
31
  def self.path=(path)
52
32
  Platform.assert_executable path
@@ -56,8 +36,6 @@ module Selenium
56
36
  def self.path
57
37
  @path ||= nil
58
38
  end
59
- end # EdgeChrome
60
-
61
- Edge = EdgeHtml # Alias EdgeHtml as Edge for now
39
+ end # Edge
62
40
  end # WebDriver
63
41
  end # Selenium
@@ -21,18 +21,24 @@ require 'selenium/webdriver/chrome/driver'
21
21
 
22
22
  module Selenium
23
23
  module WebDriver
24
- module EdgeChrome
24
+ module Edge
25
25
 
26
26
  #
27
- # Driver implementation for EdgeChrome.
27
+ # Driver implementation for Microsoft Edge.
28
28
  # @api private
29
29
  #
30
30
 
31
31
  class Driver < Selenium::WebDriver::Chrome::Driver
32
32
  def browser
33
- :edge_chrome
33
+ :edge
34
+ end
35
+
36
+ private
37
+
38
+ def devtools_address
39
+ "http://#{capabilities['ms:edgeOptions']['debuggerAddress']}"
34
40
  end
35
41
  end # Driver
36
- end # EdgeChrome
42
+ end # Edge
37
43
  end # WebDriver
38
44
  end # Selenium
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
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
+ require 'selenium/webdriver/chrome/features'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ module Edge
25
+ module Features
26
+
27
+ include WebDriver::Chrome::Features
28
+
29
+ EDGE_COMMANDS = {
30
+ send_command: [:post, 'session/:session_id/ms/cdp/execute']
31
+ }.freeze
32
+
33
+ def commands(command)
34
+ EDGE_COMMANDS[command] || Chrome::Features::CHROME_COMMANDS[command] || self.class::COMMANDS[command]
35
+ end
36
+ end # Bridge
37
+ end # Edge
38
+ end # WebDriver
39
+ end # Selenium