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.09';
3             # ABSTRACT: Emulate mobile devices by setting user agents when using webdriver
4 3     3   295833 use Moo;
  3         20935  
  3         11  
5 3     3   3323 use JSON;
  3         9127  
  3         14  
6 3     3   284 use Cwd qw/abs_path/;
  3         7  
  3         113  
7 3     3   761 use Carp qw/croak/;
  3         5  
  3         105  
8 3     3   8 use List::Util qw/any/;
  3         3  
  3         205  
9 3     3   1180 use Selenium::Firefox::Profile;
  3         6128132  
  3         2214  
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   61 my ($agent) = @_;
60              
61 72         278 my %deprecated = (
62             iphone => 'iphone4',
63             ipad_seven => 'ipad',
64             android_phone => 'nexus4',
65             android_tablet => 'nexus10'
66             );
67              
68 72 100       135 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         43 return $deprecated{ $agent };
72             }
73             else {
74 53         115 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   447 my ($self) = @_;
94              
95 35         71 my $dim = $self->_get_size;
96              
97 35         239 my $profile = Selenium::Firefox::Profile->new;
98 35         9718 $profile->set_preference(
99             'general.useragent.override' => $self->_get_user_agent
100             );
101              
102             return {
103 35         1025 firefox_profile => $profile
104             };
105             }
106             );
107              
108             has _chrome_options => (
109             is => 'ro',
110             lazy => 1,
111             builder => sub {
112 34     34   459 my ($self) = @_;
113              
114 34         48 my $size = $self->_get_size;
115 34         79 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         52 userAgent => $self->_get_user_agent
129             }
130             }
131             }
132             }
133             );
134              
135             has _specs => (
136             is => 'ro',
137             builder => sub {
138 72     72   158929 my $devices_file = abs_path(__FILE__);
139 72         397 $devices_file =~ s/UserAgent\.pm$/devices.json/;
140              
141 72         86 my $devices;
142             {
143 72         89 local $/ = undef;
  72         193  
144 72         1907 open (my $fh, "<", $devices_file);
145 72         1488 $devices = from_json(<$fh>);
146 72         4529 close ($fh);
147             }
148              
149 72         1519 return $devices;
150             }
151             );
152              
153              
154             sub caps {
155 69     69 1 577 my ($self, %args) = @_;
156              
157 69         119 my $options = $self->_desired_options(%args);
158              
159             return {
160 69         13923 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   62 my ($self, %args) = @_;
170              
171 69         47 my $options;
172 69 100       91 if ($self->_is_chrome) {
    50          
173 34         612 $options = $self->_chrome_options;
174             }
175             elsif ($self->_is_firefox) {
176 35         688 $options = $self->_firefox_options;
177              
178 35 50 66     92 unless (%args && exists $args{unencoded} && $args{unencoded}) {
      33        
179 34         87 $options->{firefox_profile} = $options->{firefox_profile}->_encode;
180             }
181             }
182              
183 69         145764 return $options;
184             }
185              
186             sub _get_user_agent {
187 103     103   93 my ($self) = @_;
188              
189 103         132 my $specs = $self->_specs;
190 103         1489 my $agent = $self->agent;
191              
192 103         660 return $specs->{$agent}->{user_agent};
193             }
194              
195             sub _get_size {
196 138     138   114 my ($self) = @_;
197              
198 138         230 my $specs = $self->_specs;
199 138         2423 my $agent = $self->agent;
200 138         2589 my $orientation = $self->orientation;
201              
202 138         951 my $size = $specs->{$agent}->{$orientation};
203 138         172 $size->{pixel_ratio} = $specs->{$agent}->{pixel_ratio};
204              
205 138         165 return $size;
206             }
207              
208             sub _get_size_for {
209 69     69   119 my ($self, $format) = @_;
210 69         85 my $dim = $self->_get_size;
211              
212 69 50       119 if ($format eq 'caps') {
    0          
213 69         997 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   1041 return shift->browserName =~ /firefox/i
222             }
223              
224             sub _is_chrome {
225 69     69   957 return shift->browserName =~ /chrome/i
226             }
227              
228             1;
229              
230             __END__