File Coverage

blib/lib/Selenium/UserAgent.pm
Criterion Covered Total %
statement 69 70 98.5
branch 7 12 58.3
condition 3 6 50.0
subroutine 17 17 100.0
pod 1 1 100.0
total 97 106 91.5


line stmt bran cond sub pod time code
1             package Selenium::UserAgent;
2             $Selenium::UserAgent::VERSION = '0.10';
3             # ABSTRACT: Emulate mobile devices by setting user agents when using webdriver
4 3     3   271649 use Moo;
  3         17873  
  3         14  
5 3     3   3311 use JSON;
  3         9128  
  3         15  
6 3     3   324 use Cwd qw/abs_path/;
  3         8  
  3         109  
7 3     3   9 use Carp qw/croak/;
  3         803  
  3         122  
8 3     3   10 use List::Util 1.33 qw/any/;
  3         53  
  3         196  
9 3     3   1200 use Selenium::Firefox::Profile;
  3         238820  
  3         2213  
10              
11              
12             has browserName => (
13             is => 'rw',
14             required => 1,
15             coerce => sub {
16             my $browser = $_[0];
17              
18             croak 'Only chrome and firefox are supported.'
19             unless $browser =~ /chrome|firefox/;
20             return lc($browser)
21             }
22             );
23              
24              
25             has agent => (
26             is => 'rw',
27             required => 1,
28             coerce => sub {
29             my $agent = $_[0];
30              
31             my @valid = qw/
32             iphone4
33             iphone5
34             iphone6
35             iphone6plus
36             ipad_mini
37             ipad
38             galaxy_s3
39             galaxy_s4
40             galaxy_s5
41             galaxy_note3
42             nexus4
43             nexus9
44             nexus10
45             /;
46              
47             my $updated_agent = _convert_deprecated_agent( $agent );
48              
49             if (any { $_ eq $updated_agent } @valid) {
50             return $updated_agent;
51             }
52             else {
53             croak 'invalid agent: "' . $agent . '"';
54             }
55             }
56             );
57              
58             sub _convert_deprecated_agent {
59 72     72   74 my ($agent) = @_;
60              
61 72         358 my %deprecated = (
62             iphone => 'iphone4',
63             ipad_seven => 'ipad',
64             android_phone => 'nexus4',
65             android_tablet => 'nexus10'
66             );
67              
68 72 100       154 if ( exists $deprecated{ $agent }) {
69             # Attempt to return the updated agent key as of v0.06 that will be able to
70             # pass the coercion
71 19         45 return $deprecated{ $agent };
72             }
73             else {
74 53         149 return $agent;
75             }
76             }
77              
78              
79             has orientation => (
80             is => 'rw',
81             coerce => sub {
82             croak 'Invalid orientation; please choose "portrait" or "landscape'
83             unless $_[0] =~ /portrait|landscape/;
84             return $_[0];
85             },
86             default => 'portrait'
87             );
88              
89             has _firefox_options => (
90             is => 'ro',
91             lazy => 1,
92             builder => sub {
93 35     35   495 my ($self) = @_;
94              
95 35         62 my $dim = $self->_get_size;
96              
97 35         321 my $profile = Selenium::Firefox::Profile->new;
98 35         11883 $profile->set_preference(
99             'general.useragent.override' => $self->_get_user_agent
100             );
101              
102             return {
103 35         1268 firefox_profile => $profile
104             };
105             }
106             );
107              
108             has _chrome_options => (
109             is => 'ro',
110             lazy => 1,
111             builder => sub {
112 34     34   446 my ($self) = @_;
113              
114 34         41 my $size = $self->_get_size;
115 34         81 my $window_size = $size->{width} . ',' . $size->{height};
116              
117             return {
118             chromeOptions => {
119             args => [
120             'user-agent=' . $self->_get_user_agent,
121             ],
122             mobileEmulation => {
123             deviceMetrics => {
124             width => $size->{width} + 0,
125             height => $size->{height} + 0,
126             pixelRatio => $size->{pixel_ratio}
127             },
128 34         50 userAgent => $self->_get_user_agent
129             }
130             }
131             }
132             }
133             );
134              
135             has _specs => (
136             is => 'ro',
137             builder => sub {
138 72     72   169297 my $devices_file = abs_path(__FILE__);
139 72         437 $devices_file =~ s/UserAgent\.pm$/devices.json/;
140              
141 72         114 my $devices;
142             {
143 72         99 local $/ = undef;
  72         215  
144 72         2499 open (my $fh, "<", $devices_file);
145 72         1719 $devices = from_json(<$fh>);
146 72         4826 close ($fh);
147             }
148              
149 72         1475 return $devices;
150             }
151             );
152              
153              
154             sub caps {
155 69     69 1 629 my ($self, %args) = @_;
156              
157 69         142 my $options = $self->_desired_options(%args);
158              
159             return {
160 69         16575 inner_window_size => $self->_get_size_for('caps'),
161             desired_capabilities => {
162             browserName => $self->browserName,
163             %$options
164             }
165             };
166             }
167              
168             sub _desired_options {
169 69     69   84 my ($self, %args) = @_;
170              
171 69         65 my $options;
172 69 100       104 if ($self->_is_chrome) {
    50          
173 34         593 $options = $self->_chrome_options;
174             }
175             elsif ($self->_is_firefox) {
176 35         711 $options = $self->_firefox_options;
177              
178 35 50 66     93 unless (%args && exists $args{unencoded} && $args{unencoded}) {
      33        
179 34         105 $options->{firefox_profile} = $options->{firefox_profile}->_encode;
180             }
181             }
182              
183 69         178180 return $options;
184             }
185              
186             sub _get_user_agent {
187 103     103   93 my ($self) = @_;
188              
189 103         119 my $specs = $self->_specs;
190 103         1489 my $agent = $self->agent;
191              
192 103         709 return $specs->{$agent}->{user_agent};
193             }
194              
195             sub _get_size {
196 138     138   166 my ($self) = @_;
197              
198 138         254 my $specs = $self->_specs;
199 138         2559 my $agent = $self->agent;
200 138         2648 my $orientation = $self->orientation;
201              
202 138         977 my $size = $specs->{$agent}->{$orientation};
203 138         206 $size->{pixel_ratio} = $specs->{$agent}->{pixel_ratio};
204              
205 138         193 return $size;
206             }
207              
208             sub _get_size_for {
209 69     69   142 my ($self, $format) = @_;
210 69         127 my $dim = $self->_get_size;
211              
212 69 50       148 if ($format eq 'caps') {
    0          
213 69         1118 return [ $dim->{height}, $dim->{width} ];
214             }
215             elsif ($format eq 'chrome') {
216 0         0 return $dim->{width} . ',' . $dim->{height};
217             }
218             }
219              
220             sub _is_firefox {
221 35     35   1063 return shift->browserName =~ /firefox/i
222             }
223              
224             sub _is_chrome {
225 69     69   958 return shift->browserName =~ /chrome/i
226             }
227              
228             1;
229              
230             __END__