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 +4 -4
- data/CHANGELOG.md +20 -1
- data/docs/api_coverage.md +4 -3
- data/lib/puppeteer/browser_runner.rb +3 -1
- data/lib/puppeteer/console_message.rb +14 -4
- data/lib/puppeteer/devices.rb +364 -0
- 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 +13 -12
- data/lib/puppeteer/version.rb +1 -1
- data/puppeteer-ruby.gemspec +2 -2
- metadata +7 -7
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,26 @@
|
|
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
|
+
|
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.
|
3
|
-
- puppeteer-ruby version: 0.40.
|
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
|
-
*
|
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
|
-
|
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
|
16
|
-
def initialize(log_type, text, args,
|
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
|
-
@
|
20
|
+
@stack_trace_locations = stack_trace_locations
|
21
21
|
end
|
22
22
|
|
23
|
-
attr_reader :log_type, :text, :args
|
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
|
data/lib/puppeteer/devices.rb
CHANGED
@@ -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
|
-
|
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)
|
@@ -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
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
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
|
-
|
595
|
+
[]
|
595
596
|
end
|
596
|
-
console_message = Puppeteer::ConsoleMessage.new(type, text_tokens.join(' '), args,
|
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
|
|
data/lib/puppeteer/version.rb
CHANGED
data/puppeteer-ruby.gemspec
CHANGED
@@ -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.
|
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.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
350
|
+
rubygems_version: 3.3.7
|
351
351
|
signing_key:
|
352
352
|
specification_version: 4
|
353
353
|
summary: A ruby port of puppeteer
|