puppeteer-ruby 0.40.2 → 0.40.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e88033f07007a1841f99535a96497bef2aa35b58e0599d51886ec760ef8f8201
4
- data.tar.gz: 3b4b69f023861cc24a4ecf402e2b6eff0cba0d57fbef37991996964a1b57007b
3
+ metadata.gz: 2f6c1abfbf66f645ac208cf5f3f0ad24c4ae421e576c5b1516803cdc897bad22
4
+ data.tar.gz: a40b422147eff9261720975d8009ecc3fbd24a1f0d2d828f1fe3b5dce31f5c24
5
5
  SHA512:
6
- metadata.gz: 6e63bd3b526e4cc09f309fc206f9395618393ab104438e93eebc190e3efa36a7e12e3037388480b9dd735121f752cbbd0bd5dc1152ae39a57be6f855dc41b41f
7
- data.tar.gz: fe6dff5b5b82813c003e67725868a467e2e9b43e16c4bf4bca1eb48c588daa2efd782d4c1c6b351117a3cfbf7daea4feb37b36fde3637abacea33cd2e3244cb4
6
+ metadata.gz: f532e2ff58c283c0904d5c76c0e9254d5b91be1f6ff7c576b728d91a727b0bb246f9d0eefe1461b1a7ba28607f33ac7a541d9d9a9ee3da0e5742c330f3c01b6e
7
+ data.tar.gz: c0dab5bca1e3ae23c6c2f3866cb3127024a9fd9663e01ff20d7edd68ef60060fc2203ffe81d80f322a10428ea4632193e1eef8b502e3375ea0c8413a3172dc61
data/CHANGELOG.md CHANGED
@@ -1,7 +1,26 @@
1
- ### main [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.2...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
+
11
+ ### 0.40.4 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.3...0.40.4)]
12
+
13
+ Bugfix:
14
+
15
+ - Fix warning on handling console message.
16
+
17
+ ### 0.40.3 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.2...0.40.3)]
18
+
19
+ Bugfix:
20
+
21
+ - Prevent `Ctrl+C` from stopping Chrome [#196](https://github.com/YusukeIwaki/puppeteer-ruby/pull/196)
22
+
23
+
5
24
  ### 0.40.2 [[diff](https://github.com/YusukeIwaki/puppeteer-ruby/compare/0.40.1...0.40.2)]
6
25
 
7
26
  Bugfix:
data/docs/api_coverage.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # API coverages
2
- - Puppeteer version: v13.0.1
3
- - puppeteer-ruby version: 0.40.2
2
+ - Puppeteer version: v13.5.1
3
+ - puppeteer-ruby version: 0.40.4
4
4
 
5
5
  ## Puppeteer
6
6
 
@@ -204,7 +204,7 @@
204
204
 
205
205
  * args
206
206
  * location
207
- * ~~stackTrace~~
207
+ * stackTrace => `#stack_trace`
208
208
  * text
209
209
  * ~~type~~
210
210
 
@@ -337,6 +337,7 @@
337
337
  * status
338
338
  * statusText => `#status_text`
339
339
  * text
340
+ * ~~timing~~
340
341
  * url
341
342
 
342
343
  ## ~~SecurityDetails~~
@@ -31,7 +31,9 @@ class Puppeteer::BrowserRunner
31
31
  [executable_path]
32
32
  end
33
33
 
34
- stdin, @stdout, @stderr, @thread = Open3.popen3(env, executable_path, *args)
34
+ popen3_args = args || []
35
+ popen3_args << { pgroup: true } unless Puppeteer.env.windows?
36
+ stdin, @stdout, @stderr, @thread = Open3.popen3(env, executable_path, *popen3_args)
35
37
  stdin.close
36
38
  @pid = @thread.pid
37
39
  rescue Errno::ENOENT => err
@@ -12,13 +12,23 @@ class Puppeteer::ConsoleMessage
12
12
  # @param log_type [String]
13
13
  # @param text [String]
14
14
  # @param args [Array<Puppeteer::JSHandle>]
15
- # @param location [Location]
16
- def initialize(log_type, text, args, location)
15
+ # @param stack_trace_locations [Array<Location>]
16
+ def initialize(log_type, text, args, stack_trace_locations)
17
17
  @log_type = log_type
18
18
  @text = text
19
19
  @args = args
20
- @location = location
20
+ @stack_trace_locations = stack_trace_locations
21
21
  end
22
22
 
23
- attr_reader :log_type, :text, :args, :location
23
+ attr_reader :log_type, :text, :args
24
+
25
+ # @return [Location]
26
+ def location
27
+ @stack_trace_locations.first
28
+ end
29
+
30
+ # @return [Array<Location>]
31
+ def stack_trace
32
+ @stack_trace_locations
33
+ end
24
34
  end
@@ -262,6 +262,58 @@ Puppeteer::DEVICES = Hash[
262
262
  isLandscape: true,
263
263
  },
264
264
  },
265
+ {
266
+ name: 'iPad (gen 6)',
267
+ userAgent:
268
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
269
+ viewport: {
270
+ width: 768,
271
+ height: 1024,
272
+ deviceScaleFactor: 2,
273
+ isMobile: true,
274
+ hasTouch: true,
275
+ isLandscape: false,
276
+ },
277
+ },
278
+ {
279
+ name: 'iPad (gen 6) landscape',
280
+ userAgent:
281
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
282
+ viewport: {
283
+ width: 1024,
284
+ height: 768,
285
+ deviceScaleFactor: 2,
286
+ isMobile: true,
287
+ hasTouch: true,
288
+ isLandscape: true,
289
+ },
290
+ },
291
+ {
292
+ name: 'iPad (gen 7)',
293
+ userAgent:
294
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
295
+ viewport: {
296
+ width: 810,
297
+ height: 1080,
298
+ deviceScaleFactor: 2,
299
+ isMobile: true,
300
+ hasTouch: true,
301
+ isLandscape: false,
302
+ },
303
+ },
304
+ {
305
+ name: 'iPad (gen 7) landscape',
306
+ userAgent:
307
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
308
+ viewport: {
309
+ width: 1080,
310
+ height: 810,
311
+ deviceScaleFactor: 2,
312
+ isMobile: true,
313
+ hasTouch: true,
314
+ isLandscape: true,
315
+ },
316
+ },
265
317
  {
266
318
  name: 'iPad Mini',
267
319
  userAgent:
@@ -314,6 +366,32 @@ Puppeteer::DEVICES = Hash[
314
366
  isLandscape: true,
315
367
  },
316
368
  },
369
+ {
370
+ name: 'iPad Pro 11',
371
+ userAgent:
372
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
373
+ viewport: {
374
+ width: 834,
375
+ height: 1194,
376
+ deviceScaleFactor: 2,
377
+ isMobile: true,
378
+ hasTouch: true,
379
+ isLandscape: false,
380
+ },
381
+ },
382
+ {
383
+ name: 'iPad Pro 11 landscape',
384
+ userAgent:
385
+ 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
386
+ viewport: {
387
+ width: 1194,
388
+ height: 834,
389
+ deviceScaleFactor: 2,
390
+ isMobile: true,
391
+ hasTouch: true,
392
+ isLandscape: true,
393
+ },
394
+ },
317
395
  {
318
396
  name: 'iPhone 4',
319
397
  userAgent:
@@ -678,6 +756,214 @@ Puppeteer::DEVICES = Hash[
678
756
  isLandscape: true,
679
757
  },
680
758
  },
759
+ {
760
+ name: 'iPhone 12',
761
+ userAgent:
762
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
763
+ viewport: {
764
+ width: 390,
765
+ height: 844,
766
+ deviceScaleFactor: 3,
767
+ isMobile: true,
768
+ hasTouch: true,
769
+ isLandscape: false,
770
+ },
771
+ },
772
+ {
773
+ name: 'iPhone 12 landscape',
774
+ userAgent:
775
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
776
+ viewport: {
777
+ width: 844,
778
+ height: 390,
779
+ deviceScaleFactor: 3,
780
+ isMobile: true,
781
+ hasTouch: true,
782
+ isLandscape: true,
783
+ },
784
+ },
785
+ {
786
+ name: 'iPhone 12 Pro',
787
+ userAgent:
788
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
789
+ viewport: {
790
+ width: 390,
791
+ height: 844,
792
+ deviceScaleFactor: 3,
793
+ isMobile: true,
794
+ hasTouch: true,
795
+ isLandscape: false,
796
+ },
797
+ },
798
+ {
799
+ name: 'iPhone 12 Pro landscape',
800
+ userAgent:
801
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
802
+ viewport: {
803
+ width: 844,
804
+ height: 390,
805
+ deviceScaleFactor: 3,
806
+ isMobile: true,
807
+ hasTouch: true,
808
+ isLandscape: true,
809
+ },
810
+ },
811
+ {
812
+ name: 'iPhone 12 Pro Max',
813
+ userAgent:
814
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
815
+ viewport: {
816
+ width: 428,
817
+ height: 926,
818
+ deviceScaleFactor: 3,
819
+ isMobile: true,
820
+ hasTouch: true,
821
+ isLandscape: false,
822
+ },
823
+ },
824
+ {
825
+ name: 'iPhone 12 Pro Max landscape',
826
+ userAgent:
827
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
828
+ viewport: {
829
+ width: 926,
830
+ height: 428,
831
+ deviceScaleFactor: 3,
832
+ isMobile: true,
833
+ hasTouch: true,
834
+ isLandscape: true,
835
+ },
836
+ },
837
+ {
838
+ name: 'iPhone 12 Mini',
839
+ userAgent:
840
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
841
+ viewport: {
842
+ width: 375,
843
+ height: 812,
844
+ deviceScaleFactor: 3,
845
+ isMobile: true,
846
+ hasTouch: true,
847
+ isLandscape: false,
848
+ },
849
+ },
850
+ {
851
+ name: 'iPhone 12 Mini landscape',
852
+ userAgent:
853
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
854
+ viewport: {
855
+ width: 812,
856
+ height: 375,
857
+ deviceScaleFactor: 3,
858
+ isMobile: true,
859
+ hasTouch: true,
860
+ isLandscape: true,
861
+ },
862
+ },
863
+ {
864
+ name: 'iPhone 13',
865
+ userAgent:
866
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
867
+ viewport: {
868
+ width: 390,
869
+ height: 844,
870
+ deviceScaleFactor: 3,
871
+ isMobile: true,
872
+ hasTouch: true,
873
+ isLandscape: false,
874
+ },
875
+ },
876
+ {
877
+ name: 'iPhone 13 landscape',
878
+ userAgent:
879
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
880
+ viewport: {
881
+ width: 844,
882
+ height: 390,
883
+ deviceScaleFactor: 3,
884
+ isMobile: true,
885
+ hasTouch: true,
886
+ isLandscape: true,
887
+ },
888
+ },
889
+ {
890
+ name: 'iPhone 13 Pro',
891
+ userAgent:
892
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
893
+ viewport: {
894
+ width: 390,
895
+ height: 844,
896
+ deviceScaleFactor: 3,
897
+ isMobile: true,
898
+ hasTouch: true,
899
+ isLandscape: false,
900
+ },
901
+ },
902
+ {
903
+ name: 'iPhone 13 Pro landscape',
904
+ userAgent:
905
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
906
+ viewport: {
907
+ width: 844,
908
+ height: 390,
909
+ deviceScaleFactor: 3,
910
+ isMobile: true,
911
+ hasTouch: true,
912
+ isLandscape: true,
913
+ },
914
+ },
915
+ {
916
+ name: 'iPhone 13 Pro Max',
917
+ userAgent:
918
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
919
+ viewport: {
920
+ width: 428,
921
+ height: 926,
922
+ deviceScaleFactor: 3,
923
+ isMobile: true,
924
+ hasTouch: true,
925
+ isLandscape: false,
926
+ },
927
+ },
928
+ {
929
+ name: 'iPhone 13 Pro Max landscape',
930
+ userAgent:
931
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
932
+ viewport: {
933
+ width: 926,
934
+ height: 428,
935
+ deviceScaleFactor: 3,
936
+ isMobile: true,
937
+ hasTouch: true,
938
+ isLandscape: true,
939
+ },
940
+ },
941
+ {
942
+ name: 'iPhone 13 Mini',
943
+ userAgent:
944
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
945
+ viewport: {
946
+ width: 375,
947
+ height: 812,
948
+ deviceScaleFactor: 3,
949
+ isMobile: true,
950
+ hasTouch: true,
951
+ isLandscape: false,
952
+ },
953
+ },
954
+ {
955
+ name: 'iPhone 13 Mini landscape',
956
+ userAgent:
957
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1',
958
+ viewport: {
959
+ width: 812,
960
+ height: 375,
961
+ deviceScaleFactor: 3,
962
+ isMobile: true,
963
+ hasTouch: true,
964
+ isLandscape: true,
965
+ },
966
+ },
681
967
  {
682
968
  name: 'JioPhone 2',
683
969
  userAgent:
@@ -1133,6 +1419,84 @@ Puppeteer::DEVICES = Hash[
1133
1419
  isLandscape: true,
1134
1420
  },
1135
1421
  },
1422
+ {
1423
+ name: 'Pixel 4a (5G)',
1424
+ userAgent:
1425
+ 'Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1426
+ viewport: {
1427
+ width: 353,
1428
+ height: 745,
1429
+ deviceScaleFactor: 3,
1430
+ isMobile: true,
1431
+ hasTouch: true,
1432
+ isLandscape: false,
1433
+ },
1434
+ },
1435
+ {
1436
+ name: 'Pixel 4a (5G) landscape',
1437
+ userAgent:
1438
+ 'Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1439
+ viewport: {
1440
+ width: 745,
1441
+ height: 353,
1442
+ deviceScaleFactor: 3,
1443
+ isMobile: true,
1444
+ hasTouch: true,
1445
+ isLandscape: true,
1446
+ },
1447
+ },
1448
+ {
1449
+ name: 'Pixel 5',
1450
+ userAgent:
1451
+ 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1452
+ viewport: {
1453
+ width: 393,
1454
+ height: 851,
1455
+ deviceScaleFactor: 3,
1456
+ isMobile: true,
1457
+ hasTouch: true,
1458
+ isLandscape: false,
1459
+ },
1460
+ },
1461
+ {
1462
+ name: 'Pixel 5 landscape',
1463
+ userAgent:
1464
+ 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1465
+ viewport: {
1466
+ width: 851,
1467
+ height: 393,
1468
+ deviceScaleFactor: 3,
1469
+ isMobile: true,
1470
+ hasTouch: true,
1471
+ isLandscape: true,
1472
+ },
1473
+ },
1474
+ {
1475
+ name: 'Moto G4',
1476
+ userAgent:
1477
+ 'Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1478
+ viewport: {
1479
+ width: 360,
1480
+ height: 640,
1481
+ deviceScaleFactor: 3,
1482
+ isMobile: true,
1483
+ hasTouch: true,
1484
+ isLandscape: false,
1485
+ },
1486
+ },
1487
+ {
1488
+ name: 'Moto G4 landscape',
1489
+ userAgent:
1490
+ 'Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4812.0 Mobile Safari/537.36',
1491
+ viewport: {
1492
+ width: 640,
1493
+ height: 360,
1494
+ deviceScaleFactor: 3,
1495
+ isMobile: true,
1496
+ hasTouch: true,
1497
+ isLandscape: true,
1498
+ },
1499
+ },
1136
1500
  ].map do |json|
1137
1501
  [
1138
1502
  json[:name],
@@ -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)
@@ -582,18 +582,19 @@ class Puppeteer::Page
582
582
  private def add_console_message(type, args, stack_trace)
583
583
  text_tokens = args.map { |arg| arg.remote_object.value }
584
584
 
585
- call_frame = stack_trace['callFrames']&.first
586
- location =
587
- if call_frame
588
- Puppeteer::ConsoleMessage::Location.new(
589
- url: call_frame['url'],
590
- line_number: call_frame['lineNumber'],
591
- column_number: call_frame['columnNumber'],
592
- )
585
+ stack_trace_locations =
586
+ if stack_trace && stack_trace['callFrames']
587
+ stack_trace['callFrames'].map do |call_frame|
588
+ Puppeteer::ConsoleMessage::Location.new(
589
+ url: call_frame['url'],
590
+ line_number: call_frame['lineNumber'],
591
+ column_number: call_frame['columnNumber'],
592
+ )
593
+ end
593
594
  else
594
- nil
595
+ []
595
596
  end
596
- console_message = Puppeteer::ConsoleMessage.new(type, text_tokens.join(' '), args, location)
597
+ console_message = Puppeteer::ConsoleMessage.new(type, text_tokens.join(' '), args, stack_trace_locations)
597
598
  emit_event(PageEmittedEvents::Console, console_message)
598
599
  end
599
600
 
@@ -1,3 +1,3 @@
1
1
  module Puppeteer
2
- VERSION = '0.40.2'
2
+ VERSION = '0.40.5'
3
3
  end
@@ -30,9 +30,9 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency 'pry-byebug'
31
31
  spec.add_development_dependency 'rake', '~> 13.0.3'
32
32
  spec.add_development_dependency 'rollbar'
33
- spec.add_development_dependency 'rspec', '~> 3.10.0 '
33
+ spec.add_development_dependency 'rspec', '~> 3.11.0'
34
34
  spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
35
- spec.add_development_dependency 'rubocop', '~> 1.24.0'
35
+ spec.add_development_dependency 'rubocop', '~> 1.26.0'
36
36
  spec.add_development_dependency 'rubocop-rspec'
37
37
  spec.add_development_dependency 'sinatra'
38
38
  spec.add_development_dependency 'webrick'
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.2
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-02-01 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
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 3.10.0
145
+ version: 3.11.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 3.10.0
152
+ version: 3.11.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: rspec_junit_formatter
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +170,14 @@ dependencies:
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: 1.24.0
173
+ version: 1.26.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: 1.24.0
180
+ version: 1.26.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: rubocop-rspec
183
183
  requirement: !ruby/object:Gem::Requirement
@@ -347,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
347
347
  - !ruby/object:Gem::Version
348
348
  version: '0'
349
349
  requirements: []
350
- rubygems_version: 3.3.3
350
+ rubygems_version: 3.3.7
351
351
  signing_key:
352
352
  specification_version: 4
353
353
  summary: A ruby port of puppeteer