File Coverage

blib/lib/Appium.pm
Criterion Covered Total %
statement 148 149 99.3
branch 13 20 65.0
condition 2 3 66.6
subroutine 41 41 100.0
pod 25 28 89.2
total 229 241 95.0


line stmt bran cond sub pod time code
1             package Appium;
2             $Appium::VERSION = '0.0804';
3             # ABSTRACT: Perl bindings to the Appium mobile automation framework (WIP)
4 5     5   12847 use Carp qw/croak/;
  5         23  
  5         333  
5 5     5   31 use feature qw/state/;
  5         10  
  5         496  
6 5     5   1602 use Moo;
  5         37730  
  5         27  
7 5     5   8454 use MooX::Aliases 0.001005;
  5         20921  
  5         32  
8              
9 5     5   3818 use Appium::Commands;
  5         24  
  5         157  
10 5     5   1882 use Appium::Element;
  5         40  
  5         159  
11 5     5   2221 use Appium::ErrorHandler;
  5         16  
  5         155  
12 5     5   2151 use Appium::SwitchTo;
  5         19  
  5         154  
13 5     5   2170 use Appium::TouchActions;
  5         41  
  5         189  
14              
15 5     5   4666 use Selenium::Remote::Driver 0.2202;
  5         1110208  
  5         200  
16 5     5   45 use Selenium::Remote::RemoteConnection;
  5         9  
  5         323  
17             extends 'Selenium::Remote::Driver';
18              
19              
20              
21             use constant FINDERS => {
22 5         9 %{ Selenium::Remote::Driver->FINDERS },
  5         9706  
23             ios => '-ios uiautomation',
24             ios_uiautomation => '-ios uiautomation',
25             android => '-android uiautomator',
26             android_uiautomator => '-android uiautomator',
27             accessibility_id => 'accessibility id'
28 5     5   29 };
  5         15  
29              
30             has 'desired_capabilities' => (
31             is => 'rw',
32             required => 1,
33             alias => 'caps',
34             predicate => 1
35             );
36              
37             has '_type' => (
38             is => 'rw',
39             lazy => 1,
40             coerce => sub {
41             my $device = shift || 'iOS';
42              
43             croak 'platformName must be Android or iOS'
44             unless grep { $_ eq $device } qw/Android iOS/;
45              
46             return $device;
47             }
48             );
49              
50             has '+remote_server_addr' => (
51             is => 'ro',
52             default => sub { 'localhost' }
53             );
54              
55             has '+port' => (
56             is => 'ro',
57             default => sub { 4723 }
58             );
59              
60             has '+commands' => (
61             is => 'ro',
62             default => sub { Appium::Commands->new }
63             );
64              
65             has '+remote_conn' => (
66             is => 'ro',
67             lazy => 1,
68             builder => sub {
69 5     5   5081 my $self = shift;
70 5         87 return Selenium::Remote::RemoteConnection->new(
71             remote_server_addr => $self->remote_server_addr,
72             port => $self->port,
73             ua => $self->ua,
74             error_handler => Appium::ErrorHandler->new
75             );
76             }
77             );
78              
79             has 'touch_actions' => (
80             is => 'ro',
81             lazy => 1,
82             init_arg => undef,
83             handles => [ qw/tap/ ],
84             default => sub { Appium::TouchActions->new( driver => shift ); }
85             );
86              
87              
88             has 'webelement_class' => (
89             is => 'rw',
90             default => sub { 'Appium::Element' }
91             );
92              
93             sub BUILD {
94 5     5 0 11630 my ($self) = @_;
95              
96 5         141 $self->_type($self->desired_capabilities->{platformName});
97              
98 5 50       85 Moo::Role->apply_roles_to_object( $self, 'Appium::Ios::CanPage' )
99             if $self->is_ios;
100              
101 5 50       3139 Moo::Role->apply_roles_to_object( $self, 'Appium::Android::CanPage' )
102             if $self->is_android;
103             }
104              
105              
106             sub contexts {
107 1     1 1 384 my ($self) = @_;
108              
109 1         4 my $res = { command => 'contexts' };
110 1         3 return $self->_execute_command( $res );
111             }
112              
113              
114             sub current_context {
115 1     1 1 406 my ($self) = @_;
116              
117 1         4 my $res = { command => 'get_current_context' };
118 1         3 my $params = {};
119              
120 1         4 return $self->_execute_command( $res, $params );
121             }
122              
123              
124             has 'switch_to' => (
125             is => 'lazy',
126             init_arg => undef,
127             default => sub { Appium::SwitchTo->new( driver => shift ); }
128             );
129              
130              
131             sub hide_keyboard {
132 4     4 1 3282 my ($self, %args) = @_;
133              
134 4         14 my $res = { command => 'hide_keyboard' };
135 4         7 my $params = {};
136              
137 4 100       19 if (exists $args{key_name}) {
    100          
138             $params->{keyName} = $args{key_name}
139 1         6 }
140             elsif (exists $args{key}) {
141             $params->{key} = $args{key}
142 1         4 }
143              
144             # default strategy is tapOutside
145 4         6 my $strategy = 'tapOutside';
146 4   66     23 $params->{strategy} = $args{strategy} || $strategy;
147              
148 4         13 return $self->_execute_command( $res, $params );
149             }
150              
151              
152             sub app_strings {
153 1     1 1 435 my ($self, $language) = @_;
154              
155 1         5 my $res = { command => 'app_strings' };
156 1         1 my $params;
157 1 50       5 if (defined $language ) {
158 1         3 $params = { language => $language }
159             }
160             else {
161 0         0 $params = {};
162             }
163              
164 1         4 return $self->_execute_command( $res, $params );
165             }
166              
167              
168             sub reset {
169 1     1 1 375 my ($self) = @_;
170              
171 1         5 my $res = { command => 'reset' };
172              
173 1         4 return $self->_execute_command( $res );
174             }
175              
176              
177             sub press_keycode {
178 2     2 1 1944 my ($self, $keycode, $metastate) = @_;
179              
180 2         7 my $res = { command => 'press_keycode' };
181 2         6 my $params = {
182             keycode => $keycode,
183             };
184              
185 2 100       7 $params->{metastate} = $metastate if $metastate;
186              
187 2         9 return $self->_execute_command( $res, $params );
188             }
189              
190              
191             sub long_press_keycode {
192 2     2 1 11980 my ($self, $keycode, $metastate) = @_;
193              
194 2         8 my $res = { command => 'long_press_keycode' };
195 2         5 my $params = {
196             keycode => $keycode,
197             };
198              
199 2 50       9 $params->{metastate} = $metastate if $metastate;
200              
201 2         9 return $self->_execute_command( $res, $params );
202             }
203              
204              
205             sub current_activity {
206 1     1 1 372 my ($self) = @_;
207              
208 1         3 my $res = { command => 'current_activity' };
209              
210 1         4 return $self->_execute_command( $res );
211             }
212              
213              
214             sub pull_file {
215 2     2 1 2430 my ($self, $path) = @_;
216 2 50       10 croak "Please specify a path to pull from the device"
217             unless defined $path;
218              
219 2         8 my $res = { command => 'pull_file' };
220 2         6 my $params = { path => $path };
221              
222 2         8 return $self->_execute_command( $res, $params );
223             }
224              
225              
226             sub pull_folder {
227 2     2 1 2286 my ($self, $path) = @_;
228 2 50       10 croak 'Please specify a folder path to pull'
229             unless defined $path;
230              
231 2         7 my $res = { command => 'pull_folder' };
232 2         6 my $params = { path => $path };
233              
234 2         17 return $self->_execute_command( $res, $params );
235             }
236              
237              
238             sub push_file {
239 2     2 1 2236 my ($self, $path, $data) = @_;
240              
241 2         7 my $res = { command => 'push_file' };
242 2         8 my $params = {
243             path => $path,
244             data => $data
245             };
246              
247 2         8 return $self->_execute_command( $res, $params );
248             }
249              
250              
251             # todo: add better examples of complex find
252              
253             sub complex_find {
254 2     2 1 2319 my ($self, @selector) = @_;
255 2 50       10 croak 'Please specify selection criteria'
256             unless scalar @selector;
257              
258 2         6 my $res = { command => 'complex_find' };
259 2         7 my $params = { selector => \@selector };
260              
261 2         7 return $self->_execute_command( $res, $params );
262             }
263              
264              
265             sub background_app {
266 2     2 1 6736 my ($self, $seconds) = @_;
267              
268 2         8 my $res = { command => 'background_app' };
269 2         7 my $params = { seconds => $seconds};
270              
271 2         8 return $self->_execute_command( $res, $params );
272             }
273              
274              
275             sub is_app_installed {
276 2     2 1 2343 my ($self, $bundle_id) = @_;
277              
278 2         26 my $res = { command => 'is_app_installed' };
279 2         6 my $params = { bundleId => $bundle_id };
280              
281 2         8 return $self->_execute_command( $res, $params );
282             }
283              
284              
285             sub install_app {
286 2     2 1 2265 my ($self, $app_path) = @_;
287              
288 2         33 my $res = { command => 'install_app' };
289 2         7 my $params = { appPath => $app_path };
290              
291 2         9 return $self->_execute_command( $res, $params );
292             }
293              
294              
295             sub remove_app {
296 2     2 1 2288 my ($self, $app_id) = @_;
297              
298 2         30 my $res = { command => 'remove_app' };
299 2         10 my $params = { appId => $app_id };
300              
301 2         12 return $self->_execute_command( $res, $params );
302             }
303              
304              
305             sub launch_app {
306 2     2 1 2308 my ($self) = @_;
307              
308 2         8 my $res = { command => 'launch_app' };
309 2         9 return $self->_execute_command( $res );
310             }
311              
312              
313             sub close_app {
314 2     2 1 1370 my ($self) = @_;
315              
316 2         7 my $res = { command => 'close_app' };
317 2         7 return $self->_execute_command( $res );
318             }
319              
320              
321             sub end_test_coverage {
322 2     2 1 3430 my ($self, $intent, $path) = @_;
323              
324 2         6 my $res = { command => 'end_test_coverage' };
325 2         8 my $params = {
326             intent => $intent,
327             path => $path
328             };
329              
330 2         8 return $self->_execute_command( $res, $params );
331             }
332              
333              
334             sub lock {
335 2     2 1 1271 my ($self, $seconds) = @_;
336              
337 2         7 my $res = { command => 'lock' };
338 2         8 my $params = { seconds => $seconds };
339              
340 2         8 return $self->_execute_command( $res, $params );
341             }
342              
343              
344             sub is_locked {
345 2     2 1 2308 my($self) = @_;
346              
347 2         16 my $res = { command => 'is_locked' };
348 2         8 return $self->_execute_command( $res );
349             }
350              
351              
352             sub shake {
353 2     2 1 1266 my ($self) = @_;
354              
355 2         15 my $res = { command => 'shake' };
356 2         12 return $self->_execute_command( $res );
357             }
358              
359              
360             sub open_notifications {
361 2     2 1 1263 my ($self) = @_;
362              
363 2         8 my $res = { command => 'open_notifications' };
364 2         8 return $self->_execute_command( $res );
365             }
366              
367              
368             sub network_connection {
369 2     2 1 1244 my ($self) = @_;
370              
371 2         8 my $res = { command => 'network_connection' };
372 2         17 return $self->_execute_command( $res );
373             }
374              
375              
376             sub set_network_connection {
377 2     2 1 1290 my ($self, $connection_bitmask) = @_;
378              
379 2         6 my $res = { command => 'set_network_connection' };
380 2         7 my $params = {
381             parameters => {
382             type => $connection_bitmask
383             }
384             };
385              
386 2         8 return $self->_execute_command( $res, $params );
387             }
388              
389              
390             sub is_android {
391 5     5 0 119 return shift->_type eq 'Android';
392             }
393              
394             sub is_ios {
395 5     5 0 84 return shift->_type eq 'iOS';
396             }
397              
398              
399              
400             1;
401              
402             __END__