|
@@ -0,0 +1,181 @@
|
|
|
|
|
+#!/usr/bin/perl
|
|
|
|
|
+# ABSTRACT: List runs in a TestRail project matching the provided filters
|
|
|
|
|
+# PODNAME: TestRail::Bin::Replay
|
|
|
|
|
+
|
|
|
|
|
+=head1 SYNOPSIS
|
|
|
|
|
+
|
|
|
|
|
+ testrail-replay [OPTIONS] NAME
|
|
|
|
|
+
|
|
|
|
|
+ require `which testrail-runs`;
|
|
|
|
|
+ TestRail::Bin::Replay::run('args' => \@args);
|
|
|
|
|
+
|
|
|
|
|
+=head1 DESCRIPTION
|
|
|
|
|
+
|
|
|
|
|
+testrail-replay - Re-play the results of a test run or plan as though executed by prove.
|
|
|
|
|
+Optionally wait for results to come in.
|
|
|
|
|
+
|
|
|
|
|
+Can be used as the modulino TestRail::Bin::Replay.
|
|
|
|
|
+Has a single 'run' function which accepts a hash with the 'args' parameter being the array of arguments.
|
|
|
|
|
+
|
|
|
|
|
+=head1 PARAMETERS:
|
|
|
|
|
+
|
|
|
|
|
+=head2 MANDATORY PARAMETERS
|
|
|
|
|
+
|
|
|
|
|
+=over 4
|
|
|
|
|
+
|
|
|
|
|
+--apiurl : full URL to get to TestRail index document
|
|
|
|
|
+
|
|
|
|
|
+--password : Your TestRail Password, or a valid API key (TestRail 4.2 and above).
|
|
|
|
|
+
|
|
|
|
|
+--user : Your TestRail User Name.
|
|
|
|
|
+
|
|
|
|
|
+-j --project : desired project name.
|
|
|
|
|
+
|
|
|
|
|
+=back
|
|
|
|
|
+
|
|
|
|
|
+All mandatory options not passed with the above switches, or in your ~/.testrailrc will be prompted for.
|
|
|
|
|
+
|
|
|
|
|
+=head2 OPTIONAL PARAMETERS
|
|
|
|
|
+
|
|
|
|
|
+=over 4
|
|
|
|
|
+
|
|
|
|
|
+-p --plan : Instead of a run to look for, look for a plan with the provided NAME.
|
|
|
|
|
+
|
|
|
|
|
+-e --encoding : Character encoding of arguments. Defaults to UTF-8. See L<Encode::Supported> for supported encodings.
|
|
|
|
|
+
|
|
|
|
|
+-v --verbose : Print full test output rather than summaries with links to the testrail result.
|
|
|
|
|
+
|
|
|
|
|
+-w --watch : Watch tests until all report results other than untested or re-test.
|
|
|
|
|
+
|
|
|
|
|
+=back
|
|
|
|
|
+
|
|
|
|
|
+=head1 CONFIGURATION FILE
|
|
|
|
|
+
|
|
|
|
|
+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.
|
|
|
|
|
+Valid Keys are the same as documented by L<App::Prove::Plugin::TestRail>.
|
|
|
|
|
+All options specified thereby are overridden by passing the command-line switches above.
|
|
|
|
|
+
|
|
|
|
|
+=head1 MISCELLANEOUS OPTIONS:
|
|
|
|
|
+
|
|
|
|
|
+=over 4
|
|
|
|
|
+
|
|
|
|
|
+--help : show this output
|
|
|
|
|
+
|
|
|
|
|
+=back
|
|
|
|
|
+
|
|
|
|
|
+=cut
|
|
|
|
|
+
|
|
|
|
|
+package TestRail::Bin::Replay;
|
|
|
|
|
+
|
|
|
|
|
+use strict;
|
|
|
|
|
+use warnings;
|
|
|
|
|
+
|
|
|
|
|
+use TestRail::API;
|
|
|
|
|
+use TestRail::Utils;
|
|
|
|
|
+use TestRail::Utils::Find;
|
|
|
|
|
+
|
|
|
|
|
+use Getopt::Long qw{GetOptionsFromArray};
|
|
|
|
|
+use File::HomeDir qw{my_home};
|
|
|
|
|
+
|
|
|
|
|
+if (!caller()) {
|
|
|
|
|
+ my ($out,$code) = run('args' => \@ARGV);
|
|
|
|
|
+ print $out;
|
|
|
|
|
+ exit $code;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+sub run {
|
|
|
|
|
+ my %params = @_;
|
|
|
|
|
+ my $opts = {};
|
|
|
|
|
+
|
|
|
|
|
+ # Parse config file
|
|
|
|
|
+ my $homedir = my_home() || '.';
|
|
|
|
|
+ if (-e $homedir . '/.testrailrc') {
|
|
|
|
|
+ $opts = TestRail::Utils::parseConfig($homedir);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ GetOptionsFromArray($params{'args'},
|
|
|
|
|
+ 'apiurl=s' => \$opts->{'apiurl'},
|
|
|
|
|
+ 'password=s' => \$opts->{'password'},
|
|
|
|
|
+ 'user=s' => \$opts->{'user'},
|
|
|
|
|
+ 'j|project=s' => \$opts->{'project'},
|
|
|
|
|
+ 'e|encoding=s' => \$opts->{'encoding'},
|
|
|
|
|
+ 'p|plan' => \$opts->{'plan'},
|
|
|
|
|
+ 'v|verbose' => \$opts->{'verbose'},
|
|
|
|
|
+ 'w|watch' => \$opts->{'watch'},
|
|
|
|
|
+ 'h|help' => \$opts->{'help'},
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if ($opts->{help}) { return ('',TestRail::Utils::help()); }
|
|
|
|
|
+
|
|
|
|
|
+ $opts->{'browser'} = $params{'browser'};
|
|
|
|
|
+
|
|
|
|
|
+ TestRail::Utils::interrogateUser($opts,qw{apiurl user password project});
|
|
|
|
|
+
|
|
|
|
|
+ my $tr = TestRail::Utils::getHandle($opts);
|
|
|
|
|
+ my $project = $tr->getProjectByName($opts->{'project'});
|
|
|
|
|
+ return ("No such project '$opts->{project}'",2) unless $project;
|
|
|
|
|
+
|
|
|
|
|
+ my $subject = $ARGV[0];
|
|
|
|
|
+ my ($runs,$plan);
|
|
|
|
|
+
|
|
|
|
|
+ if ($opts->{'plan'}) {
|
|
|
|
|
+ $plan = $tr->getPlanByName($project->{'id'},$subject);
|
|
|
|
|
+ $runs = $tr->getChildRuns($plan) if $plan;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ my $run = $tr->getRunByName($project->{'id'},$subject);
|
|
|
|
|
+ push( @$runs, $run) if $run;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ("No runs found matching your criterion.\n",1) unless ref $runs eq 'ARRAY' && @$runs;
|
|
|
|
|
+
|
|
|
|
|
+ my @tests;
|
|
|
|
|
+ foreach my $run (@$runs) {
|
|
|
|
|
+ my $tests = $tr->getTests($run->{id});
|
|
|
|
|
+ @$tests = map { $_->{config} = $run->{config}; $_ } @$tests;
|
|
|
|
|
+ push( @tests, @{$tests}) if ref $tests eq 'ARRAY' && @$tests;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #TODO get status ids for untested/retest, check em
|
|
|
|
|
+ my @retry_status_ids = $tr->statusNamesToIds(qw{untested retest});
|
|
|
|
|
+ my @bad_status_ids = $tr->statusNamesToIds(qw{failed todo_pass});
|
|
|
|
|
+
|
|
|
|
|
+ my $rc = 0;
|
|
|
|
|
+ while (my $test = shift @tests) {
|
|
|
|
|
+ my $results = $tr->getTestResults($test->{id},1);
|
|
|
|
|
+ if ( !( ref $results eq 'ARRAY') || !@$results) {
|
|
|
|
|
+ push(@tests,$test) if $opts->{watch};
|
|
|
|
|
+ next;
|
|
|
|
|
+ }
|
|
|
|
|
+ my $result = $results->[0];
|
|
|
|
|
+ next unless ref $result eq 'HASH';
|
|
|
|
|
+ if (!grep { $result->{status_id} eq $_ } @retry_status_ids) {
|
|
|
|
|
+ print $result->{comment}."\n" if $opts->{verbose};
|
|
|
|
|
+ my $line = $test->{title};
|
|
|
|
|
+ $line .= " ($test->{config})" if $test->{config};
|
|
|
|
|
+ $line .= " ...";
|
|
|
|
|
+ if (grep { $result->{status_id} eq $_ } @bad_status_ids) {
|
|
|
|
|
+ $rc = 3;
|
|
|
|
|
+ $line .= ' not';
|
|
|
|
|
+ }
|
|
|
|
|
+ print "# $opts->{apiurl}/index.php?/tests/view/$test->{id}\n";
|
|
|
|
|
+ print "$line ok\n";
|
|
|
|
|
+ next;
|
|
|
|
|
+ }
|
|
|
|
|
+ push(@tests,$test) if $opts->{watch};
|
|
|
|
|
+ # If we have to wait, back off a little to not slam the server
|
|
|
|
|
+ sleep 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ("Done",$rc);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+1;
|
|
|
|
|
+__END__
|
|
|
|
|
+
|
|
|
|
|
+L<TestRail::API>
|
|
|
|
|
+
|
|
|
|
|
+L<File::HomeDir> for the finding of .testrailrc
|
|
|
|
|
+
|
|
|
|
|
+=head1 SPECIAL THANKS
|
|
|
|
|
+
|
|
|
|
|
+Thanks to cPanel Inc, for graciously funding the creation of this distribution.
|