| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Playwright::Util; |
|
2
|
|
|
|
|
|
|
$Playwright::Util::VERSION = '1.551'; |
|
3
|
3
|
|
|
3
|
|
148155
|
use strict; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
102
|
|
|
4
|
3
|
|
|
3
|
|
26
|
use warnings; |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
169
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
3
|
|
|
3
|
|
37
|
use v5.28; |
|
|
3
|
|
|
|
|
10
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
3
|
|
|
3
|
|
1154
|
use JSON::MaybeXS(); |
|
|
3
|
|
|
|
|
22442
|
|
|
|
3
|
|
|
|
|
92
|
|
|
9
|
3
|
|
|
3
|
|
19
|
use Carp qw{confess}; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
188
|
|
|
10
|
3
|
|
|
3
|
|
27
|
use Sereal::Encoder; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
111
|
|
|
11
|
3
|
|
|
3
|
|
15
|
use Sereal::Decoder; |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
88
|
|
|
12
|
3
|
|
|
3
|
|
2187
|
use File::Temp; |
|
|
3
|
|
|
|
|
57734
|
|
|
|
3
|
|
|
|
|
290
|
|
|
13
|
3
|
|
|
3
|
|
1262
|
use POSIX(); |
|
|
3
|
|
|
|
|
18098
|
|
|
|
3
|
|
|
|
|
102
|
|
|
14
|
3
|
|
|
3
|
|
27
|
use Scalar::Util qw{reftype}; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
165
|
|
|
15
|
3
|
|
|
3
|
|
17
|
use Cwd(); |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
62
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#ABSTRACT: Common utility functions for the Playwright module |
|
18
|
|
|
|
|
|
|
|
|
19
|
3
|
|
|
3
|
|
12
|
no warnings 'experimental'; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
158
|
|
|
20
|
3
|
|
|
3
|
|
15
|
use feature qw{signatures}; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
548
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
3
|
|
|
3
|
|
18
|
use constant IS_WIN => $^O eq 'MSWin32'; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
3941
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
3
|
|
|
3
|
|
526595
|
sub request ( $method, $url, $host, $port, $ua, %args ) { |
|
|
3
|
|
|
|
|
10
|
|
|
|
3
|
|
|
|
|
61
|
|
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
10
|
|
|
|
3
|
|
|
|
|
5
|
|
|
25
|
3
|
|
|
|
|
12
|
my $fullurl = "http://$host:$port/$url"; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# Handle passing Playwright elements as arguments |
|
28
|
|
|
|
|
|
|
# Seems we also pass Playwright pages to get CDP Handles |
|
29
|
3
|
50
|
|
|
|
17
|
if ( ref $args{args} eq 'ARRAY' ) { |
|
30
|
0
|
|
|
|
|
0
|
@{ $args{args} } = map { |
|
31
|
0
|
|
|
|
|
0
|
my $transformed = $_; |
|
32
|
0
|
0
|
0
|
|
|
0
|
if ( ref $_ && reftype $_ eq 'HASH' && exists $_->{guid} ) { |
|
|
|
|
0
|
|
|
|
|
|
33
|
0
|
|
|
|
|
0
|
$transformed = { uuid => $_->{guid} }; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
0
|
|
|
|
|
0
|
$transformed; |
|
36
|
0
|
|
|
|
|
0
|
} @{ $args{args} }; |
|
|
0
|
|
|
|
|
0
|
|
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
3
|
|
|
|
|
27
|
my $request = HTTP::Request->new( $method, $fullurl ); |
|
40
|
3
|
|
|
|
|
12635
|
$request->header( 'Content-type' => 'application/json' ); |
|
41
|
3
|
|
|
|
|
321
|
$request->content( JSON::MaybeXS::encode_json( \%args ) ); |
|
42
|
3
|
|
|
|
|
141
|
my $response = $ua->request($request); |
|
43
|
3
|
|
|
|
|
28
|
my $content = $response->decoded_content(); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# If we get this kind of response the server failed to come up :( |
|
46
|
3
|
50
|
|
|
|
23
|
die "playwright server failed to spawn!" |
|
47
|
|
|
|
|
|
|
if $content =~ m/^Can't connect to/; |
|
48
|
|
|
|
|
|
|
|
|
49
|
3
|
|
|
|
|
8
|
local $@; |
|
50
|
3
|
100
|
|
|
|
8
|
my $decoded = eval { JSON::MaybeXS::decode_json($content) } or do { |
|
|
3
|
|
|
|
|
51
|
|
|
51
|
1
|
|
|
|
|
418
|
confess( |
|
52
|
|
|
|
|
|
|
qq[error decoding Playwright server response: $@\ncontent:\n$content\n] |
|
53
|
|
|
|
|
|
|
); |
|
54
|
|
|
|
|
|
|
}; |
|
55
|
|
|
|
|
|
|
|
|
56
|
2
|
|
|
|
|
7
|
my $msg = $decoded->{message}; |
|
57
|
|
|
|
|
|
|
|
|
58
|
2
|
100
|
|
|
|
63
|
confess($msg) if $decoded->{error}; |
|
59
|
|
|
|
|
|
|
|
|
60
|
1
|
|
|
|
|
27
|
return $msg; |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
0
|
|
|
0
|
1
|
|
sub arr2hash ( $array, $primary_key, $callback = '' ) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
|
my $inside_out = {}; |
|
65
|
|
|
|
|
|
|
@$inside_out{ |
|
66
|
|
|
|
|
|
|
map { |
|
67
|
0
|
0
|
|
|
|
|
$callback ? $callback->( $_->{$primary_key} ) : $_->{$primary_key} |
|
|
0
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
} @$array |
|
69
|
|
|
|
|
|
|
} = @$array; |
|
70
|
0
|
|
|
|
|
|
return $inside_out; |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# Serialize a subprocess because NOTHING ON CPAN DOES THIS GRRRRR |
|
74
|
0
|
|
|
0
|
0
|
|
sub async ($subroutine) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# The fork would result in the tmpdir getting whacked when it terminates. |
|
77
|
0
|
|
|
|
|
|
my $fh = File::Temp->new(); |
|
78
|
0
|
|
0
|
|
|
|
my $pid = fork() // die "Could not fork"; |
|
79
|
0
|
0
|
|
|
|
|
_child( $fh->filename, $subroutine ) unless $pid; |
|
80
|
0
|
|
|
|
|
|
return { pid => $pid, file => $fh }; |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
|
|
83
|
0
|
|
|
0
|
|
|
sub _child ( $filename, $subroutine ) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
Sereal::Encoder->encode_to_file( $filename, $subroutine->() ); |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# Prevent destructors from firing due to exiting instantly...unless we are on windows, where they won't. |
|
87
|
0
|
|
|
|
|
|
POSIX::_exit(0) unless IS_WIN; |
|
88
|
0
|
|
|
|
|
|
exit 0; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
0
|
|
|
0
|
0
|
|
sub await ($to_wait) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
waitpid( $to_wait->{pid}, 0 ); |
|
93
|
|
|
|
|
|
|
confess("Timed out while waiting for event.") |
|
94
|
0
|
0
|
0
|
|
|
|
unless -f $to_wait->{file}->filename && -s _; |
|
95
|
0
|
|
|
|
|
|
return Sereal::Decoder->decode_from_file( $to_wait->{file}->filename ); |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Make author tests work |
|
99
|
|
|
|
|
|
|
sub find_node_modules { |
|
100
|
0
|
|
|
0
|
0
|
|
return _find('node_modules'); |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub find_playwright_server { |
|
104
|
0
|
|
|
0
|
0
|
|
return _find('bin/playwright_server'); |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _find { |
|
108
|
0
|
|
|
0
|
|
|
my $to_find = shift; |
|
109
|
|
|
|
|
|
|
my $dir = |
|
110
|
0
|
|
|
|
|
|
File::Basename::dirname( Cwd::abs_path( $INC{'Playwright/Util.pm'} ) ); |
|
111
|
0
|
|
|
|
|
|
while ( !-e "$dir/$to_find" ) { |
|
112
|
0
|
|
|
|
|
|
$dir = Cwd::abs_path("$dir/.."); |
|
113
|
0
|
0
|
|
|
|
|
last if $dir eq '/'; |
|
114
|
|
|
|
|
|
|
} |
|
115
|
0
|
|
|
|
|
|
return Cwd::abs_path("$dir/$to_find"); |
|
116
|
|
|
|
|
|
|
} |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
1; |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
__END__ |