File Coverage

blib/lib/Selenium/UserAgent.pm
Criterion Covered Total %
statement 68 73 93.1
branch 6 12 50.0
condition 3 6 50.0
subroutine 17 18 94.4
pod 1 1 100.0
total 95 110 86.3


line stmt bran cond sub pod time code
1             package Selenium::UserAgent;
2             $Selenium::UserAgent::VERSION = '0.11';
3             # ABSTRACT: Emulate mobile devices by setting user agents when using webdriver
4 3     3   364373 use Moo;
  3         16517  
  3         14  
5 3     3   2670 use JSON;
  3         7989  
  3         24  
6 3     3   329 use Cwd qw/abs_path/;
  3         8  
  3         119  
7 3     3   14 use Carp qw/croak/;
  3         5  
  3         111  
8 3     3   15 use List::Util 1.33 qw/any/;
  3         65  
  3         198  
9 3     3   893 use Selenium::Firefox::Profile;
  3         247840  
  3         2434  
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   129 my ($agent) = @_;
60              
61 72         316 my %deprecated = (
62             iphone => 'iphone4',
63             ipad_seven => 'ipad',
64             android_phone => 'nexus4',
65             android_tablet => 'nexus10'
66             );
67              
68 72 100       174 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         57 return $deprecated{ $agent };
72             }
73             else {
74 53         165 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   331 my ($self) = @_;
94              
95 35         106 my $dim = $self->_get_size;
96              
97 35         313 my $profile = Selenium::Firefox::Profile->new;
98 35         11322 $profile->set_preference(
99             'general.useragent.override' => $self->_get_user_agent
100             );
101              
102             return {
103 35         1244 firefox_profile => $profile
104             };
105             }
106             );
107              
108             has _chrome_options => (
109             is => 'ro',
110             lazy => 1,
111             builder => sub {
112 34     34   201 my ($self) = @_;
113              
114 34         55 my $size = $self->_get_size;
115 34         89 my $window_size = $size->{width} . ',' . $size->{height};
116              
117             return {
118 34         67 chromeOptions => {
119             args => [
120             'user-agent=' . $self->_get_user_agent,
121             ],
122             mobileEmulation => {
123             deviceName => $self->_agent_to_chrome
124             }
125             }
126             }
127             }
128             );
129              
130             has _specs => (
131             is => 'ro',
132             builder => sub {
133 72     72   99573 my $devices_file = abs_path(__FILE__);
134 72         553 $devices_file =~ s/UserAgent\.pm$/devices.json/;
135              
136 72         128 my $devices;
137             {
138 72         137 local $/ = undef;
  72         245  
139 72         1482 open (my $fh, "<", $devices_file);
140 72         1405 $devices = from_json(<$fh>);
141 72         4748 close ($fh);
142             }
143              
144 72         1504 return $devices;
145             }
146             );
147              
148              
149             sub caps {
150 69     69 1 676 my ($self, %args) = @_;
151              
152 69         152 my $options = $self->_desired_options(%args);
153              
154             return {
155             # inner_window_size => $self->_get_size_for('caps'),
156 69         13522 desired_capabilities => {
157             browserName => $self->browserName,
158             %$options
159             }
160             };
161             }
162              
163             sub _desired_options {
164 69     69   105 my ($self, %args) = @_;
165              
166 69         87 my $options;
167 69 100       114 if ($self->_is_chrome) {
    50          
168 34         637 $options = $self->_chrome_options;
169             }
170             elsif ($self->_is_firefox) {
171 35         1085 $options = $self->_firefox_options;
172              
173 35 50 66     98 unless (%args && exists $args{unencoded} && $args{unencoded}) {
      33        
174 34         99 $options->{firefox_profile} = $options->{firefox_profile}->_encode;
175             }
176             }
177              
178 69         193480 return $options;
179             }
180              
181             sub _get_user_agent {
182 69     69   103 my ($self) = @_;
183              
184 69         128 my $specs = $self->_specs;
185 69         1072 my $agent = $self->agent;
186              
187 69         564 return $specs->{$agent}->{user_agent};
188             }
189              
190             sub _get_size {
191 69     69   103 my ($self) = @_;
192              
193 69         146 my $specs = $self->_specs;
194 69         966 my $agent = $self->agent;
195 69         1201 my $orientation = $self->orientation;
196              
197 69         356 my $size = $specs->{$agent}->{$orientation};
198 69         134 $size->{pixel_ratio} = $specs->{$agent}->{pixel_ratio};
199              
200 69         120 return $size;
201             }
202              
203             sub _get_size_for {
204 0     0   0 my ($self, $format) = @_;
205 0         0 my $dim = $self->_get_size;
206              
207 0 0       0 if ($format eq 'caps') {
    0          
208 0         0 return [ $dim->{height}, $dim->{width} ];
209             }
210             elsif ($format eq 'chrome') {
211 0         0 return $dim->{width} . ',' . $dim->{height};
212             }
213             }
214              
215             sub _is_firefox {
216 35     35   826 return shift->browserName =~ /firefox/i
217             }
218              
219             sub _is_chrome {
220 69     69   971 return shift->browserName =~ /chrome/i
221             }
222              
223             sub _agent_to_chrome {
224 34     34   54 my ($self) = @_;
225              
226 34         226 my $map = {
227             iphone4 => 'iPhone 4',
228             iphone5 => 'iPhone 5',
229             iphone6 => 'iPhone 6',
230             iphone6plus => 'iPhone 6 Plus',
231             ipad_mini => 'iPad Mini',
232             ipad => 'iPad',
233             galaxy_s3 => 'Galaxy S III',
234             galaxy_s5 => 'Galaxy S5',
235             galaxy_note3 => 'Galaxy Note 3',
236             nexus4 => 'Nexus 4',
237             nexus9 => 'Nexus 10',
238             nexus10 => 'Nexus 10',
239             iphone => 'iPhone 4',
240             ipad_seven => 'iPad',
241             android_phone => 'Nexus 4',
242             android_tablet => 'Nexus 10'
243             };
244              
245 34         438 return $map->{$self->agent};
246             }
247              
248             1;
249              
250             __END__