puppeteer-ruby 0.43.1 → 0.44.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.
- 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
|