puppeteer-ruby 0.0.3 → 0.0.8
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +30 -0
- data/.github/stale.yml +16 -0
- data/.rubocop.yml +4 -5
- data/README.md +4 -1
- data/docs/Puppeteer.html +2020 -0
- data/docs/Puppeteer/AsyncAwaitBehavior.html +105 -0
- data/docs/Puppeteer/Browser.html +2150 -0
- data/docs/Puppeteer/BrowserContext.html +809 -0
- data/docs/Puppeteer/BrowserFetcher.html +214 -0
- data/docs/Puppeteer/BrowserRunner.html +914 -0
- data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +477 -0
- data/docs/Puppeteer/CDPSession.html +813 -0
- data/docs/Puppeteer/CDPSession/Error.html +124 -0
- data/docs/Puppeteer/ConcurrentRubyUtils.html +430 -0
- data/docs/Puppeteer/Connection.html +960 -0
- data/docs/Puppeteer/Connection/MessageCallback.html +434 -0
- data/docs/Puppeteer/Connection/ProtocolError.html +216 -0
- data/docs/Puppeteer/Connection/RequestDebugPrinter.html +217 -0
- data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +244 -0
- data/docs/Puppeteer/ConsoleMessage.html +565 -0
- data/docs/Puppeteer/ConsoleMessage/Location.html +433 -0
- data/docs/Puppeteer/DOMWorld.html +2219 -0
- data/docs/Puppeteer/DOMWorld/DetachedError.html +124 -0
- data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +124 -0
- data/docs/Puppeteer/DebugPrint.html +233 -0
- data/docs/Puppeteer/Device.html +470 -0
- data/docs/Puppeteer/Devices.html +139 -0
- data/docs/Puppeteer/ElementHandle.html +2224 -0
- data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +206 -0
- data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +206 -0
- data/docs/Puppeteer/ElementHandle/Point.html +481 -0
- data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +124 -0
- data/docs/Puppeteer/EmulationManager.html +454 -0
- data/docs/Puppeteer/EventCallbackable.html +433 -0
- data/docs/Puppeteer/EventCallbackable/EventListeners.html +435 -0
- data/docs/Puppeteer/ExecutionContext.html +998 -0
- data/docs/Puppeteer/ExecutionContext/EvaluationError.html +124 -0
- data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +357 -0
- data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +389 -0
- data/docs/Puppeteer/FileChooser.html +455 -0
- data/docs/Puppeteer/Frame.html +3677 -0
- data/docs/Puppeteer/FrameManager.html +2414 -0
- data/docs/Puppeteer/FrameManager/NavigationError.html +124 -0
- data/docs/Puppeteer/IfPresent.html +222 -0
- data/docs/Puppeteer/JSHandle.html +1352 -0
- data/docs/Puppeteer/Keyboard.html +1557 -0
- data/docs/Puppeteer/Keyboard/KeyDefinition.html +831 -0
- data/docs/Puppeteer/Keyboard/KeyDescription.html +603 -0
- data/docs/Puppeteer/Launcher.html +237 -0
- data/docs/Puppeteer/Launcher/Base.html +385 -0
- data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +124 -0
- data/docs/Puppeteer/Launcher/BrowserOptions.html +441 -0
- data/docs/Puppeteer/Launcher/Chrome.html +669 -0
- data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +382 -0
- data/docs/Puppeteer/Launcher/ChromeArgOptions.html +531 -0
- data/docs/Puppeteer/Launcher/LaunchOptions.html +893 -0
- data/docs/Puppeteer/LifecycleWatcher.html +834 -0
- data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +363 -0
- data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +206 -0
- data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +124 -0
- data/docs/Puppeteer/Mouse.html +1105 -0
- data/docs/Puppeteer/Mouse/Button.html +136 -0
- data/docs/Puppeteer/NetworkManager.html +901 -0
- data/docs/Puppeteer/NetworkManager/Credentials.html +385 -0
- data/docs/Puppeteer/Page.html +5970 -0
- data/docs/Puppeteer/Page/FileChooserTimeoutError.html +206 -0
- data/docs/Puppeteer/Page/ScreenshotOptions.html +845 -0
- data/docs/Puppeteer/Page/ScriptTag.html +555 -0
- data/docs/Puppeteer/Page/StyleTag.html +448 -0
- data/docs/Puppeteer/Page/TargetCrashedError.html +124 -0
- data/docs/Puppeteer/RemoteObject.html +1016 -0
- data/docs/Puppeteer/Target.html +1384 -0
- data/docs/Puppeteer/Target/InitializeFailure.html +124 -0
- data/docs/Puppeteer/Target/TargetInfo.html +729 -0
- data/docs/Puppeteer/TimeoutError.html +135 -0
- data/docs/Puppeteer/TimeoutSettings.html +496 -0
- data/docs/Puppeteer/TouchScreen.html +464 -0
- data/docs/Puppeteer/Viewport.html +757 -0
- data/docs/Puppeteer/WaitTask.html +637 -0
- data/docs/Puppeteer/WaitTask/TerminatedError.html +124 -0
- data/docs/Puppeteer/WaitTask/TimeoutError.html +206 -0
- data/docs/Puppeteer/WebSocket.html +673 -0
- data/docs/Puppeteer/WebSocket/DriverImpl.html +412 -0
- data/docs/Puppeteer/WebSocketTransport.html +600 -0
- data/docs/Puppeteer/WebSocktTransportError.html +124 -0
- data/docs/_index.html +809 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +496 -0
- data/docs/file.README.html +123 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +123 -0
- data/docs/js/app.js +314 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +3979 -0
- data/docs/top-level-namespace.html +126 -0
- data/lib/puppeteer.rb +16 -8
- data/lib/puppeteer/async_await_behavior.rb +6 -0
- data/lib/puppeteer/browser.rb +21 -1
- data/lib/puppeteer/browser_runner.rb +1 -1
- data/lib/puppeteer/cdp_session.rb +33 -11
- data/lib/puppeteer/connection.rb +1 -1
- data/lib/puppeteer/dom_world.rb +142 -121
- data/lib/puppeteer/element_handle.rb +223 -181
- data/lib/puppeteer/execution_context.rb +41 -17
- data/lib/puppeteer/file_chooser.rb +29 -0
- data/lib/puppeteer/frame.rb +23 -15
- data/lib/puppeteer/frame_manager.rb +7 -9
- data/lib/puppeteer/js_handle.rb +3 -3
- data/lib/puppeteer/keyboard.rb +1 -1
- data/lib/puppeteer/keyboard/us_keyboard_layout.rb +4 -4
- data/lib/puppeteer/launcher.rb +0 -1
- data/lib/puppeteer/launcher/chrome.rb +48 -2
- data/lib/puppeteer/lifecycle_watcher.rb +9 -4
- data/lib/puppeteer/mouse.rb +10 -7
- data/lib/puppeteer/page.rb +134 -70
- data/lib/puppeteer/remote_object.rb +11 -1
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer/wait_task.rb +183 -1
- data/puppeteer-ruby.gemspec +4 -1
- metadata +143 -4
|
@@ -16,6 +16,11 @@ class Puppeteer::ExecutionContext
|
|
|
16
16
|
|
|
17
17
|
attr_reader :client, :world
|
|
18
18
|
|
|
19
|
+
# only used in DomWorld#delete_context
|
|
20
|
+
def _context_id
|
|
21
|
+
@context_id
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
# @return [Puppeteer::Frame]
|
|
20
25
|
def frame
|
|
21
26
|
if_present(@world) do |world|
|
|
@@ -117,7 +122,7 @@ class Puppeteer::ExecutionContext
|
|
|
117
122
|
remote_object = Puppeteer::RemoteObject.new(result['result'])
|
|
118
123
|
|
|
119
124
|
if exception_details
|
|
120
|
-
raise EvaluationError.new("Evaluation failed: #{
|
|
125
|
+
raise EvaluationError.new("Evaluation failed: #{exception_details}")
|
|
121
126
|
end
|
|
122
127
|
|
|
123
128
|
if @return_by_value
|
|
@@ -211,20 +216,39 @@ class Puppeteer::ExecutionContext
|
|
|
211
216
|
# return createJSHandle(this, response.objects);
|
|
212
217
|
# }
|
|
213
218
|
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
#
|
|
228
|
-
#
|
|
229
|
-
|
|
219
|
+
# @param backend_node_id [Integer]
|
|
220
|
+
# @return [Puppeteer::ElementHandle]
|
|
221
|
+
def adopt_backend_node_id(backend_node_id)
|
|
222
|
+
response = @client.send_message('DOM.resolveNode',
|
|
223
|
+
backendNodeId: backend_node_id,
|
|
224
|
+
executionContextId: @context_id,
|
|
225
|
+
)
|
|
226
|
+
Puppeteer::JSHandle.create(
|
|
227
|
+
context: self,
|
|
228
|
+
remote_object: Puppeteer::RemoteObject.new(response["object"]),
|
|
229
|
+
)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# @param element_handle [Puppeteer::ElementHandle]
|
|
233
|
+
# @return [Puppeteer::ElementHandle]
|
|
234
|
+
def adopt_element_handle(element_handle)
|
|
235
|
+
if element_handle.execution_context == self
|
|
236
|
+
raise ArgumentError.new('Cannot adopt handle that already belongs to this execution context')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
unless @world
|
|
240
|
+
raise 'Cannot adopt handle without DOMWorld'
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
node_info = element_handle.remote_object.node_info(@client)
|
|
244
|
+
response = @client.send_message('DOM.resolveNode',
|
|
245
|
+
backendNodeId: node_info["node"]["backendNodeId"],
|
|
246
|
+
executionContextId: @context_id,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
Puppeteer::JSHandle.create(
|
|
250
|
+
context: self,
|
|
251
|
+
remote_object: Puppeteer::RemoteObject.new(response["object"]),
|
|
252
|
+
)
|
|
253
|
+
end
|
|
230
254
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Puppeteer::FileChooser
|
|
2
|
+
# @param element [Puppeteer::ElementHandle]
|
|
3
|
+
# @param event [Hash]
|
|
4
|
+
def initialize(element, event)
|
|
5
|
+
@element = element
|
|
6
|
+
@multiple = event['mode'] != 'selectSingle'
|
|
7
|
+
@handled = false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def multiple?
|
|
11
|
+
@multiple
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @param file_paths [Array<String>]
|
|
15
|
+
def accept(file_paths)
|
|
16
|
+
if @handled
|
|
17
|
+
raise 'Cannot accept FileChooser which is already handled!'
|
|
18
|
+
end
|
|
19
|
+
@handled = true
|
|
20
|
+
@element.upload_file(*file_paths)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def cancel
|
|
24
|
+
if @handled
|
|
25
|
+
raise 'Cannot cancel FileChooser which is already handled!'
|
|
26
|
+
end
|
|
27
|
+
@handled = true
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/puppeteer/frame.rb
CHANGED
|
@@ -143,8 +143,10 @@ class Puppeteer::Frame
|
|
|
143
143
|
@main_world.add_style_tag(style_tag)
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
# @param
|
|
147
|
-
# @param
|
|
146
|
+
# @param selector [String]
|
|
147
|
+
# @param delay [Number]
|
|
148
|
+
# @param button [String] "left"|"right"|"middle"
|
|
149
|
+
# @param click_count [Number]
|
|
148
150
|
def click(selector, delay: nil, button: nil, click_count: nil)
|
|
149
151
|
@secondary_world.click(selector, delay: delay, button: button, click_count: click_count)
|
|
150
152
|
end
|
|
@@ -171,11 +173,11 @@ class Puppeteer::Frame
|
|
|
171
173
|
@secondary_world.tap(selector)
|
|
172
174
|
end
|
|
173
175
|
|
|
174
|
-
# @param
|
|
175
|
-
# @param
|
|
176
|
-
# @param
|
|
177
|
-
def
|
|
178
|
-
@main_world.
|
|
176
|
+
# @param selector [String]
|
|
177
|
+
# @param text [String]
|
|
178
|
+
# @param delay [Number]
|
|
179
|
+
def type_text(selector, text, delay: nil)
|
|
180
|
+
@main_world.type_text(selector, text, delay: delay)
|
|
179
181
|
end
|
|
180
182
|
|
|
181
183
|
# /**
|
|
@@ -200,9 +202,10 @@ class Puppeteer::Frame
|
|
|
200
202
|
# return Promise.reject(new Error('Unsupported target type: ' + (typeof selectorOrFunctionOrTimeout)));
|
|
201
203
|
# }
|
|
202
204
|
|
|
203
|
-
# @param
|
|
204
|
-
# @param
|
|
205
|
-
# @
|
|
205
|
+
# @param selector [String]
|
|
206
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
207
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
208
|
+
# @param timeout [Integer]
|
|
206
209
|
def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
|
|
207
210
|
handle = @secondary_world.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
|
|
208
211
|
if !handle
|
|
@@ -214,9 +217,10 @@ class Puppeteer::Frame
|
|
|
214
217
|
result
|
|
215
218
|
end
|
|
216
219
|
|
|
217
|
-
# @param
|
|
218
|
-
# @param
|
|
219
|
-
# @
|
|
220
|
+
# @param xpath [String]
|
|
221
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
222
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
223
|
+
# @param timeout [Integer]
|
|
220
224
|
def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
|
|
221
225
|
handle = @secondary_world.wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
|
|
222
226
|
if !handle
|
|
@@ -246,6 +250,10 @@ class Puppeteer::Frame
|
|
|
246
250
|
# TODO(lushnikov): remove this once requestInterception has loaderId exposed.
|
|
247
251
|
@navigation_url = frame_payload['url']
|
|
248
252
|
@url = frame_payload['url']
|
|
253
|
+
|
|
254
|
+
# Ensure loaderId updated.
|
|
255
|
+
# The order of [Page.lifecycleEvent name="init"] and [Page.frameNavigated] is random... for some reason...
|
|
256
|
+
@loader_id = frame_payload['loaderId']
|
|
249
257
|
end
|
|
250
258
|
|
|
251
259
|
# @param url [String]
|
|
@@ -268,8 +276,8 @@ class Puppeteer::Frame
|
|
|
268
276
|
|
|
269
277
|
def detach
|
|
270
278
|
@detached = true
|
|
271
|
-
|
|
272
|
-
|
|
279
|
+
@main_world.detach
|
|
280
|
+
@secondary_world.detach
|
|
273
281
|
if @parent_frame
|
|
274
282
|
@parent_frame._child_frames.delete(self)
|
|
275
283
|
end
|
|
@@ -206,12 +206,12 @@ class Puppeteer::FrameManager
|
|
|
206
206
|
# @param {string} frameId
|
|
207
207
|
# @param {?string} parentFrameId
|
|
208
208
|
def handle_frame_attached(frame_id, parent_frame_id)
|
|
209
|
-
return if @frames.has_key?
|
|
209
|
+
return if @frames.has_key?(frame_id)
|
|
210
210
|
if !parent_frame_id
|
|
211
211
|
raise ArgymentError.new('parent_frame_id must not be nil')
|
|
212
212
|
end
|
|
213
213
|
parent_frame = @frames[parent_frame_id]
|
|
214
|
-
frame = Frame.new(self, @client, parent_frame, frame_id)
|
|
214
|
+
frame = Puppeteer::Frame.new(self, @client, parent_frame, frame_id)
|
|
215
215
|
@frames[frame_id] = frame
|
|
216
216
|
|
|
217
217
|
emit_event 'Events.FrameManager.FrameAttached', frame
|
|
@@ -219,7 +219,7 @@ class Puppeteer::FrameManager
|
|
|
219
219
|
|
|
220
220
|
# @param frame_payload [Hash]
|
|
221
221
|
def handle_frame_navigated(frame_payload)
|
|
222
|
-
is_main_frame = !frame_payload['
|
|
222
|
+
is_main_frame = !frame_payload['parentId']
|
|
223
223
|
frame =
|
|
224
224
|
if is_main_frame
|
|
225
225
|
@main_frame
|
|
@@ -285,8 +285,6 @@ class Puppeteer::FrameManager
|
|
|
285
285
|
frame.navigated_within_document(url)
|
|
286
286
|
emit_event 'Events.FrameManager.FrameNavigatedWithinDocument', frame
|
|
287
287
|
emit_event 'Events.FrameManager.FrameNavigated', frame
|
|
288
|
-
handle_frame_manager_frame_navigated_within_document(frame)
|
|
289
|
-
handle_frame_manager_frame_navigated(frame)
|
|
290
288
|
end
|
|
291
289
|
|
|
292
290
|
# @param frame_id [String]
|
|
@@ -332,12 +330,12 @@ class Puppeteer::FrameManager
|
|
|
332
330
|
@context_id_to_context.delete(execution_context_id)
|
|
333
331
|
@context_id_created.delete(execution_context_id)
|
|
334
332
|
if context.world
|
|
335
|
-
context.world.
|
|
333
|
+
context.world.delete_context(execution_context_id)
|
|
336
334
|
end
|
|
337
335
|
end
|
|
338
336
|
|
|
339
337
|
def handle_execution_contexts_cleared
|
|
340
|
-
#
|
|
338
|
+
# executionContextsCleared is often notified after executionContextCreated.
|
|
341
339
|
# D, [2020-04-06T01:47:03.101227 #13823] DEBUG -- : RECV << {"method"=>"Runtime.executionContextCreated", "params"=>{"context"=>{"id"=>5, "origin"=>"https://github.com", "name"=>"", "auxData"=>{"isDefault"=>true, "type"=>"default", "frameId"=>"71C347B70848B89DDDEFAA8AB5B0BC92"}}}, "sessionId"=>"53F088EED260C28001D26A019F95D9E3"}
|
|
342
340
|
# D, [2020-04-06T01:47:03.101439 #13823] DEBUG -- : RECV << {"method"=>"Page.frameNavigated", "params"=>{"frame"=>{"id"=>"71C347B70848B89DDDEFAA8AB5B0BC92", "loaderId"=>"80338225D035AC96BAE8F6D4E81C7D51", "url"=>"https://github.com/search?q=puppeteer", "securityOrigin"=>"https://github.com", "mimeType"=>"text/html"}}, "sessionId"=>"53F088EED260C28001D26A019F95D9E3"}
|
|
343
341
|
# D, [2020-04-06T01:47:03.101325 #13823] DEBUG -- : RECV << {"method"=>"Target.targetInfoChanged", "params"=>{"targetInfo"=>{"targetId"=>"71C347B70848B89DDDEFAA8AB5B0BC92", "type"=>"page", "title"=>"https://github.com/search?q=puppeteer", "url"=>"https://github.com/search?q=puppeteer", "attached"=>true, "browserContextId"=>"AF37BC660284CE1552B4ECB147BE9305"}}}
|
|
@@ -346,9 +344,9 @@ class Puppeteer::FrameManager
|
|
|
346
344
|
# To avoid the problem, just skip recent created ids.
|
|
347
345
|
now = Time.now
|
|
348
346
|
context_ids_to_skip = @context_id_created.select { |k, v| now - v < 1 }.keys
|
|
349
|
-
@context_id_to_context.reject { |k, v| context_ids_to_skip.include?(k) }.
|
|
347
|
+
@context_id_to_context.reject { |k, v| context_ids_to_skip.include?(k) }.each do |execution_context_id, context|
|
|
350
348
|
if context.world
|
|
351
|
-
context.world.
|
|
349
|
+
context.world.delete_context(execution_context_id)
|
|
352
350
|
end
|
|
353
351
|
end
|
|
354
352
|
@context_id_to_context.select! { |k, v| context_ids_to_skip.include?(k) }
|
data/lib/puppeteer/js_handle.rb
CHANGED
|
@@ -89,8 +89,9 @@ class Puppeteer::JSHandle
|
|
|
89
89
|
response['result'].each_with_object({}) do |prop, h|
|
|
90
90
|
next unless prop['enumerable']
|
|
91
91
|
h[prop['name']] = Puppeteer::JSHandle.create(
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
context: @context,
|
|
93
|
+
remote_object: Puppeteer::RemoteObject.new(prop['value']),
|
|
94
|
+
)
|
|
94
95
|
end
|
|
95
96
|
end
|
|
96
97
|
|
|
@@ -116,7 +117,6 @@ class Puppeteer::JSHandle
|
|
|
116
117
|
nil
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
# @return [Future]
|
|
120
120
|
def dispose
|
|
121
121
|
return if @disposed
|
|
122
122
|
|
data/lib/puppeteer/keyboard.rb
CHANGED
|
@@ -41,10 +41,10 @@ class Puppeteer::Keyboard
|
|
|
41
41
|
'Backspace': KeyDefinition.new({ 'keyCode': 8, 'code': 'Backspace', 'key': 'Backspace' }),
|
|
42
42
|
'Tab': KeyDefinition.new({ 'keyCode': 9, 'code': 'Tab', 'key': 'Tab' }),
|
|
43
43
|
'Numpad5': KeyDefinition.new({ 'keyCode': 12, 'shiftKeyCode': 101, 'key': 'Clear', 'code': 'Numpad5', 'shiftKey': '5', 'location': 3 }),
|
|
44
|
-
'NumpadEnter': KeyDefinition.new({ 'keyCode': 13, 'code': 'NumpadEnter', 'key': 'Enter', 'text':
|
|
45
|
-
'Enter': KeyDefinition.new({ 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text':
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
'NumpadEnter': KeyDefinition.new({ 'keyCode': 13, 'code': 'NumpadEnter', 'key': 'Enter', 'text': "\r", 'location': 3 }),
|
|
45
|
+
'Enter': KeyDefinition.new({ 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': "\r" }),
|
|
46
|
+
"\r": KeyDefinition.new({ 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': "\r" }),
|
|
47
|
+
"\n": KeyDefinition.new({ 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': "\r" }),
|
|
48
48
|
'ShiftLeft': KeyDefinition.new({ 'keyCode': 16, 'code': 'ShiftLeft', 'key': 'Shift', 'location': 1 }),
|
|
49
49
|
'ShiftRight': KeyDefinition.new({ 'keyCode': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2 }),
|
|
50
50
|
'ControlLeft': KeyDefinition.new({ 'keyCode': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1 }),
|
data/lib/puppeteer/launcher.rb
CHANGED
|
@@ -149,8 +149,54 @@ module Puppeteer::Launcher
|
|
|
149
149
|
|
|
150
150
|
# @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
|
151
151
|
# @return {!Promise<!Browser>}
|
|
152
|
-
def connect(options)
|
|
153
|
-
|
|
152
|
+
def connect(options = {})
|
|
153
|
+
@browser_options = BrowserOptions.new(options)
|
|
154
|
+
browser_ws_endpoint = options[:browser_ws_endpoint]
|
|
155
|
+
browser_url = options[:browser_url]
|
|
156
|
+
transport = options[:transport]
|
|
157
|
+
|
|
158
|
+
connection =
|
|
159
|
+
if browser_ws_endpoint && browser_url.nil? && transport.nil?
|
|
160
|
+
connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
|
161
|
+
elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
|
|
162
|
+
connect_with_browser_url(browser_url)
|
|
163
|
+
elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
|
|
164
|
+
connect_with_transport(transport)
|
|
165
|
+
else
|
|
166
|
+
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
result = connection.send_message('Target.getBrowserContexts')
|
|
170
|
+
browser_context_ids = result['browserContextIds']
|
|
171
|
+
|
|
172
|
+
Puppeteer::Browser.create(
|
|
173
|
+
connection: connection,
|
|
174
|
+
context_ids: browser_context_ids,
|
|
175
|
+
ignore_https_errors: @browser_options.ignore_https_errors?,
|
|
176
|
+
default_viewport: @browser_options.default_viewport,
|
|
177
|
+
process: nil,
|
|
178
|
+
close_callback: -> { connection.send_message('Browser.close') },
|
|
179
|
+
)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @return [Puppeteer::Connection]
|
|
183
|
+
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
|
184
|
+
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
|
|
185
|
+
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @return [Puppeteer::Connection]
|
|
189
|
+
private def connect_with_browser_url(browser_url)
|
|
190
|
+
raise NotImplementedError.new('Puppeteer#connect with browserUrl is not implemented yet.')
|
|
191
|
+
# const connectionURL = await getWSEndpoint(browserURL);
|
|
192
|
+
# const connectionTransport = await WebSocketTransport.create(
|
|
193
|
+
# connectionURL
|
|
194
|
+
# );
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# @return [Puppeteer::Connection]
|
|
198
|
+
private def connect_with_transport(transport)
|
|
199
|
+
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
|
|
154
200
|
end
|
|
155
201
|
|
|
156
202
|
# @return {string}
|
|
@@ -50,6 +50,11 @@ class Puppeteer::LifecycleWatcher
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
class FrameDetachedError < StandardError
|
|
54
|
+
def initialize
|
|
55
|
+
super('Navigating frame was detached')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
53
58
|
class TerminatedError < StandardError; end
|
|
54
59
|
|
|
55
60
|
# * @param {!Puppeteer.FrameManager} frameManager
|
|
@@ -68,7 +73,7 @@ class Puppeteer::LifecycleWatcher
|
|
|
68
73
|
terminate(TerminatedError.new('Navigation failed because browser has disconnected!'))
|
|
69
74
|
end
|
|
70
75
|
@listener_ids['frame_manager'] = [
|
|
71
|
-
@frame_manager.add_event_listener('Events.FrameManager.LifecycleEvent') do |
|
|
76
|
+
@frame_manager.add_event_listener('Events.FrameManager.LifecycleEvent') do |_|
|
|
72
77
|
check_lifecycle_complete
|
|
73
78
|
end,
|
|
74
79
|
@frame_manager.add_event_listener('Events.FrameManager.FrameNavigatedWithinDocument', &method(:navigated_within_document)),
|
|
@@ -92,7 +97,7 @@ class Puppeteer::LifecycleWatcher
|
|
|
92
97
|
# @param frame [Puppeteer::Frame]
|
|
93
98
|
def handle_frame_detached(frame)
|
|
94
99
|
if @frame == frame
|
|
95
|
-
|
|
100
|
+
@termination_promise.reject(FrameDetachedError.new)
|
|
96
101
|
return
|
|
97
102
|
end
|
|
98
103
|
check_lifecycle_complete
|
|
@@ -144,10 +149,10 @@ class Puppeteer::LifecycleWatcher
|
|
|
144
149
|
if @frame.loader_id == @initial_loader_id && !@has_same_document_navigation
|
|
145
150
|
return
|
|
146
151
|
end
|
|
147
|
-
if @has_same_document_navigation
|
|
152
|
+
if @has_same_document_navigation && @same_document_navigation_promise.pending?
|
|
148
153
|
@same_document_navigation_promise.fulfill(true)
|
|
149
154
|
end
|
|
150
|
-
if @frame.loader_id != @initial_loader_id
|
|
155
|
+
if @frame.loader_id != @initial_loader_id && @new_document_navigation_promise.pending?
|
|
151
156
|
@new_document_navigation_promise.fulfill(true)
|
|
152
157
|
end
|
|
153
158
|
end
|
data/lib/puppeteer/mouse.rb
CHANGED
|
@@ -37,8 +37,8 @@ class Puppeteer::Mouse
|
|
|
37
37
|
@client.send_message('Input.dispatchMouseEvent',
|
|
38
38
|
type: 'mouseMoved',
|
|
39
39
|
button: @button,
|
|
40
|
-
x: from_x + (@x - from_x) * n /
|
|
41
|
-
y: from_y + (@y - from_y) * n /
|
|
40
|
+
x: from_x + (@x - from_x) * n / move_steps,
|
|
41
|
+
y: from_y + (@y - from_y) * n / move_steps,
|
|
42
42
|
modifiers: @keyboard.modifiers,
|
|
43
43
|
)
|
|
44
44
|
end
|
|
@@ -56,16 +56,19 @@ class Puppeteer::Mouse
|
|
|
56
56
|
# @param y [number]
|
|
57
57
|
# @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
|
|
58
58
|
def click(x, y, delay: nil, button: nil, click_count: nil)
|
|
59
|
+
# await_all(async_move, async_down, async_up) often breaks the order of CDP commands.
|
|
60
|
+
# D, [2020-04-15T17:09:47.895895 #88683] DEBUG -- : RECV << {"id"=>23, "result"=>{"layoutViewport"=>{"pageX"=>0, "pageY"=>1, "clientWidth"=>375, "clientHeight"=>667}, "visualViewport"=>{"offsetX"=>0, "offsetY"=>0, "pageX"=>0, "pageY"=>1, "clientWidth"=>375, "clientHeight"=>667, "scale"=>1, "zoom"=>1}, "contentSize"=>{"x"=>0, "y"=>0, "width"=>375, "height"=>2007}}, "sessionId"=>"0B09EA5E18DEE403E525B3E7FCD7E225"}
|
|
61
|
+
# D, [2020-04-15T17:09:47.898422 #88683] DEBUG -- : SEND >> {"sessionId":"0B09EA5E18DEE403E525B3E7FCD7E225","method":"Input.dispatchMouseEvent","params":{"type":"mouseReleased","button":"left","x":0,"y":0,"modifiers":0,"clickCount":1},"id":24}
|
|
62
|
+
# D, [2020-04-15T17:09:47.899711 #88683] DEBUG -- : SEND >> {"sessionId":"0B09EA5E18DEE403E525B3E7FCD7E225","method":"Input.dispatchMouseEvent","params":{"type":"mousePressed","button":"left","x":0,"y":0,"modifiers":0,"clickCount":1},"id":25}
|
|
63
|
+
# D, [2020-04-15T17:09:47.900237 #88683] DEBUG -- : SEND >> {"sessionId":"0B09EA5E18DEE403E525B3E7FCD7E225","method":"Input.dispatchMouseEvent","params":{"type":"mouseMoved","button":"left","x":187,"y":283,"modifiers":0},"id":26}
|
|
64
|
+
# So we execute move in advance.
|
|
65
|
+
move(x, y)
|
|
59
66
|
if delay
|
|
60
|
-
|
|
61
|
-
async_move(x, y),
|
|
62
|
-
async_down(button: button, click_count: click_count),
|
|
63
|
-
)
|
|
67
|
+
down(button: button, click_count: click_count)
|
|
64
68
|
sleep(delay / 1000.0)
|
|
65
69
|
up(button: button, click_count: click_count)
|
|
66
70
|
else
|
|
67
71
|
await_all(
|
|
68
|
-
async_move(x, y),
|
|
69
72
|
async_down(button: button, click_count: click_count),
|
|
70
73
|
async_up(button: button, click_count: click_count),
|
|
71
74
|
)
|
data/lib/puppeteer/page.rb
CHANGED
|
@@ -48,10 +48,10 @@ class Puppeteer::Page
|
|
|
48
48
|
if event['targetInfo']['type'] != 'worker'
|
|
49
49
|
# If we don't detach from service workers, they will never die.
|
|
50
50
|
await @client.send_message('Target.detachFromTarget', sessionId: event['sessionId'])
|
|
51
|
-
|
|
51
|
+
next
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
session = Puppeteer::Connection.from_session(@client).session(event['sessionId'])
|
|
54
|
+
session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
|
|
55
55
|
# const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
|
56
56
|
# this._workers.set(event.sessionId, worker);
|
|
57
57
|
# this.emit(Events.Page.WorkerCreated, worker);
|
|
@@ -59,7 +59,7 @@ class Puppeteer::Page
|
|
|
59
59
|
@client.on_event 'Target.detachedFromTarget' do |event|
|
|
60
60
|
session_id = event['sessionId']
|
|
61
61
|
worker = @workers[session_id]
|
|
62
|
-
|
|
62
|
+
next unless worker
|
|
63
63
|
|
|
64
64
|
emit_event('Events.Page.WorkerDestroyed', worker)
|
|
65
65
|
@workers.delete(session_id)
|
|
@@ -88,8 +88,8 @@ class Puppeteer::Page
|
|
|
88
88
|
network_manager.on_event 'Events.NetworkManager.RequestFinished' do |event|
|
|
89
89
|
emit_event 'Events.Page.RequestFinished', event
|
|
90
90
|
end
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
@file_chooser_interception_is_disabled = false
|
|
92
|
+
@file_chooser_interceptors = Set.new
|
|
93
93
|
|
|
94
94
|
@client.on_event 'Page.domContentEventFired' do |event|
|
|
95
95
|
emit_event 'Events.Page.DOMContentLoaded'
|
|
@@ -106,7 +106,9 @@ class Puppeteer::Page
|
|
|
106
106
|
@client.on_event 'Log.entryAdded' do |event|
|
|
107
107
|
handle_log_entry_added(event)
|
|
108
108
|
end
|
|
109
|
-
|
|
109
|
+
@client.on_event 'Page.fileChooserOpened' do |event|
|
|
110
|
+
handle_file_chooser(event)
|
|
111
|
+
end
|
|
110
112
|
@target.on_close do
|
|
111
113
|
emit_event 'Events.Page.Close'
|
|
112
114
|
@closed = true
|
|
@@ -122,41 +124,53 @@ class Puppeteer::Page
|
|
|
122
124
|
)
|
|
123
125
|
end
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# interceptor.call(null, fileChooser);
|
|
139
|
-
# }
|
|
127
|
+
def handle_file_chooser(event)
|
|
128
|
+
return if @file_chooser_interceptors.empty?
|
|
129
|
+
|
|
130
|
+
frame = @frame_manager.frame(event['frameId'])
|
|
131
|
+
context = frame.execution_context
|
|
132
|
+
element = context.adopt_backend_node_id(event['backendNodeId'])
|
|
133
|
+
interceptors = @file_chooser_interceptors.to_a
|
|
134
|
+
@file_chooser_interceptors.clear
|
|
135
|
+
file_chooser = Puppeteer::FileChooser.new(element, event)
|
|
136
|
+
interceptors.each do |promise|
|
|
137
|
+
promise.fulfill(file_chooser)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
# if (!this._fileChooserInterceptors.size)
|
|
147
|
-
# await this._client.send('Page.setInterceptFileChooserDialog', {enabled: true});
|
|
141
|
+
class FileChooserTimeoutError < StandardError
|
|
142
|
+
def initialize(timeout:)
|
|
143
|
+
super("waiting for filechooser failed: timeout #{timeout}ms exceeded")
|
|
144
|
+
end
|
|
145
|
+
end
|
|
148
146
|
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
147
|
+
# @param timeout [Integer]
|
|
148
|
+
# @return [Puppeteer::FileChooser]
|
|
149
|
+
def wait_for_file_chooser(timeout: nil)
|
|
150
|
+
if @file_chooser_interceptors.empty?
|
|
151
|
+
@client.send_message('Page.setInterceptFileChooserDialog', enabled: true)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
option_timeout = timeout || @timeout_settings.timeout
|
|
155
|
+
promise = resolvable_future
|
|
156
|
+
@file_chooser_interceptors << promise
|
|
157
|
+
|
|
158
|
+
begin
|
|
159
|
+
Timeout.timeout(option_timeout / 1000.0) do
|
|
160
|
+
promise.value!
|
|
161
|
+
end
|
|
162
|
+
rescue Timeout::Error
|
|
163
|
+
raise FileChooserTimeoutError.new(timeout: option_timeout)
|
|
164
|
+
ensure
|
|
165
|
+
@file_chooser_interceptors.delete(promise)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @param timeout [Integer]
|
|
170
|
+
# @return [Future<Puppeteer::FileChooser>]
|
|
171
|
+
async def async_wait_for_file_chooser(timeout: nil)
|
|
172
|
+
wait_for_file_chooser(timeout: timeout)
|
|
173
|
+
end
|
|
160
174
|
|
|
161
175
|
|
|
162
176
|
# /**
|
|
@@ -173,7 +187,7 @@ class Puppeteer::Page
|
|
|
173
187
|
# await this._client.send('Emulation.setGeolocationOverride', {longitude, latitude, accuracy});
|
|
174
188
|
# }
|
|
175
189
|
|
|
176
|
-
attr_reader :target
|
|
190
|
+
attr_reader :javascript_enabled, :target
|
|
177
191
|
|
|
178
192
|
def browser
|
|
179
193
|
@target.browser
|
|
@@ -204,7 +218,9 @@ class Puppeteer::Page
|
|
|
204
218
|
end
|
|
205
219
|
if source != 'worker'
|
|
206
220
|
console_message_location = Puppeteer::ConsoleMessage::Location.new(
|
|
207
|
-
|
|
221
|
+
url: url,
|
|
222
|
+
line_number: line_number,
|
|
223
|
+
)
|
|
208
224
|
emit_event('Events.Page.Console',
|
|
209
225
|
Puppeteer::ConsoleMessage.new(level, text, [], console_message_location))
|
|
210
226
|
end
|
|
@@ -273,23 +289,37 @@ class Puppeteer::Page
|
|
|
273
289
|
end
|
|
274
290
|
|
|
275
291
|
# `$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.
|
|
276
|
-
# @param
|
|
277
|
-
# @param
|
|
278
|
-
# @
|
|
279
|
-
# @return {!Promise<(!Object|undefined)>}
|
|
292
|
+
# @param selector [String]
|
|
293
|
+
# @param page_function [String]
|
|
294
|
+
# @return [Object]
|
|
280
295
|
def Seval(selector, page_function, *args)
|
|
281
296
|
main_frame.Seval(selector, page_function, *args)
|
|
282
297
|
end
|
|
283
298
|
|
|
299
|
+
# `$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.
|
|
300
|
+
# @param selector [String]
|
|
301
|
+
# @param page_function [String]
|
|
302
|
+
# @return [Future]
|
|
303
|
+
async def async_Seval(selector, page_function, *args)
|
|
304
|
+
Seval(selector, page_function, *args)
|
|
305
|
+
end
|
|
306
|
+
|
|
284
307
|
# `$$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.
|
|
285
|
-
# @param
|
|
286
|
-
# @param
|
|
287
|
-
# @
|
|
288
|
-
# @return {!Promise<(!Object|undefined)>}
|
|
308
|
+
# @param selector [String]
|
|
309
|
+
# @param page_function [String]
|
|
310
|
+
# @return [Object]
|
|
289
311
|
def SSeval(selector, page_function, *args)
|
|
290
312
|
main_frame.SSeval(selector, page_function, *args)
|
|
291
313
|
end
|
|
292
314
|
|
|
315
|
+
# `$$eval()` in JavaScript. $ is not allowed to use as a method name in Ruby.
|
|
316
|
+
# @param selector [String]
|
|
317
|
+
# @param page_function [String]
|
|
318
|
+
# @return [Future]
|
|
319
|
+
async def async_SSeval(selector, page_function, *args)
|
|
320
|
+
SSeval(selector, page_function, *args)
|
|
321
|
+
end
|
|
322
|
+
|
|
293
323
|
# `$x()` in JavaScript. $ is not allowed to use as a method name in Ruby.
|
|
294
324
|
# @param {string} expression
|
|
295
325
|
# @return {!Promise<!Array<!Puppeteer.ElementHandle>>}
|
|
@@ -608,14 +638,14 @@ class Puppeteer::Page
|
|
|
608
638
|
main_frame.goto(url, referer: referer, timeout: timeout, wait_until: wait_until)
|
|
609
639
|
end
|
|
610
640
|
|
|
611
|
-
# @param
|
|
612
|
-
# @
|
|
641
|
+
# @param timeout [number|nil]
|
|
642
|
+
# @param wait_until [string|nil] 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
|
|
643
|
+
# @return [Puppeteer::Response]
|
|
613
644
|
def reload(timeout: nil, wait_until: nil)
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
# return response;
|
|
645
|
+
await_all(
|
|
646
|
+
async_wait_for_navigation(timeout: timeout, wait_until: wait_until),
|
|
647
|
+
@client.async_send_message('Page.reload'),
|
|
648
|
+
).first
|
|
619
649
|
end
|
|
620
650
|
|
|
621
651
|
# @param timeout [number|nil]
|
|
@@ -932,12 +962,23 @@ class Puppeteer::Page
|
|
|
932
962
|
|
|
933
963
|
attr_reader :mouse
|
|
934
964
|
|
|
935
|
-
# @param
|
|
936
|
-
# @param
|
|
965
|
+
# @param selector [String]
|
|
966
|
+
# @param delay [Number]
|
|
967
|
+
# @param button [String] "left"|"right"|"middle"
|
|
968
|
+
# @param click_count [Number]
|
|
937
969
|
def click(selector, delay: nil, button: nil, click_count: nil)
|
|
938
970
|
main_frame.click(selector, delay: delay, button: button, click_count: click_count)
|
|
939
971
|
end
|
|
940
972
|
|
|
973
|
+
# @param selector [String]
|
|
974
|
+
# @param delay [Number]
|
|
975
|
+
# @param button [String] "left"|"right"|"middle"
|
|
976
|
+
# @param click_count [Number]
|
|
977
|
+
# @return [Future]
|
|
978
|
+
async def async_click(selector, delay: nil, button: nil, click_count: nil)
|
|
979
|
+
click(selector, delay: delay, button: button, click_count: click_count)
|
|
980
|
+
end
|
|
981
|
+
|
|
941
982
|
# @param {string} selector
|
|
942
983
|
def focus(selector)
|
|
943
984
|
main_frame.focus(selector)
|
|
@@ -955,16 +996,21 @@ class Puppeteer::Page
|
|
|
955
996
|
main_frame.select(selector, *values)
|
|
956
997
|
end
|
|
957
998
|
|
|
958
|
-
# @param
|
|
999
|
+
# @param selector [String]
|
|
959
1000
|
def tap(selector)
|
|
960
1001
|
main_frame.tap(selector)
|
|
961
1002
|
end
|
|
962
1003
|
|
|
963
|
-
# @param
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1004
|
+
# @param selector [String]
|
|
1005
|
+
async def async_tap(selector)
|
|
1006
|
+
tap(selector)
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
# @param selector [String]
|
|
1010
|
+
# @param text [String]
|
|
1011
|
+
# @param delay [Number]
|
|
1012
|
+
def type_text(selector, text, delay: nil)
|
|
1013
|
+
main_frame.type_text(selector, text, delay: delay)
|
|
968
1014
|
end
|
|
969
1015
|
|
|
970
1016
|
# /**
|
|
@@ -977,20 +1023,38 @@ class Puppeteer::Page
|
|
|
977
1023
|
# return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
|
|
978
1024
|
# }
|
|
979
1025
|
|
|
980
|
-
# @param
|
|
981
|
-
# @param
|
|
982
|
-
# @
|
|
1026
|
+
# @param selector [String]
|
|
1027
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
1028
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
1029
|
+
# @param timeout [Integer]
|
|
983
1030
|
def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
|
|
984
1031
|
main_frame.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
|
|
985
1032
|
end
|
|
986
1033
|
|
|
987
|
-
# @param
|
|
988
|
-
# @param
|
|
989
|
-
# @
|
|
1034
|
+
# @param selector [String]
|
|
1035
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
1036
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
1037
|
+
# @param timeout [Integer]
|
|
1038
|
+
async def async_wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
|
|
1039
|
+
wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
# @param xpath [String]
|
|
1043
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
1044
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
1045
|
+
# @param timeout [Integer]
|
|
990
1046
|
def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
|
|
991
1047
|
main_frame.wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
|
|
992
1048
|
end
|
|
993
1049
|
|
|
1050
|
+
# @param xpath [String]
|
|
1051
|
+
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
|
1052
|
+
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
|
1053
|
+
# @param timeout [Integer]
|
|
1054
|
+
async def async_wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
|
|
1055
|
+
wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
|
|
1056
|
+
end
|
|
1057
|
+
|
|
994
1058
|
# @param {Function|string} pageFunction
|
|
995
1059
|
# @param {!{polling?: string|number, timeout?: number}=} options
|
|
996
1060
|
# @param {!Array<*>} args
|