selenium-webdriver 3.142.7 → 4.3.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 (157) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +432 -5
  3. data/Gemfile +3 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +2 -0
  6. data/README.md +4 -5
  7. data/lib/selenium/server.rb +75 -64
  8. data/lib/selenium/webdriver/atoms/findElements.js +122 -0
  9. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  10. data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
  11. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  12. data/lib/selenium/webdriver/bidi/session.rb +38 -0
  13. data/lib/selenium/webdriver/bidi.rb +55 -0
  14. data/lib/selenium/webdriver/chrome/driver.rb +26 -83
  15. data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +55 -12
  16. data/lib/selenium/webdriver/chrome/options.rb +138 -67
  17. data/lib/selenium/webdriver/chrome/profile.rb +6 -3
  18. data/lib/selenium/webdriver/chrome/service.rb +8 -15
  19. data/lib/selenium/webdriver/chrome.rb +5 -18
  20. data/lib/selenium/webdriver/common/action_builder.rb +171 -236
  21. data/lib/selenium/webdriver/common/driver.rb +76 -29
  22. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
  23. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_bidi.rb} +10 -8
  26. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +87 -0
  27. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +38 -0
  28. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +44 -0
  29. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +43 -0
  30. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
  31. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  32. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
  33. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_logs.rb} +4 -4
  34. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
  35. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  36. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
  38. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
  39. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  40. data/lib/selenium/webdriver/common/element.rb +83 -23
  41. data/lib/selenium/webdriver/common/error.rb +32 -196
  42. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  43. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -22
  44. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  45. data/lib/selenium/webdriver/common/interactions/key_actions.rb +10 -6
  46. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  47. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  48. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  49. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +68 -78
  50. data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
  51. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  52. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  53. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  54. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  55. data/lib/selenium/webdriver/common/interactions/scroll.rb +57 -0
  56. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  57. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  58. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  59. data/lib/selenium/webdriver/common/{w3c_manager.rb → interactions/wheel_input.rb} +14 -17
  60. data/lib/selenium/webdriver/common/keys.rb +1 -0
  61. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  62. data/lib/selenium/webdriver/common/logger.rb +50 -15
  63. data/lib/selenium/webdriver/common/manager.rb +11 -38
  64. data/lib/selenium/webdriver/common/options.rb +147 -23
  65. data/lib/selenium/webdriver/common/platform.rb +10 -5
  66. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  67. data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
  68. data/lib/selenium/webdriver/common/proxy.rb +6 -3
  69. data/lib/selenium/webdriver/common/search_context.rb +7 -9
  70. data/lib/selenium/webdriver/common/service.rb +17 -125
  71. data/lib/selenium/webdriver/common/service_manager.rb +150 -0
  72. data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
  73. data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
  74. data/lib/selenium/webdriver/common/socket_poller.rb +3 -3
  75. data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
  76. data/lib/selenium/webdriver/common/target_locator.rb +32 -4
  77. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  78. data/lib/selenium/webdriver/common/wait.rb +1 -1
  79. data/lib/selenium/webdriver/common/websocket_connection.rb +149 -0
  80. data/lib/selenium/webdriver/common/window.rb +0 -4
  81. data/lib/selenium/webdriver/common/zipper.rb +3 -9
  82. data/lib/selenium/webdriver/common.rb +35 -18
  83. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  84. data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
  85. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  86. data/lib/selenium/webdriver/devtools/pinned_script.rb +59 -0
  87. data/lib/selenium/webdriver/devtools/request.rb +67 -0
  88. data/lib/selenium/webdriver/devtools/response.rb +66 -0
  89. data/lib/selenium/webdriver/devtools.rb +86 -0
  90. data/lib/selenium/webdriver/edge/driver.rb +7 -29
  91. data/lib/selenium/webdriver/edge/features.rb +45 -0
  92. data/lib/selenium/webdriver/edge/options.rb +11 -48
  93. data/lib/selenium/webdriver/edge/profile.rb +33 -0
  94. data/lib/selenium/webdriver/edge/service.rb +10 -26
  95. data/lib/selenium/webdriver/edge.rb +11 -14
  96. data/lib/selenium/webdriver/firefox/driver.rb +32 -19
  97. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  98. data/lib/selenium/webdriver/firefox/features.rb +63 -0
  99. data/lib/selenium/webdriver/firefox/options.rb +73 -50
  100. data/lib/selenium/webdriver/firefox/profile.rb +16 -70
  101. data/lib/selenium/webdriver/firefox/service.rb +5 -9
  102. data/lib/selenium/webdriver/firefox/util.rb +1 -1
  103. data/lib/selenium/webdriver/firefox.rb +17 -28
  104. data/lib/selenium/webdriver/ie/driver.rb +1 -47
  105. data/lib/selenium/webdriver/ie/options.rb +15 -46
  106. data/lib/selenium/webdriver/ie/service.rb +13 -15
  107. data/lib/selenium/webdriver/ie.rb +3 -16
  108. data/lib/selenium/webdriver/remote/bridge.rb +563 -86
  109. data/lib/selenium/webdriver/remote/capabilities.rb +159 -123
  110. data/lib/selenium/webdriver/remote/commands.rb +158 -0
  111. data/lib/selenium/webdriver/remote/driver.rb +22 -13
  112. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  113. data/lib/selenium/webdriver/remote/http/default.rb +22 -31
  114. data/lib/selenium/webdriver/remote/response.rb +18 -49
  115. data/lib/selenium/webdriver/remote.rb +15 -12
  116. data/lib/selenium/webdriver/safari/driver.rb +3 -31
  117. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
  118. data/lib/selenium/webdriver/safari/options.rb +10 -29
  119. data/lib/selenium/webdriver/safari/service.rb +4 -8
  120. data/lib/selenium/webdriver/safari.rb +13 -19
  121. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  122. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
  123. data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
  124. data/lib/selenium/webdriver/support/color.rb +9 -9
  125. data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
  126. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  127. data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +22 -19
  128. data/lib/selenium/webdriver/support/guards.rb +95 -0
  129. data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
  130. data/lib/selenium/webdriver/support/select.rb +3 -3
  131. data/lib/selenium/webdriver/support.rb +1 -0
  132. data/lib/selenium/webdriver/version.rb +1 -1
  133. data/lib/selenium/webdriver.rb +14 -13
  134. data/selenium-webdriver.gemspec +32 -13
  135. metadata +176 -69
  136. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  137. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  138. data/lib/selenium/webdriver/common/keyboard.rb +0 -70
  139. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  140. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  141. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  142. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  143. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  144. data/lib/selenium/webdriver/firefox/binary.rb +0 -187
  145. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
  146. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  147. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  148. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  149. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  150. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  151. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  152. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -60
  153. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  154. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  155. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  156. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  157. data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -0,0 +1,149 @@
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 'websocket'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ class WebSocketConnection
25
+ RESPONSE_WAIT_TIMEOUT = 30
26
+ RESPONSE_WAIT_INTERVAL = 0.1
27
+
28
+ def initialize(url:)
29
+ @callback_threads = ThreadGroup.new
30
+
31
+ @messages = []
32
+ @session_id = nil
33
+ @url = url
34
+
35
+ process_handshake
36
+ @socket_thread = attach_socket_listener
37
+ end
38
+
39
+ def close
40
+ @callback_threads.list.each(&:exit)
41
+ @socket_thread.exit
42
+ socket.close
43
+ end
44
+
45
+ def callbacks
46
+ @callbacks ||= Hash.new { |callbacks, event| callbacks[event] = [] }
47
+ end
48
+
49
+ def send_cmd(**payload)
50
+ id = next_id
51
+ data = payload.merge(id: id)
52
+ data = JSON.generate(data)
53
+ WebDriver.logger.debug "WebSocket -> #{data}"
54
+
55
+ out_frame = WebSocket::Frame::Outgoing::Client.new(version: ws.version, data: data, type: 'text')
56
+ socket.write(out_frame.to_s)
57
+
58
+ wait.until { @messages.find { |m| m['id'] == id } }
59
+ end
60
+
61
+ private
62
+
63
+ def process_handshake
64
+ socket.print(ws.to_s)
65
+ ws << socket.readpartial(1024)
66
+ end
67
+
68
+ def attach_socket_listener
69
+ Thread.new do
70
+ Thread.current.abort_on_exception = true
71
+ Thread.current.report_on_exception = false
72
+
73
+ until socket.eof?
74
+ incoming_frame << socket.readpartial(1024)
75
+
76
+ while (frame = incoming_frame.next)
77
+ message = process_frame(frame)
78
+ next unless message['method']
79
+
80
+ params = message['params']
81
+ callbacks[message['method']].each do |callback|
82
+ @callback_threads.add(callback_thread(params, &callback))
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def incoming_frame
90
+ @incoming_frame ||= WebSocket::Frame::Incoming::Client.new(version: ws.version)
91
+ end
92
+
93
+ def process_frame(frame)
94
+ message = frame.to_s
95
+
96
+ # Firefox will periodically fail on unparsable empty frame
97
+ return {} if message.empty?
98
+
99
+ message = JSON.parse(message)
100
+ @messages << message
101
+ WebDriver.logger.debug "WebSocket <- #{message}"
102
+
103
+ message
104
+ end
105
+
106
+ def callback_thread(params)
107
+ Thread.new do
108
+ Thread.current.abort_on_exception = true
109
+
110
+ # We might end up blocked forever when we have an error in event.
111
+ # For example, if network interception event raises error,
112
+ # the browser will keep waiting for the request to be proceeded
113
+ # before returning back to the original thread. In this case,
114
+ # we should at least print the error.
115
+ Thread.current.report_on_exception = true
116
+
117
+ yield params
118
+ end
119
+ end
120
+
121
+ def wait
122
+ @wait ||= Wait.new(timeout: RESPONSE_WAIT_TIMEOUT, interval: RESPONSE_WAIT_INTERVAL)
123
+ end
124
+
125
+ def socket
126
+ @socket ||= if URI(@url).scheme == 'wss'
127
+ socket = TCPSocket.new(ws.host, ws.port)
128
+ socket = OpenSSL::SSL::SSLSocket.new(socket, OpenSSL::SSL::SSLContext.new)
129
+ socket.sync_close = true
130
+ socket.connect
131
+
132
+ socket
133
+ else
134
+ TCPSocket.new(ws.host, ws.port)
135
+ end
136
+ end
137
+
138
+ def ws
139
+ @ws ||= WebSocket::Handshake::Client.new(url: @url)
140
+ end
141
+
142
+ def next_id
143
+ @id ||= 0
144
+ @id += 1
145
+ end
146
+
147
+ end # BiDi
148
+ end # WebDriver
149
+ end # Selenium
@@ -19,10 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- #
23
- # @api beta This API may be changed or removed in a future release.
24
- #
25
-
26
22
  class Window
27
23
  #
28
24
  # @api private
@@ -72,16 +72,10 @@ module Selenium
72
72
  private
73
73
 
74
74
  def with_tmp_zip(&blk)
75
- # can't use Tempfile here since it doesn't support File::BINARY mode on 1.8
76
- # can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
77
- tmp_dir = Dir.mktmpdir
78
- zip_path = File.join(tmp_dir, 'webdriver-zip')
79
-
80
- begin
75
+ # Don't use Tempfile since it lacks rb_file_s_rename permission on Windows.
76
+ Dir.mktmpdir do |tmp_dir|
77
+ zip_path = File.join(tmp_dir, 'webdriver-zip')
81
78
  Zip::File.open(zip_path, Zip::File::CREATE, &blk)
82
- ensure
83
- FileUtils.rm_rf tmp_dir
84
- FileUtils.rm_rf zip_path
85
79
  end
86
80
  end
87
81
 
@@ -23,15 +23,13 @@ require 'selenium/webdriver/common/proxy'
23
23
  require 'selenium/webdriver/common/log_entry'
24
24
  require 'selenium/webdriver/common/file_reaper'
25
25
  require 'selenium/webdriver/common/service'
26
+ require 'selenium/webdriver/common/service_manager'
26
27
  require 'selenium/webdriver/common/socket_lock'
27
28
  require 'selenium/webdriver/common/socket_poller'
28
29
  require 'selenium/webdriver/common/port_prober'
29
30
  require 'selenium/webdriver/common/zipper'
30
31
  require 'selenium/webdriver/common/wait'
31
32
  require 'selenium/webdriver/common/alert'
32
- require 'selenium/webdriver/common/mouse'
33
- require 'selenium/webdriver/common/keyboard'
34
- require 'selenium/webdriver/common/touch_screen'
35
33
  require 'selenium/webdriver/common/target_locator'
36
34
  require 'selenium/webdriver/common/navigation'
37
35
  require 'selenium/webdriver/common/timeouts'
@@ -39,39 +37,58 @@ require 'selenium/webdriver/common/window'
39
37
  require 'selenium/webdriver/common/logger'
40
38
  require 'selenium/webdriver/common/logs'
41
39
  require 'selenium/webdriver/common/manager'
42
- require 'selenium/webdriver/common/w3c_manager'
43
40
  require 'selenium/webdriver/common/search_context'
44
- require 'selenium/webdriver/common/action_builder'
41
+ require 'selenium/webdriver/common/interactions/interaction'
42
+ require 'selenium/webdriver/common/interactions/interactions'
43
+ require 'selenium/webdriver/common/interactions/pointer_event_properties'
44
+ require 'selenium/webdriver/common/interactions/pointer_cancel'
45
+ require 'selenium/webdriver/common/interactions/pointer_move'
46
+ require 'selenium/webdriver/common/interactions/pointer_press'
47
+ require 'selenium/webdriver/common/interactions/typing_interaction'
48
+ require 'selenium/webdriver/common/interactions/pause'
45
49
  require 'selenium/webdriver/common/interactions/key_actions'
46
50
  require 'selenium/webdriver/common/interactions/pointer_actions'
47
- require 'selenium/webdriver/common/w3c_action_builder'
48
- require 'selenium/webdriver/common/touch_action_builder'
51
+ require 'selenium/webdriver/common/interactions/input_device'
52
+ require 'selenium/webdriver/common/interactions/none_input'
53
+ require 'selenium/webdriver/common/interactions/key_input'
54
+ require 'selenium/webdriver/common/interactions/pointer_input'
55
+ require 'selenium/webdriver/common/interactions/scroll'
56
+ require 'selenium/webdriver/common/interactions/wheel_input'
57
+ require 'selenium/webdriver/common/interactions/scroll_origin'
58
+ require 'selenium/webdriver/common/interactions/wheel_actions'
59
+ require 'selenium/webdriver/common/action_builder'
49
60
  require 'selenium/webdriver/common/html5/shared_web_storage'
50
61
  require 'selenium/webdriver/common/html5/local_storage'
51
62
  require 'selenium/webdriver/common/html5/session_storage'
52
- require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
53
- require 'selenium/webdriver/common/driver_extensions/rotatable'
54
63
  require 'selenium/webdriver/common/driver_extensions/has_web_storage'
55
64
  require 'selenium/webdriver/common/driver_extensions/downloads_files'
56
65
  require 'selenium/webdriver/common/driver_extensions/has_location'
57
66
  require 'selenium/webdriver/common/driver_extensions/has_session_id'
58
- require 'selenium/webdriver/common/driver_extensions/has_touch_screen'
59
- require 'selenium/webdriver/common/driver_extensions/has_remote_status'
60
67
  require 'selenium/webdriver/common/driver_extensions/has_network_conditions'
61
68
  require 'selenium/webdriver/common/driver_extensions/has_network_connection'
69
+ require 'selenium/webdriver/common/driver_extensions/has_network_interception'
70
+ require 'selenium/webdriver/common/driver_extensions/has_apple_permissions'
62
71
  require 'selenium/webdriver/common/driver_extensions/has_permissions'
63
72
  require 'selenium/webdriver/common/driver_extensions/has_debugger'
73
+ require 'selenium/webdriver/common/driver_extensions/has_context'
74
+ require 'selenium/webdriver/common/driver_extensions/prints_page'
64
75
  require 'selenium/webdriver/common/driver_extensions/uploads_files'
76
+ require 'selenium/webdriver/common/driver_extensions/full_page_screenshot'
65
77
  require 'selenium/webdriver/common/driver_extensions/has_addons'
66
- require 'selenium/webdriver/common/interactions/interactions'
67
- require 'selenium/webdriver/common/interactions/input_device'
68
- require 'selenium/webdriver/common/interactions/interaction'
69
- require 'selenium/webdriver/common/interactions/none_input'
70
- require 'selenium/webdriver/common/interactions/key_input'
71
- require 'selenium/webdriver/common/interactions/pointer_input'
78
+ require 'selenium/webdriver/common/driver_extensions/has_bidi'
79
+ require 'selenium/webdriver/common/driver_extensions/has_devtools'
80
+ require 'selenium/webdriver/common/driver_extensions/has_authentication'
81
+ require 'selenium/webdriver/common/driver_extensions/has_logs'
82
+ require 'selenium/webdriver/common/driver_extensions/has_log_events'
83
+ require 'selenium/webdriver/common/driver_extensions/has_pinned_scripts'
84
+ require 'selenium/webdriver/common/driver_extensions/has_cdp'
85
+ require 'selenium/webdriver/common/driver_extensions/has_casting'
86
+ require 'selenium/webdriver/common/driver_extensions/has_launching'
72
87
  require 'selenium/webdriver/common/keys'
73
- require 'selenium/webdriver/common/bridge_helper'
74
88
  require 'selenium/webdriver/common/profile_helper'
75
89
  require 'selenium/webdriver/common/options'
90
+ require 'selenium/webdriver/common/takes_screenshot'
76
91
  require 'selenium/webdriver/common/driver'
77
92
  require 'selenium/webdriver/common/element'
93
+ require 'selenium/webdriver/common/shadow_root'
94
+ require 'selenium/webdriver/common/websocket_connection'
@@ -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
@@ -0,0 +1,36 @@
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 ExceptionEvent
24
+
25
+ attr_accessor :description, :timestamp, :stacktrace
26
+
27
+ def initialize(description:, timestamp:, stacktrace:)
28
+ @description = description
29
+ @timestamp = Time.at(timestamp / 1000)
30
+ @stacktrace = stacktrace
31
+ end
32
+
33
+ end # ExceptionEvent
34
+ end # DevTools
35
+ end # WebDriver
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,59 @@
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 PinnedScript
24
+
25
+ attr_accessor :key, :devtools_identifier, :script
26
+
27
+ def initialize(script)
28
+ @key = SecureRandom.alphanumeric
29
+ @script = script
30
+ end
31
+
32
+ #
33
+ # @api private
34
+ #
35
+
36
+ def callable
37
+ "function __webdriver_#{key}(arguments) { #{script} }"
38
+ end
39
+
40
+ #
41
+ # @api private
42
+ #
43
+
44
+ def to_json(*)
45
+ %{"return __webdriver_#{key}(arguments)"}
46
+ end
47
+
48
+ #
49
+ # @api private
50
+ #
51
+
52
+ def remove
53
+ "__webdriver_#{key} = undefined"
54
+ end
55
+
56
+ end # PinnedScript
57
+ end # DevTools
58
+ end # WebDriver
59
+ end # Selenium
@@ -0,0 +1,67 @@
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_accessor :url, :method, :headers, :post_data
26
+ attr_reader :id
27
+
28
+ #
29
+ # Creates request from DevTools message.
30
+ # @api private
31
+ #
32
+
33
+ def self.from(id, params)
34
+ new(
35
+ id: id,
36
+ url: params.dig('request', 'url'),
37
+ method: params.dig('request', 'method'),
38
+ headers: params.dig('request', 'headers').dup,
39
+ post_data: params.dig('request', 'postData')
40
+ )
41
+ end
42
+
43
+ def initialize(id:, url:, method:, headers:, post_data:)
44
+ @id = id
45
+ @url = url
46
+ @method = method
47
+ @headers = headers
48
+ @post_data = post_data
49
+ end
50
+
51
+ def ==(other)
52
+ self.class == other.class &&
53
+ id == other.id &&
54
+ url == other.url &&
55
+ method == other.method &&
56
+ headers == other.headers &&
57
+ post_data == other.post_data
58
+ end
59
+
60
+ def inspect
61
+ %(#<#{self.class.name} @id="#{id}" @method="#{method}" @url="#{url}")
62
+ end
63
+
64
+ end # Request
65
+ end # DevTools
66
+ end # WebDriver
67
+ end # Selenium
@@ -0,0 +1,66 @@
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 Response
24
+
25
+ attr_accessor :code, :body, :headers
26
+ attr_reader :id
27
+
28
+ #
29
+ # Creates response from DevTools message.
30
+ # @api private
31
+ #
32
+
33
+ def self.from(id, encoded_body, params)
34
+ new(
35
+ id: id,
36
+ code: params['responseStatusCode'],
37
+ body: (Base64.strict_decode64(encoded_body) if encoded_body),
38
+ headers: params.fetch('responseHeaders', []).each_with_object({}) do |header, hash|
39
+ hash[header['name']] = header['value']
40
+ end
41
+ )
42
+ end
43
+
44
+ def initialize(id:, code:, body:, headers:)
45
+ @id = id
46
+ @code = code
47
+ @body = body
48
+ @headers = headers
49
+ end
50
+
51
+ def ==(other)
52
+ self.class == other.class &&
53
+ id == other.id &&
54
+ code == other.code &&
55
+ body == other.body &&
56
+ headers == other.headers
57
+ end
58
+
59
+ def inspect
60
+ %(#<#{self.class.name} @id="#{id}" @code="#{code}")
61
+ end
62
+
63
+ end # Response
64
+ end # DevTools
65
+ end # WebDriver
66
+ end # Selenium
@@ -0,0 +1,86 @@
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 :PinnedScript, 'selenium/webdriver/devtools/pinned_script'
27
+ autoload :Request, 'selenium/webdriver/devtools/request'
28
+ autoload :Response, 'selenium/webdriver/devtools/response'
29
+
30
+ def initialize(url:)
31
+ @ws = WebSocketConnection.new(url: url)
32
+ @session_id = nil
33
+ start_session
34
+ end
35
+
36
+ def close
37
+ @ws.close
38
+ end
39
+
40
+ def callbacks
41
+ @ws.callbacks
42
+ end
43
+
44
+ def send_cmd(method, **params)
45
+ data = {method: method, params: params.compact}
46
+ data[:sessionId] = @session_id if @session_id
47
+ message = @ws.send_cmd(**data)
48
+ raise Error::WebDriverError, error_message(message['error']) if message['error']
49
+
50
+ message
51
+ end
52
+
53
+ def method_missing(method, *_args)
54
+ desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
55
+ return unless Object.const_defined?(desired_class)
56
+
57
+ self.class.class_eval do
58
+ define_method(method) do
59
+ Object.const_get(desired_class).new(self)
60
+ end
61
+ end
62
+
63
+ send(method)
64
+ end
65
+
66
+ def respond_to_missing?(method, *_args)
67
+ desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
68
+ Object.const_defined?(desired_class)
69
+ end
70
+
71
+ private
72
+
73
+ def start_session
74
+ targets = target.get_targets.dig('result', 'targetInfos')
75
+ page_target = targets.find { |target| target['type'] == 'page' }
76
+ session = target.attach_to_target(target_id: page_target['targetId'], flatten: true)
77
+ @session_id = session.dig('result', 'sessionId')
78
+ end
79
+
80
+ def error_message(error)
81
+ [error['code'], error['message'], error['data']].join(': ')
82
+ end
83
+
84
+ end # DevTools
85
+ end # WebDriver
86
+ end # Selenium