puppeteer-ruby 0.43.1 → 0.44.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/docs/api_coverage.md +5 -12
- data/lib/puppeteer/aria_query_handler.rb +51 -11
- data/lib/puppeteer/coverage.rb +1 -1
- data/lib/puppeteer/custom_query_handler.rb +29 -2
- data/lib/puppeteer/element_handle.rb +7 -18
- data/lib/puppeteer/execution_context.rb +3 -60
- data/lib/puppeteer/frame.rb +14 -20
- data/lib/puppeteer/frame_manager.rb +2 -2
- data/lib/puppeteer/{dom_world.rb → isolated_world.rb} +36 -20
- data/lib/puppeteer/js_handle.rb +2 -6
- data/lib/puppeteer/lifecycle_watcher.rb +4 -3
- data/lib/puppeteer/page.rb +3 -3
- data/lib/puppeteer/query_handler_manager.rb +2 -2
- data/lib/puppeteer/remote_object.rb +2 -2
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ade25ba8f8e99240ed29fdad9300af7b65cc12ddf09e45c43f7b672c6324ed4
|
4
|
+
data.tar.gz: 97d3bfc48b3a2e3729dd8857c2bb6deca7babd4d0b055195f2dbe7c01c941e97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 891d8c29ac63d25cdb34178024d7a9202675d77b121a903e24a51e9465e46a9b7a0a9b70a2d893d9b274724b5547d5bb90e133aa2c217052f3f523f952e1a0a3
|
7
|
+
data.tar.gz: eea1fb6ff2f179208932a3bb84ca96841b1b08ff588d914e88ace6ad9e31f71c567c21321e3376b019a265122e51a4352b3f0039dd6bea770dba2a383efe82e5
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
### main [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.
|
1
|
+
### main [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.44.0...main)]
|
2
2
|
|
3
3
|
- xxx
|
4
4
|
|
5
|
+
### 0.44.0 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.43.1...0.44.0)]
|
6
|
+
|
7
|
+
- Port Puppeteer v17.0-v17.1 features.
|
8
|
+
- `wait_for_selector` no longer accept `root` parameter.
|
9
|
+
|
10
|
+
|
5
11
|
### 0.43.1 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.43.0...0.43.1)]
|
6
12
|
|
7
13
|
- Port Puppeteer v16.1 features, including bugfix and XPath query handler.
|
data/docs/api_coverage.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# API coverages
|
2
|
-
- Puppeteer version:
|
3
|
-
- puppeteer-ruby version: 0.
|
2
|
+
- Puppeteer version: v17.1.3
|
3
|
+
- puppeteer-ruby version: 0.44.0
|
4
4
|
|
5
5
|
## Puppeteer
|
6
6
|
|
@@ -150,13 +150,6 @@
|
|
150
150
|
* ~~removeAllListeners~~
|
151
151
|
* ~~removeListener~~
|
152
152
|
|
153
|
-
## ExecutionContext
|
154
|
-
|
155
|
-
* evaluate
|
156
|
-
* evaluateHandle => `#evaluate_handle`
|
157
|
-
* frame
|
158
|
-
* ~~queryObjects~~
|
159
|
-
|
160
153
|
## FileChooser
|
161
154
|
|
162
155
|
* accept
|
@@ -172,12 +165,12 @@
|
|
172
165
|
* $x => `#Sx`
|
173
166
|
* addScriptTag => `#add_script_tag`
|
174
167
|
* addStyleTag => `#add_style_tag`
|
168
|
+
* addStyleTag => `#add_style_tag`
|
175
169
|
* childFrames => `#child_frames`
|
176
170
|
* click
|
177
171
|
* content
|
178
172
|
* evaluate
|
179
173
|
* evaluateHandle => `#evaluate_handle`
|
180
|
-
* executionContext => `#execution_context`
|
181
174
|
* focus
|
182
175
|
* goto
|
183
176
|
* hover
|
@@ -251,7 +244,6 @@
|
|
251
244
|
* dispose
|
252
245
|
* evaluate
|
253
246
|
* evaluateHandle => `#evaluate_handle`
|
254
|
-
* executionContext => `#execution_context`
|
255
247
|
* getProperties => `#properties`
|
256
248
|
* getProperty => `#[]`
|
257
249
|
* getProperty => `#[]`
|
@@ -289,6 +281,7 @@
|
|
289
281
|
* $x => `#Sx`
|
290
282
|
* addScriptTag => `#add_script_tag`
|
291
283
|
* addStyleTag => `#add_style_tag`
|
284
|
+
* addStyleTag => `#add_style_tag`
|
292
285
|
* authenticate
|
293
286
|
* bringToFront => `#bring_to_front`
|
294
287
|
* browser
|
@@ -313,6 +306,7 @@
|
|
313
306
|
* exposeFunction => `#expose_function`
|
314
307
|
* focus
|
315
308
|
* frames
|
309
|
+
* ~~getDefaultTimeout~~
|
316
310
|
* goBack => `#go_back`
|
317
311
|
* goForward => `#go_forward`
|
318
312
|
* goto
|
@@ -401,5 +395,4 @@
|
|
401
395
|
|
402
396
|
* ~~evaluate~~
|
403
397
|
* ~~evaluateHandle~~
|
404
|
-
* ~~executionContext~~
|
405
398
|
* ~~url~~
|
@@ -25,43 +25,83 @@ class Puppeteer::AriaQueryHandler
|
|
25
25
|
query_options
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
# @param element [Puppeteer::ElementHandle]
|
29
|
+
# @param selector [String]
|
30
|
+
private def query_one_id(element, selector)
|
30
31
|
parse_result = parse_aria_selector(selector)
|
31
32
|
res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
|
32
|
-
|
33
|
+
|
34
|
+
if res.first.is_a?(Hash)
|
35
|
+
res.first['backendDOMNodeId']
|
36
|
+
else
|
33
37
|
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def query_one(element, selector)
|
42
|
+
id = query_one_id(element, selector)
|
43
|
+
|
44
|
+
if id
|
45
|
+
element.frame.main_world.adopt_backend_node(id)
|
34
46
|
else
|
35
|
-
|
47
|
+
nil
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
39
|
-
def wait_for(
|
51
|
+
def wait_for(element_or_frame, selector, visible: nil, hidden: nil, timeout: nil)
|
52
|
+
case element_or_frame
|
53
|
+
when Puppeteer::Frame
|
54
|
+
frame = element_or_frame
|
55
|
+
element = nil
|
56
|
+
when Puppeteer::ElementHandle
|
57
|
+
frame = element_or_frame.frame
|
58
|
+
element = frame.puppeteer_world.adopt_handle(element_or_frame)
|
59
|
+
else
|
60
|
+
raise ArgumentError.new("element_or_frame must be a Frame or ElementHandle. #{element_or_frame.inspect}")
|
61
|
+
end
|
62
|
+
|
40
63
|
# addHandlerToWorld
|
41
|
-
binding_function = Puppeteer::
|
64
|
+
binding_function = Puppeteer::IsolaatedWorld::BindingFunction.new(
|
42
65
|
name: 'ariaQuerySelector',
|
43
|
-
proc: -> (sel) {
|
66
|
+
proc: -> (sel) {
|
67
|
+
id = query_one_id(element || frame.puppeteer_world.document, sel)
|
68
|
+
|
69
|
+
if id
|
70
|
+
frame.puppeteer_world.adopt_backend_node(id)
|
71
|
+
else
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
},
|
44
75
|
)
|
45
|
-
|
76
|
+
result = frame.puppeteer_world.send(:wait_for_selector_in_page,
|
46
77
|
'(_, selector) => globalThis.ariaQuerySelector(selector)',
|
78
|
+
element,
|
47
79
|
selector,
|
48
80
|
visible: visible,
|
49
81
|
hidden: hidden,
|
50
82
|
timeout: timeout,
|
51
83
|
binding_function: binding_function,
|
52
|
-
root: root,
|
53
84
|
)
|
85
|
+
|
86
|
+
element&.dispose
|
87
|
+
|
88
|
+
if result.is_a?(Puppeteer::ElementHandle)
|
89
|
+
result.frame.main_world.transfer_handle(result)
|
90
|
+
else
|
91
|
+
result&.dispose
|
92
|
+
nil
|
93
|
+
end
|
54
94
|
end
|
55
95
|
|
56
96
|
def query_all(element, selector)
|
57
|
-
|
97
|
+
world = element.frame.main_world
|
58
98
|
parse_result = parse_aria_selector(selector)
|
59
99
|
res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
|
60
100
|
if res.empty?
|
61
101
|
nil
|
62
102
|
else
|
63
103
|
promises = res.map do |ax_node|
|
64
|
-
|
104
|
+
world.send(:async_adopt_backend_node, ax_node['backendDOMNodeId'])
|
65
105
|
end
|
66
106
|
await_all(*promises)
|
67
107
|
end
|
data/lib/puppeteer/coverage.rb
CHANGED
@@ -21,12 +21,39 @@ class Puppeteer::CustomQueryHandler
|
|
21
21
|
nil
|
22
22
|
end
|
23
23
|
|
24
|
-
def wait_for(
|
24
|
+
def wait_for(element_or_frame, selector, visible: nil, hidden: nil, timeout: nil)
|
25
|
+
case element_or_frame
|
26
|
+
when Puppeteer::Frame
|
27
|
+
frame = element_or_frame
|
28
|
+
element = nil
|
29
|
+
when Puppeteer::ElementHandle
|
30
|
+
frame = element_or_frame.frame
|
31
|
+
element = frame.puppeteer_world.adopt_handle(element_or_frame)
|
32
|
+
else
|
33
|
+
raise ArgumentError.new("element_or_frame must be a Frame or ElementHandle. #{element_or_frame.inspect}")
|
34
|
+
end
|
35
|
+
|
25
36
|
unless @query_one
|
26
37
|
raise NotImplementedError.new("#{self.class}##{__method__} is not implemented.")
|
27
38
|
end
|
28
39
|
|
29
|
-
|
40
|
+
result = frame.puppeteer_world.send(:wait_for_selector_in_page,
|
41
|
+
@query_one,
|
42
|
+
element,
|
43
|
+
selector,
|
44
|
+
visible: visible,
|
45
|
+
hidden: hidden,
|
46
|
+
timeout: timeout,
|
47
|
+
)
|
48
|
+
|
49
|
+
element&.dispose
|
50
|
+
|
51
|
+
if result.is_a?(Puppeteer::ElementHandle)
|
52
|
+
result.frame.main_world.transfer_handle(result)
|
53
|
+
else
|
54
|
+
result&.dispose
|
55
|
+
nil
|
56
|
+
end
|
30
57
|
end
|
31
58
|
|
32
59
|
def query_all(element, selector)
|
@@ -12,16 +12,16 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
12
12
|
# @param client [Puppeteer::CDPSession]
|
13
13
|
# @param remote_object [Puppeteer::RemoteObject]
|
14
14
|
# @param frame [Puppeteer::Frame]
|
15
|
-
|
16
|
-
# @param frame_manager [Puppeteer::FrameManager]
|
17
|
-
def initialize(context:, client:, remote_object:, frame:, page:, frame_manager:)
|
15
|
+
def initialize(context:, client:, remote_object:, frame:)
|
18
16
|
super(context: context, client: client, remote_object: remote_object)
|
19
17
|
@frame = frame
|
20
|
-
@page = page
|
21
|
-
@frame_manager = frame_manager
|
18
|
+
@page = frame.page
|
19
|
+
@frame_manager = frame.frame_manager
|
22
20
|
@disposed = false
|
23
21
|
end
|
24
22
|
|
23
|
+
attr_reader :page, :frame, :frame_manager
|
24
|
+
|
25
25
|
def inspect
|
26
26
|
values = %i[context remote_object page disposed].map do |sym|
|
27
27
|
value = instance_variable_get(:"@#{sym}")
|
@@ -60,18 +60,7 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
60
60
|
# (30 seconds). Pass `0` to disable timeout. The default value can be changed
|
61
61
|
# by using the {@link Page.setDefaultTimeout} method.
|
62
62
|
def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
|
63
|
-
|
64
|
-
|
65
|
-
secondary_world = frame.secondary_world
|
66
|
-
adopted_root = secondary_world.execution_context.adopt_element_handle(self)
|
67
|
-
handle = secondary_world.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout, root: adopted_root)
|
68
|
-
adopted_root.dispose
|
69
|
-
return nil unless handle
|
70
|
-
|
71
|
-
main_world = frame.main_world
|
72
|
-
result = main_world.execution_context.adopt_element_handle(handle)
|
73
|
-
handle.dispose
|
74
|
-
result
|
63
|
+
query_handler_manager.detect_query_handler(selector).wait_for(self, visible: visible, hidden: hidden, timeout: timeout)
|
75
64
|
end
|
76
65
|
|
77
66
|
define_async_method :async_wait_for_selector
|
@@ -653,6 +642,6 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
653
642
|
# used in AriaQueryHandler
|
654
643
|
def query_ax_tree(accessible_name: nil, role: nil)
|
655
644
|
@remote_object.query_ax_tree(@client,
|
656
|
-
|
645
|
+
accessible_name: accessible_name, role: role)
|
657
646
|
end
|
658
647
|
end
|
@@ -7,7 +7,7 @@ class Puppeteer::ExecutionContext
|
|
7
7
|
|
8
8
|
# @param client [Puppeteer::CDPSession]
|
9
9
|
# @param context_payload [Hash]
|
10
|
-
# @param world [Puppeteer::
|
10
|
+
# @param world [Puppeteer::IsolaatedWorld?]
|
11
11
|
def initialize(client, context_payload, world)
|
12
12
|
@client = client
|
13
13
|
@world = world
|
@@ -17,23 +17,16 @@ class Puppeteer::ExecutionContext
|
|
17
17
|
|
18
18
|
attr_reader :client, :world
|
19
19
|
|
20
|
-
# only used in
|
20
|
+
# only used in IsolaatedWorld
|
21
21
|
private def _context_id
|
22
22
|
@context_id
|
23
23
|
end
|
24
24
|
|
25
|
-
# only used in
|
25
|
+
# only used in IsolaatedWorld::BindingFunction#add_binding_to_context
|
26
26
|
private def _context_name
|
27
27
|
@context_name
|
28
28
|
end
|
29
29
|
|
30
|
-
# @return [Puppeteer::Frame]
|
31
|
-
def frame
|
32
|
-
if_present(@world) do |world|
|
33
|
-
world.frame
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
30
|
# @param page_function [String]
|
38
31
|
# @return [Object]
|
39
32
|
def evaluate(page_function, *args)
|
@@ -208,54 +201,4 @@ class Puppeteer::ExecutionContext
|
|
208
201
|
context_id: @context_id,
|
209
202
|
)
|
210
203
|
end
|
211
|
-
|
212
|
-
# /**
|
213
|
-
# * @param {!JSHandle} prototypeHandle
|
214
|
-
# * @return {!Promise<!JSHandle>}
|
215
|
-
# */
|
216
|
-
# async queryObjects(prototypeHandle) {
|
217
|
-
# assert(!prototypeHandle._disposed, 'Prototype JSHandle is disposed!');
|
218
|
-
# assert(prototypeHandle._remoteObject.objectId, 'Prototype JSHandle must not be referencing primitive value');
|
219
|
-
# const response = await this._client.send('Runtime.queryObjects', {
|
220
|
-
# prototypeObjectId: prototypeHandle._remoteObject.objectId
|
221
|
-
# });
|
222
|
-
# return createJSHandle(this, response.objects);
|
223
|
-
# }
|
224
|
-
|
225
|
-
# @param backend_node_id [Integer]
|
226
|
-
# @return [Puppeteer::ElementHandle]
|
227
|
-
def adopt_backend_node_id(backend_node_id)
|
228
|
-
response = @client.send_message('DOM.resolveNode',
|
229
|
-
backendNodeId: backend_node_id,
|
230
|
-
executionContextId: @context_id,
|
231
|
-
)
|
232
|
-
Puppeteer::JSHandle.create(
|
233
|
-
context: self,
|
234
|
-
remote_object: Puppeteer::RemoteObject.new(response["object"]),
|
235
|
-
)
|
236
|
-
end
|
237
|
-
private define_async_method :async_adopt_backend_node_id
|
238
|
-
|
239
|
-
# @param element_handle [Puppeteer::ElementHandle]
|
240
|
-
# @return [Puppeteer::ElementHandle]
|
241
|
-
def adopt_element_handle(element_handle)
|
242
|
-
if element_handle.execution_context == self
|
243
|
-
raise ArgumentError.new('Cannot adopt handle that already belongs to this execution context')
|
244
|
-
end
|
245
|
-
|
246
|
-
unless @world
|
247
|
-
raise 'Cannot adopt handle without DOMWorld'
|
248
|
-
end
|
249
|
-
|
250
|
-
node_info = element_handle.remote_object.node_info(@client)
|
251
|
-
response = @client.send_message('DOM.resolveNode',
|
252
|
-
backendNodeId: node_info["node"]["backendNodeId"],
|
253
|
-
executionContextId: @context_id,
|
254
|
-
)
|
255
|
-
|
256
|
-
Puppeteer::JSHandle.create(
|
257
|
-
context: self,
|
258
|
-
remote_object: Puppeteer::RemoteObject.new(response["object"]),
|
259
|
-
)
|
260
|
-
end
|
261
204
|
end
|
data/lib/puppeteer/frame.rb
CHANGED
@@ -37,8 +37,8 @@ class Puppeteer::Frame
|
|
37
37
|
# @param client [Puppeteer::CDPSession]
|
38
38
|
private def update_client(client)
|
39
39
|
@client = client
|
40
|
-
@main_world = Puppeteer::
|
41
|
-
@
|
40
|
+
@main_world = Puppeteer::IsolaatedWorld.new(@client, @frame_manager, self, @frame_manager.timeout_settings)
|
41
|
+
@puppeteer_world = Puppeteer::IsolaatedWorld.new(@client, @frame_manager, self, @frame_manager.timeout_settings)
|
42
42
|
end
|
43
43
|
|
44
44
|
def page
|
@@ -49,7 +49,7 @@ class Puppeteer::Frame
|
|
49
49
|
@client != @frame_manager.client
|
50
50
|
end
|
51
51
|
|
52
|
-
attr_accessor :frame_manager, :id, :loader_id, :lifecycle_events, :main_world, :
|
52
|
+
attr_accessor :frame_manager, :id, :loader_id, :lifecycle_events, :main_world, :puppeteer_world
|
53
53
|
|
54
54
|
def has_started_loading?
|
55
55
|
@has_started_loading
|
@@ -154,14 +154,14 @@ class Puppeteer::Frame
|
|
154
154
|
|
155
155
|
# @return [String]
|
156
156
|
def content
|
157
|
-
@
|
157
|
+
@puppeteer_world.content
|
158
158
|
end
|
159
159
|
|
160
160
|
# @param html [String]
|
161
161
|
# @param timeout [Integer]
|
162
162
|
# @param wait_until [String|Array<String>]
|
163
163
|
def set_content(html, timeout: nil, wait_until: nil)
|
164
|
-
@
|
164
|
+
@puppeteer_world.set_content(html, timeout: timeout, wait_until: wait_until)
|
165
165
|
end
|
166
166
|
|
167
167
|
# @return [String]
|
@@ -212,35 +212,35 @@ class Puppeteer::Frame
|
|
212
212
|
# @param button [String] "left"|"right"|"middle"
|
213
213
|
# @param click_count [Number]
|
214
214
|
def click(selector, delay: nil, button: nil, click_count: nil)
|
215
|
-
@
|
215
|
+
@puppeteer_world.click(selector, delay: delay, button: button, click_count: click_count)
|
216
216
|
end
|
217
217
|
|
218
218
|
define_async_method :async_click
|
219
219
|
|
220
220
|
# @param {string} selector
|
221
221
|
def focus(selector)
|
222
|
-
@
|
222
|
+
@puppeteer_world.focus(selector)
|
223
223
|
end
|
224
224
|
|
225
225
|
define_async_method :async_focus
|
226
226
|
|
227
227
|
# @param {string} selector
|
228
228
|
def hover(selector)
|
229
|
-
@
|
229
|
+
@puppeteer_world.hover(selector)
|
230
230
|
end
|
231
231
|
|
232
232
|
# @param {string} selector
|
233
233
|
# @param {!Array<string>} values
|
234
234
|
# @return {!Promise<!Array<string>>}
|
235
235
|
def select(selector, *values)
|
236
|
-
@
|
236
|
+
@puppeteer_world.select(selector, *values)
|
237
237
|
end
|
238
238
|
|
239
239
|
define_async_method :async_select
|
240
240
|
|
241
241
|
# @param {string} selector
|
242
242
|
def tap(selector)
|
243
|
-
@
|
243
|
+
@puppeteer_world.tap(selector)
|
244
244
|
end
|
245
245
|
|
246
246
|
define_async_method :async_tap
|
@@ -259,14 +259,8 @@ class Puppeteer::Frame
|
|
259
259
|
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
260
260
|
# @param timeout [Integer]
|
261
261
|
def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
|
262
|
-
|
263
|
-
|
264
|
-
return nil
|
265
|
-
end
|
266
|
-
main_execution_context = @main_world.execution_context
|
267
|
-
result = main_execution_context.adopt_element_handle(handle)
|
268
|
-
handle.dispose
|
269
|
-
result
|
262
|
+
query_handler_manager = Puppeteer::QueryHandlerManager.instance
|
263
|
+
query_handler_manager.detect_query_handler(selector).wait_for(self, visible: visible, hidden: hidden, timeout: timeout)
|
270
264
|
end
|
271
265
|
|
272
266
|
define_async_method :async_wait_for_selector
|
@@ -306,7 +300,7 @@ class Puppeteer::Frame
|
|
306
300
|
|
307
301
|
# @return [String]
|
308
302
|
def title
|
309
|
-
@
|
303
|
+
@puppeteer_world.title
|
310
304
|
end
|
311
305
|
|
312
306
|
# @param frame_payload [Hash]
|
@@ -344,7 +338,7 @@ class Puppeteer::Frame
|
|
344
338
|
def detach
|
345
339
|
@detached = true
|
346
340
|
@main_world.detach
|
347
|
-
@
|
341
|
+
@puppeteer_world.detach
|
348
342
|
if @parent_frame
|
349
343
|
@parent_frame._child_frames.delete(self)
|
350
344
|
end
|
@@ -413,11 +413,11 @@ class Puppeteer::FrameManager
|
|
413
413
|
|
414
414
|
if context_payload.dig('auxData', 'isDefault')
|
415
415
|
world = frame.main_world
|
416
|
-
elsif context_payload['name'] == UTILITY_WORLD_NAME && !frame.
|
416
|
+
elsif context_payload['name'] == UTILITY_WORLD_NAME && !frame.puppeteer_world.has_context?
|
417
417
|
# In case of multiple sessions to the same target, there's a race between
|
418
418
|
# connections so we might end up creating multiple isolated worlds.
|
419
419
|
# We can use either.
|
420
|
-
world = frame.
|
420
|
+
world = frame.puppeteer_world
|
421
421
|
end
|
422
422
|
end
|
423
423
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'thread'
|
2
2
|
|
3
|
-
# https://github.com/puppeteer/puppeteer/blob/master/src/
|
4
|
-
class Puppeteer::
|
3
|
+
# https://github.com/puppeteer/puppeteer/blob/master/src/IsolaatedWorld.js
|
4
|
+
class Puppeteer::IsolaatedWorld
|
5
5
|
using Puppeteer::DefineAsyncMethod
|
6
6
|
|
7
7
|
class BindingFunction
|
@@ -152,7 +152,7 @@ class Puppeteer::DOMWorld
|
|
152
152
|
raise 'Bug of puppeteer-ruby...'
|
153
153
|
end
|
154
154
|
|
155
|
-
|
155
|
+
def document
|
156
156
|
@document ||= evaluate_document.as_element
|
157
157
|
end
|
158
158
|
|
@@ -416,16 +416,6 @@ class Puppeteer::DOMWorld
|
|
416
416
|
handle.dispose
|
417
417
|
end
|
418
418
|
|
419
|
-
# @param selector [String]
|
420
|
-
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
421
|
-
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
422
|
-
# @param timeout [Integer]
|
423
|
-
def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil, root: nil)
|
424
|
-
# call wait_for_selector_in_page with custom query selector.
|
425
|
-
query_selector_manager = Puppeteer::QueryHandlerManager.instance
|
426
|
-
query_selector_manager.detect_query_handler(selector).wait_for(self, visible: visible, hidden: hidden, timeout: timeout, root: root)
|
427
|
-
end
|
428
|
-
|
429
419
|
private def binding_identifier(name, context)
|
430
420
|
"#{name}_#{context.send(:_context_id)}"
|
431
421
|
end
|
@@ -497,7 +487,7 @@ class Puppeteer::DOMWorld
|
|
497
487
|
# @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
|
498
488
|
# @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
|
499
489
|
# @param timeout [Integer]
|
500
|
-
private def wait_for_selector_in_page(query_one, selector, visible: nil, hidden: nil, timeout: nil,
|
490
|
+
private def wait_for_selector_in_page(query_one, root, selector, visible: nil, hidden: nil, timeout: nil, binding_function: nil)
|
501
491
|
option_wait_for_visible = visible || false
|
502
492
|
option_wait_for_hidden = hidden || false
|
503
493
|
option_timeout = timeout || @timeout_settings.timeout
|
@@ -531,12 +521,7 @@ class Puppeteer::DOMWorld
|
|
531
521
|
root: option_root,
|
532
522
|
binding_function: binding_function,
|
533
523
|
)
|
534
|
-
|
535
|
-
unless handle.as_element
|
536
|
-
handle.dispose
|
537
|
-
return nil
|
538
|
-
end
|
539
|
-
handle.as_element
|
524
|
+
wait_task.await_promise
|
540
525
|
end
|
541
526
|
|
542
527
|
# @param page_function [String]
|
@@ -601,4 +586,35 @@ class Puppeteer::DOMWorld
|
|
601
586
|
}
|
602
587
|
JAVASCRIPT
|
603
588
|
end
|
589
|
+
|
590
|
+
# @param backend_node_id [Integer]
|
591
|
+
# @return [Puppeteer::ElementHandle]
|
592
|
+
def adopt_backend_node(backend_node_id)
|
593
|
+
response = @client.send_message('DOM.resolveNode',
|
594
|
+
backendNodeId: backend_node_id,
|
595
|
+
executionContextId: execution_context.send(:_context_id),
|
596
|
+
)
|
597
|
+
Puppeteer::JSHandle.create(
|
598
|
+
context: execution_context,
|
599
|
+
remote_object: Puppeteer::RemoteObject.new(response["object"]),
|
600
|
+
)
|
601
|
+
end
|
602
|
+
private define_async_method :async_adopt_backend_node
|
603
|
+
|
604
|
+
# @param element_handle [Puppeteer::ElementHandle]
|
605
|
+
# @return [Puppeteer::ElementHandle]
|
606
|
+
def adopt_handle(element_handle)
|
607
|
+
if element_handle.execution_context == execution_context
|
608
|
+
raise ArgumentError.new('Cannot adopt handle that already belongs to this execution context')
|
609
|
+
end
|
610
|
+
|
611
|
+
node_info = element_handle.remote_object.node_info(@client)
|
612
|
+
adopt_backend_node(node_info["node"]["backendNodeId"])
|
613
|
+
end
|
614
|
+
|
615
|
+
def transfer_handle(element_handle)
|
616
|
+
result = adopt_handle(element_handle)
|
617
|
+
element_handle.dispose
|
618
|
+
result
|
619
|
+
end
|
604
620
|
end
|
data/lib/puppeteer/js_handle.rb
CHANGED
@@ -5,16 +5,12 @@ class Puppeteer::JSHandle
|
|
5
5
|
# @param context [Puppeteer::ExecutionContext]
|
6
6
|
# @param remote_object [Puppeteer::RemoteObject]
|
7
7
|
def self.create(context:, remote_object:)
|
8
|
-
|
9
|
-
if remote_object.sub_type == 'node' && frame
|
10
|
-
frame_manager = frame.frame_manager
|
8
|
+
if remote_object.sub_type == 'node' && context.world
|
11
9
|
Puppeteer::ElementHandle.new(
|
12
10
|
context: context,
|
13
11
|
client: context.client,
|
14
12
|
remote_object: remote_object,
|
15
|
-
frame: frame,
|
16
|
-
page: frame_manager.page,
|
17
|
-
frame_manager: frame_manager,
|
13
|
+
frame: context.world.frame,
|
18
14
|
)
|
19
15
|
else
|
20
16
|
Puppeteer::JSHandle.new(
|
@@ -93,13 +93,14 @@ class Puppeteer::LifecycleWatcher
|
|
93
93
|
check_lifecycle_complete
|
94
94
|
end
|
95
95
|
|
96
|
-
class AnotherRequestReceivedError < StandardError ; end
|
97
|
-
|
98
96
|
# @param [Puppeteer::HTTPRequest] request
|
99
97
|
def handle_request(request)
|
100
98
|
return if request.frame != @frame || !request.navigation_request?
|
101
99
|
@navigation_request = request
|
102
|
-
|
100
|
+
# Resolve previous navigation response in case there are multiple
|
101
|
+
# navigation requests reported by the backend. This generally should not
|
102
|
+
# happen by it looks like it's possible.
|
103
|
+
@navigation_response_received&.fulfill(nil)
|
103
104
|
@navigation_response_received = resolvable_future
|
104
105
|
if request.response && !@navigation_response_received.resolved?
|
105
106
|
@navigation_response_received.fulfill(nil)
|
data/lib/puppeteer/page.rb
CHANGED
@@ -191,8 +191,7 @@ class Puppeteer::Page
|
|
191
191
|
return if @file_chooser_interceptors.empty?
|
192
192
|
|
193
193
|
frame = @frame_manager.frame(event['frameId'])
|
194
|
-
|
195
|
-
element = context.adopt_backend_node_id(event['backendNodeId'])
|
194
|
+
element = frame.main_world.adopt_backend_node(event['backendNodeId'])
|
196
195
|
interceptors = @file_chooser_interceptors.to_a
|
197
196
|
@file_chooser_interceptors.clear
|
198
197
|
file_chooser = Puppeteer::FileChooser.new(element, event)
|
@@ -1070,7 +1069,8 @@ class Puppeteer::Page
|
|
1070
1069
|
clip = if_present(screenshot_options.clip) do |rect|
|
1071
1070
|
x = rect[:x].round
|
1072
1071
|
y = rect[:y].round
|
1073
|
-
|
1072
|
+
scale = rect[:scale] || 1
|
1073
|
+
{ x: x, y: y, width: rect[:width] + rect[:x] - x, height: rect[:height] + rect[:y] - y, scale: scale }
|
1074
1074
|
end
|
1075
1075
|
|
1076
1076
|
if screenshot_options.full_page?
|
@@ -61,8 +61,8 @@ class Puppeteer::QueryHandlerManager
|
|
61
61
|
@query_handler.query_one(element_handle, @selector)
|
62
62
|
end
|
63
63
|
|
64
|
-
def wait_for(
|
65
|
-
@query_handler.wait_for(
|
64
|
+
def wait_for(element_or_frame, visible:, hidden:, timeout:)
|
65
|
+
@query_handler.wait_for(element_or_frame, @selector, visible: visible, hidden: hidden, timeout: timeout)
|
66
66
|
end
|
67
67
|
|
68
68
|
def query_all(element_handle)
|
@@ -105,8 +105,8 @@ class Puppeteer::RemoteObject
|
|
105
105
|
role: role,
|
106
106
|
}.compact)
|
107
107
|
|
108
|
-
result['nodes'].
|
109
|
-
node['role']['value']
|
108
|
+
result['nodes'].select do |node|
|
109
|
+
node['role'] && node['role']['value'] != 'StaticText'
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
data/lib/puppeteer/version.rb
CHANGED
data/lib/puppeteer.rb
CHANGED
@@ -32,7 +32,6 @@ require 'puppeteer/css_coverage'
|
|
32
32
|
require 'puppeteer/custom_query_handler'
|
33
33
|
require 'puppeteer/devices'
|
34
34
|
require 'puppeteer/dialog'
|
35
|
-
require 'puppeteer/dom_world'
|
36
35
|
require 'puppeteer/emulation_manager'
|
37
36
|
require 'puppeteer/exception_details'
|
38
37
|
require 'puppeteer/executable_path_finder'
|
@@ -43,6 +42,7 @@ require 'puppeteer/frame'
|
|
43
42
|
require 'puppeteer/frame_manager'
|
44
43
|
require 'puppeteer/http_request'
|
45
44
|
require 'puppeteer/http_response'
|
45
|
+
require 'puppeteer/isolated_world'
|
46
46
|
require 'puppeteer/js_coverage'
|
47
47
|
require 'puppeteer/js_handle'
|
48
48
|
require 'puppeteer/keyboard'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppeteer-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.44.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -272,7 +272,6 @@ files:
|
|
272
272
|
- lib/puppeteer/device.rb
|
273
273
|
- lib/puppeteer/devices.rb
|
274
274
|
- lib/puppeteer/dialog.rb
|
275
|
-
- lib/puppeteer/dom_world.rb
|
276
275
|
- lib/puppeteer/element_handle.rb
|
277
276
|
- lib/puppeteer/element_handle/bounding_box.rb
|
278
277
|
- lib/puppeteer/element_handle/box_model.rb
|
@@ -294,6 +293,7 @@ files:
|
|
294
293
|
- lib/puppeteer/http_request.rb
|
295
294
|
- lib/puppeteer/http_response.rb
|
296
295
|
- lib/puppeteer/if_present.rb
|
296
|
+
- lib/puppeteer/isolated_world.rb
|
297
297
|
- lib/puppeteer/js_coverage.rb
|
298
298
|
- lib/puppeteer/js_handle.rb
|
299
299
|
- lib/puppeteer/keyboard.rb
|