line
stmt
bran
cond
sub
pod
time
code
1
package Brownie::Driver::SeleniumServer;
2
3
2
2
4166
use strict;
2
5
2
90
4
2
2
13
use warnings;
2
3
2
390
5
2
2
13
use parent 'Brownie::Driver';
2
5
2
18
6
2
2
3664
use Selenium::Remote::Driver;
2
959588
2
154
7
2
2
2302
use Selenium::Server;
2
23867
2
92
8
2
2
22
use Scalar::Util qw(blessed);
2
5
2
149
9
2
2
12
use URI;
2
5
2
59
10
2
2
13
use File::Slurp qw(write_file);
2
6
2
104
11
2
2
2135
use MIME::Base64 qw(decode_base64);
2
1737
2
146
12
13
2
2
13
use Brownie::XPath;
2
5
2
49
14
2
2
697
use Brownie::Node::SeleniumServer;
2
5
2
2315
15
16
our $NodeClass = 'Brownie::Node::SeleniumServer';
17
18
sub new {
19
0
0
1
0
my ($class, %args) = @_;
20
21
0
0
0
0
if ($ENV{SELENIUM_REMOTE_SERVER_HOST} && $ENV{SELENIUM_REMOTE_SERVER_PORT}) {
22
0
0
$args{server_host} = $ENV{SELENIUM_REMOTE_SERVER_HOST};
23
0
0
$args{server_port} = $ENV{SELENIUM_REMOTE_SERVER_PORT};
24
}
25
else {
26
0
0
my $server = $class->_create_selenium_server(%args);
27
0
0
0
if ($server) {
28
0
0
$args{server} = $server;
29
0
0
$args{server_host} = $server->host;
30
0
0
$args{server_port} = $server->port,
31
}
32
}
33
34
0
0
0
$args{browser_name} ||= ($ENV{SELENIUM_BROWSER_NAME} || 'firefox');
0
35
36
0
0
return $class->SUPER::new(%args);
37
}
38
39
sub _create_selenium_server {
40
0
0
0
my ($class, %args) = @_;
41
42
0
0
my $server = Selenium::Server->new;
43
0
0
0
$server->start if $server;
44
45
0
0
$server;
46
}
47
48
sub DESTROY {
49
5
5
9
my $self = shift;
50
51
5
24
delete $self->{browser};
52
53
5
50
36
if ($self->{server}) {
54
0
$self->{server}->stop;
55
0
delete $self->{server};
56
}
57
}
58
59
0
0
0
sub server_host { shift->{server_host} }
60
0
0
0
sub server_port { shift->{server_port} }
61
0
0
0
sub browser_name { shift->{browser_name} }
62
63
sub browser {
64
0
0
1
my $self = shift;
65
66
0
0
$self->{browser} ||= Selenium::Remote::Driver->new(
67
remote_server_addr => $self->server_host,
68
port => $self->server_port,
69
browser_name => $self->browser_name,
70
);
71
72
0
return $self->{browser};
73
}
74
75
sub visit {
76
0
0
1
my ($self, $url) = @_;
77
0
$self->browser->get("$url"); # stringify for URI
78
}
79
80
sub current_url {
81
0
0
1
my $self = shift;
82
0
return URI->new($self->browser->get_current_url);
83
}
84
85
sub current_path {
86
0
0
1
my $self = shift;
87
0
return $self->current_url->path;
88
}
89
90
sub title {
91
0
0
1
my $self = shift;
92
0
return $self->browser->get_title;
93
}
94
95
sub source {
96
0
0
1
my $self = shift;
97
0
return $self->browser->get_page_source;
98
}
99
100
sub screenshot {
101
0
0
1
my ($self, $file) = @_;
102
0
my $image = decode_base64($self->browser->screenshot);
103
0
write_file($file, { binmode => ':raw' }, $image);
104
}
105
106
sub find {
107
0
0
1
my ($self, $locator, %args) = @_;
108
109
0
my $element;
110
0
my $xpath = Brownie::XPath::to_xpath($locator);
111
112
0
0
if (my $base = $args{base}) {
113
0
0
0
my $node = (blessed($base) and $base->can('native')) ? $base->native : $base;
114
0
0
$xpath = ".$xpath" unless $xpath =~ /^\./;
115
0
$element = eval { $self->browser->find_child_element($node, $xpath) }; # abs2rel
0
116
}
117
else {
118
0
$element = eval { $self->browser->find_element($xpath) };
0
119
}
120
121
0
0
return $element ? $NodeClass->new(driver => $self, native => $element) : undef;
122
}
123
124
sub all {
125
0
0
1
my ($self, $locator, %args) = @_;
126
127
0
my @elements = ();
128
0
my $xpath = Brownie::XPath::to_xpath($locator);
129
130
0
0
if (my $base = $args{base}) {
131
0
0
0
my $node = (blessed($base) and $base->can('native')) ? $base->native : $base;
132
0
0
$xpath = ".$xpath" unless $xpath =~ /^\./;
133
0
@elements = eval { $self->browser->find_child_elements($node, $xpath) }; # abs2rel
0
134
}
135
else {
136
0
@elements = eval { $self->browser->find_elements($xpath) };
0
137
}
138
139
0
0
return @elements ? map { $NodeClass->new(driver => $self, native => $_) } @elements : ();
0
140
}
141
142
sub execute_script {
143
0
0
1
my ($self, $script) = @_;
144
0
$self->browser->execute_script($script);
145
}
146
147
sub evaluate_script {
148
0
0
1
my ($self, $script) = @_;
149
0
return $self->browser->execute_script("return $script");
150
}
151
152
1;
153
154
=head1 NAME
155
156
Brownie::Driver::SeleniumServer - Selenium RemoteWebDriver bridge
157
158
=head1 SYNOPSIS
159
160
# use default browser (firefox)
161
my $driver = Brownie::Driver::SeleniumServer->new;
162
163
# specify browser
164
my $driver = Brownie::Driver::SeleniumServer->new(browser_name => 'chrome');
165
166
$driver->visit($url);
167
my $title = $driver->title;
168
169
=head1 METHODS
170
171
=head2 IMPLEMENTED
172
173
=over 4
174
175
=item * C
176
177
my $driver = Brownie::Driver::SeleniumServer->new(%args);
178
179
C<%args> are:
180
181
* browser_name: selenium-server's browser name (default: "firefox")
182
183
You can also set selenium-server parameters using C<%ENV>:
184
185
* SELENIUM_BROWSER_NAME
186
187
=item * C
188
189
=item * C
190
191
=item * C
192
193
=item * C
194
195
=item * C
196
197
=item * C
198
199
=item * C
200
201
=item * C
202
203
=item * C
204
205
=item * C
206
207
=item * C
208
209
=back
210
211
=head2 NOT SUPPORTED
212
213
=over 4
214
215
=item * C
216
217
=item * C
218
219
=back
220
221
=head1 TIPS
222
223
=head2 Use external selenium server
224
225
If you secify "SELENIUM_REMOTE_SERVER_HOST" and "SELENIUM_REMOTE_SERVER_PORT" enviromnent valiables, Brownie uses its server for selenium server. By this, you can quicken the execution of your tests.
226
227
=head1 AUTHOR
228
229
NAKAGAWA Masaki Emasaki@cpan.orgE
230
231
=head1 LICENSE
232
233
This library is free software; you can redistribute it and/or modify
234
it under the same terms as Perl itself.
235
236
=head1 SEE ALSO
237
238
L, L, L
239
240
L
241
242
L
243
244
=cut