puppeteer-ruby 0.40.4 → 0.40.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1c608c27cbcee1c2038a3ecb2ba5244ef75906136fdd7aa868c521cd8248053
4
- data.tar.gz: 9535f70cb9b6056324c9828fff4c9e4412e0fbd48c2ac7a7bd8308bc51d1d26c
3
+ metadata.gz: 2f6c1abfbf66f645ac208cf5f3f0ad24c4ae421e576c5b1516803cdc897bad22
4
+ data.tar.gz: a40b422147eff9261720975d8009ecc3fbd24a1f0d2d828f1fe3b5dce31f5c24
5
5
  SHA512:
6
- metadata.gz: 4d9da0c4e2820117bff76f55bf5c9141c1b2ac8af351f6c27951df5bb20c5825a321c33f4ddde13b1e77864fd1c29803d5eb5f014df80d1b596a850a2d7f0ac3
7
- data.tar.gz: f6159e8906c6f35b67057ef47e4e675bfeeb824ee7abaee0d52f5d25ef7bea6f6c7fe699af3a8fee9bbd1020a7894966ee4826d38d01d74e4860f8ead4b759c7
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.4...main)]
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
- def initialize(result_model)
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
- client_width = layout_metrics["layoutViewport"]["clientWidth"]
155
- client_height = layout_metrics["layoutViewport"]["clientHeight"]
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
 
@@ -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.send(:update_client, session)
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
 
@@ -12,6 +12,7 @@ class Puppeteer::JSHandle
12
12
  context: context,
13
13
  client: context.client,
14
14
  remote_object: remote_object,
15
+ frame: frame,
15
16
  page: frame_manager.page,
16
17
  frame_manager: frame_manager,
17
18
  )
@@ -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?
@@ -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 ArgumetnError.new("Data URL page can not have cookie \"#{item[:name]}\"") if item[:url]&.start_with?("data:")
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
@@ -1,3 +1,3 @@
1
1
  module Puppeteer
2
- VERSION = '0.40.4'
2
+ VERSION = '0.40.5'
3
3
  end
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
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-10 00:00:00.000000000 Z
11
+ date: 2022-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby