File Coverage

blib/lib/WWW/Testafy.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package WWW::Testafy;
2              
3 1     1   20765 use strict;
  1         7  
  1         36  
4 1     1   5 use warnings;
  1         1  
  1         82  
5              
6             our $VERSION = 1.02;
7              
8             # Copyright 2012 Grant Street Group
9              
10             =head1 NAME
11              
12             WWW::Testafy - Testafy API for perl developers
13              
14             =head1 SYNOPSIS
15              
16             use WWW::Testafy;
17              
18             my $te = new WWW::Testafy;
19              
20             my $id = $te->run_test(
21             pbehave => qq{
22             For the url http://www.google.com
23             Given a test delay of 1 second
24             When the search query field is "Testafy"
25             Then the text "Did you mean: testify" is present
26             };
27             );
28              
29             my $passed = $te->test_passed($id);
30             my $planned = $te->test_planned($id);
31             print "Passed $passed tests out of $planned\n";
32             print $te->test_results_as_string($id);
33              
34             =cut
35              
36 1     1   398 use Moose;
  0            
  0            
37             use JSON;
38             use LWP::UserAgent;
39              
40             =head1 ATTRIBUTES
41              
42             =over
43              
44             =item base_api_uri - base URI of the api server
45              
46             =cut
47              
48             has 'base_api_uri' => (
49             is => 'rw',
50             isa => 'Str',
51             default => 'https://app.testafy.com/api/v0',
52             );
53              
54             has 'auth_realm' => (
55             is => 'rw',
56             isa => 'Str',
57             default => 'Testafy',
58             );
59              
60             has 'auth_netloc' => (
61             is => 'rw',
62             isa => 'Str',
63             default => 'app.testafy.com:443',
64             );
65            
66             =item response - HTTP::Response object received from the API server
67              
68             =cut
69              
70             has 'response' => (
71             is => 'rw',
72             isa => 'HTTP::Response',
73             );
74              
75             =item response_vars - hash of the JSON response
76              
77             =cut
78              
79             has 'response_vars' => (
80             is => 'rw',
81             isa => 'HashRef',
82             );
83              
84             =item ua - LWP::UserAgent object
85              
86             =cut
87              
88             has 'ua' => (
89             is => 'rw',
90             isa => 'LWP::UserAgent',
91             default => sub {
92             return LWP::UserAgent->new();
93             },
94             );
95              
96             has 'testafy_username' => (
97             is => 'rw',
98             isa => 'Str',
99             default => '',
100             );
101              
102             has 'testafy_password' => (
103             is => 'rw',
104             isa => 'Str',
105             default => '',
106             );
107              
108             =back
109              
110             =head1 METHODS
111              
112             =head2 Basic
113              
114             =head3 $self->make_api_request($api_command, $request_vars)
115              
116             Args: api_command - command to send to API server
117             $request_vars - hashref of values to be encoded into JSON
118              
119             Returns: HTTP::Response object received
120              
121             =cut
122              
123             sub make_api_request {
124             my ($self, $api_command, $request_vars) = @_;
125              
126             my $uri = $self->base_api_uri . '/' . $api_command;
127              
128             $request_vars->{login_name} = $self->testafy_username;
129             my $r = {
130             json => to_json($request_vars)
131             };
132              
133             $self->ua->credentials(
134             $self->auth_netloc,
135             $self->auth_realm,
136             $self->testafy_username,
137             $self->testafy_password,
138             );
139            
140             $self->response($self->ua->post($uri, $r));
141             if (my $content = $self->response->content) {
142             eval { $self->response_vars(from_json($content)); };
143             $self->response_vars({error => [ $content]}) if $@;
144             }
145              
146             return $self->response;
147             }
148              
149             =head3 $self->message
150              
151             Returns: value of 'message' key from JSON response
152              
153             =cut
154              
155             sub message {
156             my $self = shift;
157              
158             return $self->response_vars->{message} if $self->response_vars;
159             }
160              
161              
162             =head3 $self->error
163              
164             Returns: arrayref of error messages from JSON response
165              
166             =cut
167              
168             sub error {
169             my $self = shift;
170            
171             return $self->response_vars->{error} if $self->response_vars;
172             }
173              
174             =head3 $self->error_string
175              
176             Returns: formatted error strings (joined with newlines)
177              
178             =cut
179              
180             sub error_string {
181             my $self = shift;
182              
183             my $error = $self->error;
184             if ($error and @$error) {
185             return join("\n", @$error);
186             }
187             }
188              
189             =head2 Commands for tests
190              
191             =head3 $self->run_test(%args), including pbehave and browser
192              
193             If the asynchronous arg flag is set to 1, test is started in background.
194             Otherwise, it waits for test to completed. The default is 0.
195              
196             Args: %args - hash of arguments
197              
198             Returns: trt_id of entry created for test
199              
200             =cut
201              
202             sub run_test {
203             my $self = shift;
204              
205             my $args = {
206             verbose => 0,
207             @_,
208             };
209              
210             if ($args->{verbose}) {
211             print "Running test with these values:\n";
212             for my $key (qw(product pbehave)) {
213             print "\t$key: $args->{$key}\n" if defined $args->{$key};
214             }
215             }
216              
217             my $response = $self->make_api_request('test/run', $args);
218              
219             return $self->response_vars ? $self->response_vars->{test_run_test_id} : 0E0
220             if $response->is_success;
221              
222             print STDERR "Response code: ".$response->code."\n";
223             print STDERR "Error(s) while running test: ".join("\n", @{$self->error})
224             if $self->error;
225             return;
226             }
227              
228             =head3 $self->test_status($trt_id)
229              
230             Args: trt_id - test_run_test_id for test
231              
232             Returns: current status of the individual test run $trt_id.
233              
234             =cut
235              
236             sub test_status {
237             my ($self, $trt_id) = @_;
238              
239             my $args = {
240             trt_id => $trt_id,
241             };
242              
243             my $response = $self->make_api_request('test/status', $args);
244             if ($response->is_success) {
245             return $self->response_vars->{status};
246             }
247             }
248              
249             =head3 $self->test_planned($trt_id)
250              
251             Args: trt_id - test_run_test_id for test
252              
253             Returns: tests planned for the individual test run $trt_id.
254              
255             =cut
256              
257             sub test_planned {
258             my ($self, $trt_id) = @_;
259              
260             my $args = {
261             trt_id => $trt_id,
262             };
263              
264             my $response = $self->make_api_request('test/stats/planned', $args);
265             if ($response->is_success) {
266             return $self->response_vars->{planned};
267             }
268             }
269              
270             =head3 $self->test_passed($trt_id)
271              
272             Args: trt_id - test_run_test_id for test
273              
274             Returns: tests passed in individual test run $trt_id.
275              
276             =cut
277              
278             sub test_passed {
279             my ($self, $trt_id) = @_;
280              
281             my $args = {
282             trt_id => $trt_id,
283             };
284              
285             my $response = $self->make_api_request('test/stats/passed', $args);
286             if ($response->is_success) {
287             return $self->response_vars->{passed};
288             }
289             }
290              
291             =head3 $self->test_failed($trt_id)
292              
293             Args: trt_id - test_run_test_id for test
294              
295             Returns: tests failed in individual test run $trt_id.
296              
297             =cut
298              
299             sub test_failed {
300             my ($self, $trt_id) = @_;
301              
302             my $args = {
303             trt_id => $trt_id,
304             };
305              
306             my $response = $self->make_api_request('test/stats/failed', $args);
307             if ($response->is_success) {
308             return $self->response_vars->{failed};
309             }
310             }
311              
312             =head3 $self->test_results($trt_id)
313              
314             Args: trt_id - test_run_test_id for test
315              
316             Returns: array of tests results. Each item in the array is an array ref of
317             result_type & result.
318              
319             =cut
320              
321             sub test_results {
322             my ($self, $trt_id) = @_;
323              
324             my $args = {
325             trt_id => $trt_id,
326             };
327              
328             my $response = $self->make_api_request('test/results', $args);
329             if ($response->is_success) {
330             my $results = $self->response_vars->{results};
331             return @$results;
332             }
333             }
334              
335             =head3 $self->test_results_as_string($trt_id)
336              
337             Returns: test results as a single string, effectively in TAP format.
338              
339             =cut
340              
341             sub test_results_as_string {
342             my ($self, $trt_id) = @_;
343              
344             my @results = $self->test_results($trt_id);
345             return join("\n", map { $_->[1] } @results)."\n";
346             }
347              
348             1;