puppeteer-ruby 0.40.4 → 0.40.5
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/lib/puppeteer/element_handle/box_model.rb +3 -2
- data/lib/puppeteer/element_handle.rb +51 -7
- data/lib/puppeteer/events.rb +1 -0
- data/lib/puppeteer/frame_manager.rb +3 -1
- data/lib/puppeteer/js_handle.rb +1 -0
- data/lib/puppeteer/lifecycle_watcher.rb +11 -0
- data/lib/puppeteer/page.rb +2 -3
- data/lib/puppeteer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f6c1abfbf66f645ac208cf5f3f0ad24c4ae421e576c5b1516803cdc897bad22
|
4
|
+
data.tar.gz: a40b422147eff9261720975d8009ecc3fbd24a1f0d2d828f1fe3b5dce31f5c24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f532e2ff58c283c0904d5c76c0e9254d5b91be1f6ff7c576b728d91a727b0bb246f9d0eefe1461b1a7ba28607f33ac7a541d9d9a9ee3da0e5742c330f3c01b6e
|
7
|
+
data.tar.gz: c0dab5bca1e3ae23c6c2f3866cb3127024a9fd9663e01ff20d7edd68ef60060fc2203ffe81d80f322a10428ea4632193e1eef8b502e3375ea0c8413a3172dc61
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
### main [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.
|
1
|
+
### main [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.5...main)]
|
2
2
|
|
3
3
|
- xxx
|
4
4
|
|
5
|
+
### 0.40.5 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.4...0.40.5)]
|
6
|
+
|
7
|
+
Bugfix:
|
8
|
+
|
9
|
+
- Port Puppeteer v13.1-v13.5 bugfixes mainly for OOPIFs.
|
10
|
+
|
5
11
|
### 0.40.4 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.3...0.40.4)]
|
6
12
|
|
7
13
|
Bugfix:
|
@@ -2,12 +2,13 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
2
2
|
class BoxModel
|
3
3
|
QUAD_ATTRIBUTE_NAMES = %i(content padding border margin)
|
4
4
|
# @param result [Hash]
|
5
|
-
|
5
|
+
# @param offset [Point]
|
6
|
+
def initialize(result_model, offset:)
|
6
7
|
QUAD_ATTRIBUTE_NAMES.each do |attr_name|
|
7
8
|
quad = result_model[attr_name.to_s]
|
8
9
|
instance_variable_set(
|
9
10
|
:"@#{attr_name}",
|
10
|
-
quad.each_slice(2).map { |x, y| Point.new(x: x, y: y) },
|
11
|
+
quad.each_slice(2).map { |x, y| Point.new(x: x, y: y) + offset },
|
11
12
|
)
|
12
13
|
end
|
13
14
|
@width = result_model['width']
|
@@ -11,10 +11,12 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
11
11
|
# @param context [Puppeteer::ExecutionContext]
|
12
12
|
# @param client [Puppeteer::CDPSession]
|
13
13
|
# @param remote_object [Puppeteer::RemoteObject]
|
14
|
+
# @param frame [Puppeteer::Frame]
|
14
15
|
# @param page [Puppeteer::Page]
|
15
16
|
# @param frame_manager [Puppeteer::FrameManager]
|
16
|
-
def initialize(context:, client:, remote_object:, page:, frame_manager:)
|
17
|
+
def initialize(context:, client:, remote_object:, frame:, page:, frame_manager:)
|
17
18
|
super(context: context, client: client, remote_object: remote_object)
|
19
|
+
@frame = frame
|
18
20
|
@page = page
|
19
21
|
@frame_manager = frame_manager
|
20
22
|
@disposed = false
|
@@ -134,6 +136,37 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
139
|
+
class ElementNotClickableError < StandardError
|
140
|
+
def initialize
|
141
|
+
super("Node is either not clickable or not an HTMLElement")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# @param quad [Array<Array<Point>>]]
|
146
|
+
# @param offset [Point]
|
147
|
+
private def apply_offsets_to_quad(quad, offset)
|
148
|
+
quad.map { |part| part + offset }
|
149
|
+
end
|
150
|
+
|
151
|
+
# @param frame [Puppeteer::Frame]
|
152
|
+
# @return [Point]
|
153
|
+
private def oopif_offsets(frame)
|
154
|
+
offset = Point.new(x: 0, y: 0)
|
155
|
+
while frame.parent_frame
|
156
|
+
parent = frame.parent_frame
|
157
|
+
unless frame.oop_frame?
|
158
|
+
frame = parent
|
159
|
+
next
|
160
|
+
end
|
161
|
+
backend_node_id = parent._client.send_message('DOM.getFrameOwner', frameId: frame.id)['backendNodeId']
|
162
|
+
result = parent._client.send_message('DOM.getBoxModel', backendNodeId: backend_node_id)
|
163
|
+
break unless result
|
164
|
+
offset = BoxModel.new(result['model'], offset: offset).content.first
|
165
|
+
frame = parent
|
166
|
+
end
|
167
|
+
offset
|
168
|
+
end
|
169
|
+
|
137
170
|
def clickable_point(offset = nil)
|
138
171
|
offset_param = Offset.from(offset)
|
139
172
|
|
@@ -150,12 +183,22 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
150
183
|
end
|
151
184
|
|
152
185
|
# Filter out quads that have too small area to click into.
|
153
|
-
layout_metrics = @client.send_message('Page.getLayoutMetrics')
|
154
|
-
|
155
|
-
|
186
|
+
layout_metrics = @page.client.send_message('Page.getLayoutMetrics')
|
187
|
+
|
188
|
+
if result.empty? || result["quads"].empty?
|
189
|
+
raise ElementNotClickableError.new
|
190
|
+
end
|
191
|
+
|
192
|
+
# Filter out quads that have too small area to click into.
|
193
|
+
# Fallback to `layoutViewport` in case of using Firefox.
|
194
|
+
layout_viewport = layout_metrics["cssLayoutViewport"] || layout_metrics["layoutViewport"]
|
195
|
+
client_width = layout_viewport["clientWidth"]
|
196
|
+
client_height = layout_viewport["clientHeight"]
|
156
197
|
|
198
|
+
oopif_offset = oopif_offsets(@frame)
|
157
199
|
quads = result["quads"].
|
158
200
|
map { |quad| from_protocol_quad(quad) }.
|
201
|
+
map { |quad| apply_offsets_to_quad(quad, oopif_offset) }.
|
159
202
|
map { |quad| intersect_quad_with_viewport(quad, client_width, client_height) }.
|
160
203
|
select { |quad| compute_quad_area(quad) > 1 }
|
161
204
|
if quads.empty?
|
@@ -357,13 +400,14 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
357
400
|
# @return [BoundingBox|nil]
|
358
401
|
def bounding_box
|
359
402
|
if_present(box_model) do |result_model|
|
403
|
+
offset = oopif_offsets(@frame)
|
360
404
|
quads = result_model.border
|
361
405
|
|
362
406
|
x = quads.map(&:x).min
|
363
407
|
y = quads.map(&:y).min
|
364
408
|
BoundingBox.new(
|
365
|
-
x: x,
|
366
|
-
y: y,
|
409
|
+
x: x + offset.x,
|
410
|
+
y: y + offset.y,
|
367
411
|
width: quads.map(&:x).max - x,
|
368
412
|
height: quads.map(&:y).max - y,
|
369
413
|
)
|
@@ -373,7 +417,7 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
373
417
|
# @return [BoxModel|nil]
|
374
418
|
def box_model
|
375
419
|
if_present(@remote_object.box_model(@client)) do |result|
|
376
|
-
BoxModel.new(result['model'])
|
420
|
+
BoxModel.new(result['model'], offset: oopif_offsets(@frame))
|
377
421
|
end
|
378
422
|
end
|
379
423
|
|
data/lib/puppeteer/events.rb
CHANGED
@@ -96,6 +96,7 @@ module FrameManagerEmittedEvents ; end
|
|
96
96
|
FrameAttached: EventsDefinitionUtils.symbol('FrameManager.FrameAttached'),
|
97
97
|
FrameNavigated: EventsDefinitionUtils.symbol('FrameManager.FrameNavigated'),
|
98
98
|
FrameDetached: EventsDefinitionUtils.symbol('FrameManager.FrameDetached'),
|
99
|
+
FrameSwapped: EventsDefinitionUtils.symbol('FrameManager.FrameSwapped'),
|
99
100
|
LifecycleEvent: EventsDefinitionUtils.symbol('FrameManager.LifecycleEvent'),
|
100
101
|
FrameNavigatedWithinDocument: EventsDefinitionUtils.symbol('FrameManager.FrameNavigatedWithinDocument'),
|
101
102
|
ExecutionContextCreated: EventsDefinitionUtils.symbol('FrameManager.ExecutionContextCreated'),
|
@@ -178,7 +178,7 @@ class Puppeteer::FrameManager
|
|
178
178
|
frame = @frames[event['targetInfo']['targetId']]
|
179
179
|
session = Puppeteer::Connection.from_session(@client).session(event['sessionId'])
|
180
180
|
|
181
|
-
frame
|
181
|
+
frame&.send(:update_client, session)
|
182
182
|
setup_listeners(session)
|
183
183
|
async_init(session)
|
184
184
|
end
|
@@ -353,6 +353,8 @@ class Puppeteer::FrameManager
|
|
353
353
|
if frame
|
354
354
|
remove_frame_recursively(frame)
|
355
355
|
end
|
356
|
+
elsif reason == 'swap'
|
357
|
+
emit_event(FrameManagerEmittedEvents::FrameSwapped, frame)
|
356
358
|
end
|
357
359
|
end
|
358
360
|
|
data/lib/puppeteer/js_handle.rb
CHANGED
@@ -77,6 +77,7 @@ class Puppeteer::LifecycleWatcher
|
|
77
77
|
check_lifecycle_complete
|
78
78
|
end,
|
79
79
|
@frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigatedWithinDocument, &method(:navigated_within_document)),
|
80
|
+
@frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameSwapped, &method(:handle_frame_swapped)),
|
80
81
|
@frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameDetached, &method(:handle_frame_detached)),
|
81
82
|
]
|
82
83
|
@listener_ids['network_manager'] = @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Request, &method(:handle_request))
|
@@ -142,11 +143,21 @@ class Puppeteer::LifecycleWatcher
|
|
142
143
|
check_lifecycle_complete
|
143
144
|
end
|
144
145
|
|
146
|
+
private def handle_frame_swapped(frame)
|
147
|
+
return if frame != @frame
|
148
|
+
@swapped = true
|
149
|
+
check_lifecycle_complete
|
150
|
+
end
|
151
|
+
|
145
152
|
private def check_lifecycle_complete
|
146
153
|
# We expect navigation to commit.
|
147
154
|
return unless @expected_lifecycle.completed?(@frame)
|
148
155
|
@lifecycle_promise.fulfill(true) if @lifecycle_promise.pending?
|
149
156
|
if @frame.loader_id == @initial_loader_id && !@has_same_document_navigation
|
157
|
+
if @swapped
|
158
|
+
@swapped = false
|
159
|
+
@new_document_navigation_promise.fulfill(true)
|
160
|
+
end
|
150
161
|
return
|
151
162
|
end
|
152
163
|
if @has_same_document_navigation && @same_document_navigation_promise.pending?
|
data/lib/puppeteer/page.rb
CHANGED
@@ -227,7 +227,7 @@ class Puppeteer::Page
|
|
227
227
|
@client.send_message('Emulation.setGeolocationOverride', geolocation.to_h)
|
228
228
|
end
|
229
229
|
|
230
|
-
attr_reader :javascript_enabled, :target
|
230
|
+
attr_reader :javascript_enabled, :target, :client
|
231
231
|
alias_method :javascript_enabled?, :javascript_enabled
|
232
232
|
|
233
233
|
def browser
|
@@ -404,7 +404,7 @@ class Puppeteer::Page
|
|
404
404
|
items = cookies.map do |cookie|
|
405
405
|
(starts_with_http ? { url: page_url } : {}).merge(cookie).tap do |item|
|
406
406
|
raise ArgumentError.new("Blank page can not have cookie \"#{item[:name]}\"") if item[:url] == "about:blank"
|
407
|
-
raise
|
407
|
+
raise ArgumentError.new("Data URL page can not have cookie \"#{item[:name]}\"") if item[:url]&.start_with?("data:")
|
408
408
|
end
|
409
409
|
end
|
410
410
|
delete_cookie(*items)
|
@@ -508,7 +508,6 @@ class Puppeteer::Page
|
|
508
508
|
end
|
509
509
|
|
510
510
|
private def handle_console_api(event)
|
511
|
-
puts "~~~~~~~~~~~~~~#{event}"
|
512
511
|
if event['executionContextId'] == 0
|
513
512
|
# DevTools protocol stores the last 1000 console messages. These
|
514
513
|
# messages are always reported even for removed execution contexts. In
|
data/lib/puppeteer/version.rb
CHANGED
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.40.
|
4
|
+
version: 0.40.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|