File Coverage

bin/testrail-replay
Criterion Covered Total %
statement 69 76 90.7
branch 16 32 50.0
condition 4 11 36.3
subroutine 8 8 100.0
pod n/a
total 97 127 76.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             # ABSTRACT: List runs in a TestRail project matching the provided filters
3             # PODNAME: TestRail::Bin::Replay
4              
5             package TestRail::Bin::Replay;
6             $TestRail::Bin::Replay::VERSION = '0.050';
7 1     1   618 use strict;
  1         2  
  1         32  
8 1     1   5 use warnings;
  1         2  
  1         25  
9              
10 1     1   813 use TestRail::API;
  1         4  
  1         61  
11 1     1   533 use TestRail::Utils;
  1         3  
  1         36  
12 1     1   601 use TestRail::Utils::Find;
  1         4  
  1         41  
13              
14 1     1   745 use Getopt::Long qw{GetOptionsFromArray};
  1         10603  
  1         18  
15 1     1   639 use File::HomeDir qw{my_home};
  1         5595  
  1         732  
16              
17             if ( !caller() ) {
18             my ( $out, $code ) = run( 'args' => \@ARGV );
19             print $out;
20             exit $code;
21             }
22              
23             sub run {
24 4     4   28700 my %params = @_;
25 4         10 my $opts = {};
26              
27             # Parse config file
28 4   50     17 my $homedir = my_home() || '.';
29 4 50       242 if ( -e $homedir . '/.testrailrc' ) {
30 0         0 $opts = TestRail::Utils::parseConfig($homedir);
31             }
32              
33             GetOptionsFromArray(
34             $params{'args'},
35             'apiurl=s' => \$opts->{'apiurl'},
36             'password=s' => \$opts->{'password'},
37             'user=s' => \$opts->{'user'},
38             'j|project=s' => \$opts->{'project'},
39             'e|encoding=s' => \$opts->{'encoding'},
40             'p|plan' => \$opts->{'plan'},
41             'v|verbose' => \$opts->{'verbose'},
42             'w|watch' => \$opts->{'watch'},
43 4         67 'h|help' => \$opts->{'help'},
44             );
45              
46 4 100       5260 if ( $opts->{help} ) { return ( '', TestRail::Utils::help() ); }
  1         7  
47              
48 3         11 $opts->{'browser'} = $params{'browser'};
49 3         14 TestRail::Utils::interrogateUser( $opts, qw{apiurl user password project} );
50              
51 3         13 my $tr = TestRail::Utils::getHandle($opts);
52 3         30 my $project = $tr->getProjectByName( $opts->{'project'} );
53 3 50       34 return ( "No such project '$opts->{project}'", 2 ) unless $project;
54              
55 3         7 my $subject = $ARGV[0];
56 3         7 my ( $runs, $plan );
57              
58 3 100       10 if ( $opts->{'plan'} ) {
59 2         9 $plan = $tr->getPlanByName( $project->{'id'}, $subject );
60 2 50       17 $runs = $tr->getChildRuns($plan) if $plan;
61             }
62             else {
63 1         46 my $run = $tr->getRunByName( $project->{'id'}, $subject );
64 1 50       11 push( @$runs, $run ) if $run;
65             }
66              
67 3 50 33     32 return ( "No runs found matching your criterion.\n", 1 )
68             unless ref $runs eq 'ARRAY' && @$runs;
69              
70 3         6 my @tests;
71 3         7 foreach my $run (@$runs) {
72 3         11 my $tests = $tr->getTests( $run->{id} );
73 3         27 @$tests = map { $_->{config} = $run->{config}; $_ } @$tests;
  3         7  
  3         10  
74 3 50 33     17 push( @tests, @{$tests} ) if ref $tests eq 'ARRAY' && @$tests;
  3         37  
75             }
76              
77             #TODO get status ids for untested/retest, check em
78 3         14 my @retry_status_ids = $tr->statusNamesToIds(qw{untested retest});
79 3         24 my @bad_status_ids = $tr->statusNamesToIds(qw{failed todo_pass});
80              
81 3         15 my $rc = 0;
82 3         10 while ( my $test = shift @tests ) {
83 3         10 my $results = $tr->getTestResults( $test->{id}, 1 );
84 3 50 33     33 if ( !( ref $results eq 'ARRAY' ) || !@$results ) {
85 0 0       0 push( @tests, $test ) if $opts->{watch};
86 0         0 next;
87             }
88 3         6 my $result = $results->[0];
89 3 50       10 next unless ref $result eq 'HASH';
90 3 50       7 if ( !grep { $result->{status_id} eq $_ } @retry_status_ids ) {
  3         16  
91 3 50       20 print $result->{comment} . "\n" if $opts->{verbose};
92 3         8 my $line = $test->{title};
93 3 50       9 $line .= " ($test->{config})" if $test->{config};
94 3         6 $line .= " ...";
95 3 50       7 if ( grep { $result->{status_id} eq $_ } @bad_status_ids ) {
  3         22  
96 0         0 $rc = 3;
97 0         0 $line .= ' not';
98             }
99 3         183 print "# $opts->{apiurl}/index.php?/tests/view/$test->{id}\n";
100 3         52 print "$line ok\n";
101 3         32 next;
102             }
103 0 0       0 push( @tests, $test ) if $opts->{watch};
104              
105             # If we have to wait, back off a little to not slam the server
106 0         0 sleep 1;
107             }
108              
109 3         69 return ( "Done", $rc );
110             }
111              
112             1;
113              
114             =pod
115              
116             =encoding UTF-8
117              
118             =head1 NAME
119              
120             TestRail::Bin::Replay - List runs in a TestRail project matching the provided filters
121              
122             =head1 VERSION
123              
124             version 0.050
125              
126             =head1 SYNOPSIS
127              
128             testrail-replay [OPTIONS] NAME
129              
130             require `which testrail-runs`;
131             TestRail::Bin::Replay::run('args' => \@args);
132              
133             =head1 DESCRIPTION
134              
135             testrail-replay - Re-play the results of a test run or plan as though executed by prove.
136             Optionally wait for results to come in.
137              
138             Can be used as the modulino TestRail::Bin::Replay.
139             Has a single 'run' function which accepts a hash with the 'args' parameter being the array of arguments.
140              
141             =head1 PARAMETERS:
142              
143             =head2 MANDATORY PARAMETERS
144              
145             =over 4
146              
147             --apiurl : full URL to get to TestRail index document
148              
149             --password : Your TestRail Password, or a valid API key (TestRail 4.2 and above).
150              
151             --user : Your TestRail User Name.
152              
153             -j --project : desired project name.
154              
155             =back
156              
157             All mandatory options not passed with the above switches, or in your ~/.testrailrc will be prompted for.
158              
159             =head2 OPTIONAL PARAMETERS
160              
161             =over 4
162              
163             -p --plan : Instead of a run to look for, look for a plan with the provided NAME.
164              
165             -e --encoding : Character encoding of arguments. Defaults to UTF-8. See L for supported encodings.
166              
167             -v --verbose : Print full test output rather than summaries with links to the testrail result.
168              
169             -w --watch : Watch tests until all report results other than untested or re-test.
170              
171             =back
172              
173             =head1 CONFIGURATION FILE
174              
175             In your \$HOME, (or the current directory, if your system has no concept of a home directory) put a file called .testrailrc with key=value syntax separated by newlines.
176             Valid Keys are the same as documented by L.
177             All options specified thereby are overridden by passing the command-line switches above.
178              
179             =head1 MISCELLANEOUS OPTIONS:
180              
181             =over 4
182              
183             --help : show this output
184              
185             =back
186              
187             =head1 SPECIAL THANKS
188              
189             Thanks to cPanel Inc, for graciously funding the creation of this distribution.
190              
191             =head1 AUTHOR
192              
193             George S. Baugh
194              
195             =head1 SOURCE
196              
197             The development version is on github at L
198             and may be cloned from L
199              
200             =head1 COPYRIGHT AND LICENSE
201              
202             This software is copyright (c) 2021 by George S. Baugh.
203              
204             This is free software; you can redistribute it and/or modify it under
205             the same terms as the Perl 5 programming language system itself.
206              
207             =cut
208              
209             __END__