diff --git a/mozilla/webtools/testopia/.bzrrev b/mozilla/webtools/testopia/.bzrrev index 0dde6d352b7..8b49166353f 100644 --- a/mozilla/webtools/testopia/.bzrrev +++ b/mozilla/webtools/testopia/.bzrrev @@ -1 +1 @@ -694 \ No newline at end of file +695 \ No newline at end of file diff --git a/mozilla/webtools/testopia/.gitrev b/mozilla/webtools/testopia/.gitrev index 245c2ecdca9..a098bc6b8ce 100644 --- a/mozilla/webtools/testopia/.gitrev +++ b/mozilla/webtools/testopia/.gitrev @@ -1 +1 @@ -b5fa234f0a5a2adcb8ef8fb1bc17f9c506510343 \ No newline at end of file +2f7fc1997b0272ffe1635b902aa594a8f048d690 \ No newline at end of file diff --git a/mozilla/webtools/testopia/extensions/Testopia/Extension.pm b/mozilla/webtools/testopia/extensions/Testopia/Extension.pm index 7fd6f068f61..39143785f4d 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/Extension.pm +++ b/mozilla/webtools/testopia/extensions/Testopia/Extension.pm @@ -363,45 +363,42 @@ sub page_before_template { require Bugzilla::Extension::Testopia::Reports::Product; Bugzilla::Extension::Testopia::Reports::Product::report($vars); } + elsif ($page eq 'tr_run_reports.html') { + require Bugzilla::Extension::Testopia::Reports::Run; + Bugzilla::Extension::Testopia::Reports::Run::report($vars); + } } sub post_bug_after_creation { my ($self, $args) = @_; - - + my $vars = $args->{vars}; my $cgi = Bugzilla->cgi; - + my $caserun_id = $cgi->param('caserun_id'); my $case_id = $cgi->param('case_id'); if (detaint_natural($caserun_id)) { my $caserun = Bugzilla::Extension::Testopia::TestCaseRun->new($cgi->param('caserun_id')); ThrowUserError("invalid-test-id-non-existent", {'id' => $caserun_id, 'type' => 'Case-Run'}) unless $caserun; ThrowUserError("testopia-read-only", {'object' => $caserun}) unless $caserun->canedit; - + $caserun->attach_bug($vars->{'id'}); - $vars->{'caserun'} = $caserun; } elsif (detaint_natural($case_id)) { my $case = Bugzilla::Extension::Testopia::TestCase->new($cgi->param('case_id')); ThrowUserError("invalid-test-id-non-existent", {'id' => $case_id, 'type' => 'Case'}) unless $case; ThrowUserError("testopia-read-only", {'object' => $case}) unless $case->canedit; - + $case->attach_bug($vars->{'id'}); - $vars->{'case'} = $case; } - } sub product_confirm_delete { my ($self, $args) = @_; - - - + my $vars = $args->{vars}; - $vars->{'testopia_product'} = new Bugzilla::Extension::Testopia::Product($vars->{product}->id); } diff --git a/mozilla/webtools/testopia/extensions/Testopia/contrib/drivers/php/.xmlrpc.inc.php b/mozilla/webtools/testopia/extensions/Testopia/contrib/drivers/php/.xmlrpc.inc.php index 9c0609d7020..a30fd722bb7 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/contrib/drivers/php/.xmlrpc.inc.php +++ b/mozilla/webtools/testopia/extensions/Testopia/contrib/drivers/php/.xmlrpc.inc.php @@ -1,7 +1,7 @@ -// $Id: .xmlrpc.inc.php,v 1.57 2015-03-15 16:30:19 bzrmirror%bugzilla.org Exp $ +// $Id: .xmlrpc.inc.php,v 1.58 2015-04-13 02:00:20 bzrmirror%bugzilla.org Exp $ // Copyright (c) 1999,2000,2002 Edd Dumbill. // All rights reserved. diff --git a/mozilla/webtools/testopia/extensions/Testopia/js/plan.js b/mozilla/webtools/testopia/extensions/Testopia/js/plan.js index 6cdc2bdbb7a..50d95c81c65 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/js/plan.js +++ b/mozilla/webtools/testopia/extensions/Testopia/js/plan.js @@ -463,7 +463,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=status&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=status&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -482,7 +482,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=completion&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=completion&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -529,7 +529,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=execution&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue(); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=execution&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue(); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -558,7 +558,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=priority&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=priority&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -576,7 +576,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=bug_grid&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=bug_grid&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -596,7 +596,7 @@ Ext.extend(Testopia.TestPlan.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=worst&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=worst&plan_ids=' + Testopia.Util.getSelectedObjects(grid, 'plan_id') + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); diff --git a/mozilla/webtools/testopia/extensions/Testopia/js/run.js b/mozilla/webtools/testopia/extensions/Testopia/js/run.js index 279751b1b34..bac0adf46e1 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/js/run.js +++ b/mozilla/webtools/testopia/extensions/Testopia/js/run.js @@ -384,7 +384,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=status&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=status&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -404,7 +404,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=completion&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=completion&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -455,7 +455,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=execution&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue() + '&tester=' + Ext.getCmp('exec_tester').getValue(); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=execution&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue() + '&tester=' + Ext.getCmp('exec_tester').getValue(); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -484,7 +484,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=priority&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=priority&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id'); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -503,7 +503,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=bug_grid&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=bug_grid&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -523,7 +523,7 @@ Ext.extend(Testopia.TestRun.Grid, Ext.grid.GridPanel, { autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=worst&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=worst&run_ids=' + Testopia.Util.getSelectedObjects(grid, 'run_id') + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -1521,8 +1521,9 @@ Ext.extend(Testopia.TestRun.FiltersList, Ext.grid.GridPanel, { Testopia.BugReport = function(params){ params.type = 'bug'; + params.id = 'tr_run_reports.html'; this.store = new Ext.data.GroupingStore({ - url: 'tr_run_reports.cgi', + url: 'page.cgi', baseParams: params, reader: new Ext.data.JsonReader({ root: 'Result', diff --git a/mozilla/webtools/testopia/extensions/Testopia/js/search.js b/mozilla/webtools/testopia/extensions/Testopia/js/search.js index 91c52472869..90f1aeaa9c5 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/js/search.js +++ b/mozilla/webtools/testopia/extensions/Testopia/js/search.js @@ -445,6 +445,7 @@ Testopia.Search.RunsForm = function(params){ } catch(err){} if (params.report){ + values.id = 'tr_run_reports.html'; Ext.getCmp('object_panel').add(new Ext.Panel({ id: 'run_search' + searchnum, closable: true, @@ -452,7 +453,7 @@ Testopia.Search.RunsForm = function(params){ autoScroll: true, listeners: { 'render': function(){ this.load({ - url: 'tr_run_reports.cgi', + url: 'page.cgi', params: values }); }}, diff --git a/mozilla/webtools/testopia/extensions/Testopia/lib/Reports/Run.pm b/mozilla/webtools/testopia/extensions/Testopia/lib/Reports/Run.pm new file mode 100644 index 00000000000..78c47204b11 --- /dev/null +++ b/mozilla/webtools/testopia/extensions/Testopia/lib/Reports/Run.pm @@ -0,0 +1,361 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::Testopia::Reports::Run; + +use strict; +use warnings; + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; + +use Bugzilla::Extension::Testopia::Report; +use Bugzilla::Extension::Testopia::Util; +use Bugzilla::Extension::Testopia::Constants; +use Bugzilla::Extension::Testopia::TestPlan; +use Bugzilla::Extension::Testopia::TestRun; +use Bugzilla::Extension::Testopia::Search; + +use JSON; + +sub report { + my ($vars) = @_; + my $input = Bugzilla->input_params; + my $template = Bugzilla->template; + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; + + Bugzilla->login(LOGIN_REQUIRED); + + my $type = $input->{'type'} || ''; + $vars->{'qname'} = $input->{'qname'}; + + if ($type eq 'completion') { + print $cgi->header; + my @r = $input->{'run_ids'}; + my @p = $input->{'plan_ids'}; + + my ($runs, $run_ids) = get_runs(\@p, \@r); + my @runs = @$runs; + my @run_ids = @$run_ids; + + my $bugs = $dbh->selectcol_arrayref(" + SELECT DISTINCT tcb.bug_id + FROM test_case_bugs AS tcb + INNER JOIN test_case_runs AS tcr ON tcr.case_run_id = tcb.case_run_id + INNER JOIN bugs on tcb.bug_id = bugs.bug_id + INNER JOIN test_case_run_status AS tcrs ON tcr.case_run_status_id = tcrs.case_run_status_id + WHERE tcr.run_id in (" . join (',',@run_ids) . ") AND tcr.iscurrent = 1", + {"Slice" =>{}}); + + my $total = $runs[0]->case_run_count(undef, \@runs); + my $passed = $runs[0]->case_run_count(PASSED, \@runs); + my $failed = $runs[0]->case_run_count(FAILED, \@runs); + my $blocked = $runs[0]->case_run_count(BLOCKED, \@runs); + + my $completed = $passed + $failed + $blocked; + my $unfinished = $total - $completed; + + $vars->{'total'} = $total; + $vars->{'completed'} = $completed; + $vars->{'uncompleted'} = $unfinished; + $vars->{'passed'} = $passed; + $vars->{'failed'} = $failed; + $vars->{'blocked'} = $blocked; + + $vars->{'percent_completed'} = calculate_percent($total, $completed); + $vars->{'percent_passed'} = calculate_percent($completed, $passed); + $vars->{'percent_failed'} = calculate_percent($completed, $failed); + $vars->{'percent_blocked'} = calculate_percent($completed, $blocked); + $vars->{'percent_idle'} = calculate_percent($total, $unfinished); + + $vars->{'runs'} = join(',',@run_ids); + $vars->{'plans'} = join(',',@p); + $vars->{'bugs'} = join(',',@$bugs); + $vars->{'bug_count'} = scalar @$bugs; + $vars->{'run_count'} = scalar @run_ids; + + $template->process("testopia/reports/completion.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'status') { + print $cgi->header; + my @r = $input->{'run_ids'}; + my @p = $input->{'plan_ids'}; + + my ($runs, $run_ids) = get_runs(\@p, \@r); + my @runs = @$runs; + my @run_ids = @$run_ids; + + $vars->{'total'} = $runs[0]->case_run_count(undef, \@runs); + $vars->{'passed'} = $runs[0]->case_run_count(PASSED, \@runs); + $vars->{'failed'} = $runs[0]->case_run_count(FAILED, \@runs); + $vars->{'blocked'} = $runs[0]->case_run_count(BLOCKED, \@runs); + $vars->{'idle'} = $runs[0]->case_run_count(IDLE, \@runs); + $vars->{'running'} = $runs[0]->case_run_count(RUNNING, \@runs); + $vars->{'paused'} = $runs[0]->case_run_count(PAUSED, \@runs); + $vars->{'error'} = $runs[0]->case_run_count(ERROR, \@runs); + + $vars->{'runs'} = join(',',@run_ids); + $vars->{'plans'} = join(',',@p); + $vars->{'run_count'} = scalar @run_ids; + + $template->process("testopia/reports/status.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'execution') { + print $cgi->header; + my @run_ids = $input->{'run_ids'}; + my @plan_ids = $input->{'plan_ids'}; + my @runs; + + foreach my $g (@plan_ids) { + foreach my $id (split(',', $g)) { + my $obj = Bugzilla::Extension::Testopia::TestPlan->new($id); + push @runs, @{$obj->test_runs} if $obj && $obj->canview; + } + } + foreach my $g (@run_ids) { + foreach my $id (split(',', $g)) { + my $obj = Bugzilla::Extension::Testopia::TestRun->new($id); + push @runs, $obj if $obj && $obj->canview; + } + } + + unless (scalar @runs) { + print "No runs found"; + exit; + } + + @run_ids = (); + foreach my $r (@runs) { + push @run_ids, $r->id; + } + my $chfieldfrom = trim(lc($input->{'chfieldfrom'})) || ''; + my $chfieldto = trim(lc($input->{'chfieldto'})) || ''; + my $tester; + if ($input->{'tester'}) { + $tester = login_to_id(trim($input->{'tester'}), 'THROW_ERROR'); + } + + trick_taint($chfieldfrom); + trick_taint($chfieldto); + my $sql_chfrom = Bugzilla::Extension::Testopia::Search::SqlifyDate($chfieldfrom); + my $sql_chto = Bugzilla::Extension::Testopia::Search::SqlifyDate($chfieldto); + + my $total = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, undef, $tester, \@runs); + my $passed = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, PASSED, $tester, \@runs); + my $failed = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, FAILED, $tester, \@runs); + my $blocked = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, BLOCKED, $tester, \@runs); + + $vars->{'total'} = $total; + $vars->{'passed'} = $passed; + $vars->{'failed'} = $failed; + $vars->{'blocked'} = $blocked; + $vars->{'closed_from'} = $chfieldfrom; + $vars->{'closed_to'} = $chfieldto; + $vars->{'closed_from_converted'} = $sql_chfrom; + $vars->{'closed_to_converted'} = $sql_chto; + $vars->{'runs'} = \@run_ids; + $vars->{'plans'} = \@plan_ids; + + $template->process("testopia/reports/execution.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'bar') { + $vars->{'total'} = $input->{'t'}; + + $vars->{'colors'} = (['#B8A0D2', '#56e871', '#ed3f58','#e17a56']); + $vars->{'legend'} = ["Complete", "PASSED", "FAILED", "BLOCKED"]; + $vars->{'data'} = [ + ["CASES"], + [$input->{'c'}], + [$input->{'p'}], + [$input->{'f'}], + [$input->{'b'}], + ]; + + print $cgi->header; + $template->process("testopia/reports/completion.png.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'bug') { + print $cgi->header; + my @run_ids = $input->{'run_ids'}; + my @plan_ids = $input->{'plan_ids'}; + my @runs; + + foreach my $g (@plan_ids) { + foreach my $id (split(',', $g)) { + my $obj = Bugzilla::Extension::Testopia::TestPlan->new($id); + push @runs, @{$obj->test_runs} if $obj && $obj->canview; + } + } + foreach my $g (@run_ids) { + foreach my $id (split(',', $g)) { + my $obj = Bugzilla::Extension::Testopia::TestRun->new($id); + push @runs, $obj if $obj && $obj->canview; + } + } + + unless (scalar @runs) { + print "No runs found"; + exit; + } + my @ids; + foreach my $r (@runs) { + push @ids, $r->id; + } + my $ref = $dbh->selectall_arrayref(" + SELECT DISTINCT tcb.bug_id, bugs.bug_status, bugs.bug_severity, tcr.run_id, tcr.case_id, tcrs.name AS case_status + FROM test_case_bugs AS tcb + INNER JOIN test_case_runs AS tcr ON tcr.case_run_id = tcb.case_run_id + INNER JOIN bugs on tcb.bug_id = bugs.bug_id + INNER JOIN test_case_run_status AS tcrs ON tcr.case_run_status_id = tcrs.case_run_status_id + WHERE tcr.run_id in (" . join (',',@ids) . ") AND tcr.iscurrent = 1", + {"Slice" =>{}}); + + my $json = new JSON; + print "{Result:"; + print $json->encode($ref); + print "}"; + exit; + } + elsif ($type eq 'bug_grid') { + $vars->{'runs'} = $input->{'run_ids'}; + $vars->{'plans'} = $input->{'plan_ids'}; + $vars->{'stripheader'} = 1 if $input->{'noheader'}; + $vars->{'uid'} = rand(10000); + + print $cgi->header; + $template->process("testopia/reports/bug-count.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'priority') { + print $cgi->header; + my @r = $input->{'run_ids'}; + my @plans = $input->{'plan_ids'}; + + my ($runs, $run_ids) = get_runs(\@plans, \@r); + my @runs = @$runs; + my @run_ids = @$run_ids; + my $priorities; + + foreach my $p (@{$dbh->selectall_arrayref("SELECT id, value FROM priority")}) { + $priorities->{$p->[1]}->{'total'} = $runs[0]->case_run_count_by_priority($p->[0], undef, \@runs); + $priorities->{$p->[1]}->{'passed'} = $runs[0]->case_run_count_by_priority($p->[0], PASSED, \@runs); + $priorities->{$p->[1]}->{'failed'} = $runs[0]->case_run_count_by_priority($p->[0], FAILED, \@runs); + $priorities->{$p->[1]}->{'blocked'} = $runs[0]->case_run_count_by_priority($p->[0], BLOCKED, \@runs); + $priorities->{$p->[1]}->{'idle'} = $runs[0]->case_run_count_by_priority($p->[0], IDLE, \@runs); + $priorities->{$p->[1]}->{'running'} = $runs[0]->case_run_count_by_priority($p->[0], RUNNING, \@runs); + $priorities->{$p->[1]}->{'paused'} = $runs[0]->case_run_count_by_priority($p->[0], PAUSED, \@runs); + $priorities->{$p->[1]}->{'error'} = $runs[0]->case_run_count_by_priority($p->[0], ERROR, \@runs); + } + $vars->{'priorities'} = $priorities; + $vars->{'runs'} = join(',',@run_ids); + $vars->{'plans'} = join(',',@plans); + $vars->{'run_count'} = scalar @run_ids; + + $template->process("testopia/reports/priority-breakdown.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + elsif ($type eq 'worst') { + print $cgi->header; + my @r = $input->{'run_ids'}; + my @plans = $input->{'plan_ids'}; + + my ($runs, $run_ids) = get_runs(\@plans, \@r); + my @runs = @$runs; + my @run_ids = @$run_ids; + my $json = new JSON; + + my $query = + "SELECT COUNT(case_id) AS top, case_id + FROM test_case_runs + WHERE run_id IN (". join(',', @$run_ids) .") + AND case_run_status_id = ? + GROUP BY case_id + ORDER BY top DESC + LIMIT ?"; + + my $ref = $dbh->selectall_arrayref($query, {'Slice' =>{}}, (FAILED, 10)); + foreach my $row (@$ref) { + $row->{top} = int($row->{top}); + } + + $vars->{'stripheader'} = 1 if $input->{'noheader'}; + $vars->{'uid'} = int(rand(10000)); + $vars->{'data'} = $json->encode($ref); + $vars->{'runs'} = join(',',@run_ids); + $vars->{'plans'} = join(',',@plans); + + $template->process("testopia/reports/bar.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + + $input->{'current_tab', 'run'}; + $input->{'viewall', 1}; + my $report = Bugzilla::Extension::Testopia::Report->new('run', 'tr_list_runs.cgi', $cgi); + $vars->{'report'} = $report; + + ### From Bugzilla report.cgi by Gervase Markham + my $formatparam = $input->{'format'}; + my $report_action = $input->{'report_action'}; + if ($report_action eq "data") { + # So which template are we using? If action is "wrap", we will be using + # no format (it gets passed through to be the format of the actual data), + # and either report.csv.tmpl (CSV), or report.html.tmpl (everything else). + # report.html.tmpl produces an HTML framework for either tables of HTML + # data, or images generated by calling report.cgi again with action as + # "plot". + $formatparam =~ s/[^a-zA-Z\-]//g; + trick_taint($formatparam); + $vars->{'format'} = $formatparam; + $formatparam = ''; + } + elsif ($report_action eq "plot") { + # If action is "plot", we will be using a format as normal (pie, bar etc.) + # and a ctype as normal (currently only png.) + $vars->{'cumulate'} = $input->{'cumulate'} ? 1 : 0; + $vars->{'x_labels_vertical'} = $input->{'x_labels_vertical'} ? 1 : 0; + $vars->{'data'} = $report->{'image_data'}; + } + else { + ThrowUserError("unknown_action", {action => $input->{'report_action'}}); + } + + my $format = $template->get_format("testopia/reports/report", $formatparam, + scalar($input->{'ctype'})); + + my @time = localtime(time()); + my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3]; + my $filename = "report-" . $date . ".$format->{extension}"; + + my $disp = "inline"; + # We set CSV files to be downloaded, as they are designed for importing + # into other programs. + if ($format->{'extension'} eq "csv" || $format->{'extension'} eq "xml") { + $disp = "attachment"; + } + + print $cgi->header( -type => $format->{'ctype'}, + -content_disposition => "$disp; filename=$filename"); + + $vars->{'time'} = $date; + $template->process("$format->{'template'}", $vars) + || ThrowTemplateError($template->error()); +} + +1; diff --git a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/pages/tr_run_reports.html.tmpl b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/pages/tr_run_reports.html.tmpl new file mode 100644 index 00000000000..bcb75107df8 --- /dev/null +++ b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/pages/tr_run_reports.html.tmpl @@ -0,0 +1,7 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] diff --git a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/plan/show.html.tmpl b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/plan/show.html.tmpl index ce9fe064c3d..f3b427baa95 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/plan/show.html.tmpl +++ b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/plan/show.html.tmpl @@ -193,7 +193,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=status&plan_ids=' + plan.plan_id; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=status&plan_ids=' + plan.plan_id; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -212,7 +212,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=completion&plan_ids=' + plan.plan_id; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=completion&plan_ids=' + plan.plan_id; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -259,7 +259,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=execution&plan_ids=' + plan.plan_id + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue(); + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=execution&plan_ids=' + plan.plan_id + '&chfieldfrom=' + Ext.getCmp('execution_start_date').getValue() + '&chfieldto=' + Ext.getCmp('execution_stop_date').getValue(); Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -288,7 +288,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=priority&plan_ids=' + plan.plan_id; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=priority&plan_ids=' + plan.plan_id; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -306,7 +306,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=bug_grid&plan_ids=' + plan.plan_id + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=bug_grid&plan_ids=' + plan.plan_id + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); @@ -326,7 +326,7 @@ autoScroll: true, tools: PortalTools }); - newPortlet.url = 'tr_run_reports.cgi?type=worst&plan_ids=' + plan.plan_id + '&noheader=1'; + newPortlet.url = 'page.cgi?id=tr_run_reports.html&type=worst&plan_ids=' + plan.plan_id + '&noheader=1'; Testopia.Search.dashboard_urls.push(newPortlet.url); Ext.getCmp('dashboard_leftcol').add(newPortlet); Ext.getCmp('dashboard_leftcol').doLayout(); diff --git a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/reports/completion.html.tmpl b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/reports/completion.html.tmpl index d9ba9b0338b..bda48f8aa93 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/reports/completion.html.tmpl +++ b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/reports/completion.html.tmpl @@ -100,7 +100,7 @@ [% END %] - + [% IF bug_count %] diff --git a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/search/run.html.tmpl b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/search/run.html.tmpl index dbca9616bbb..3ea7dfc81a0 100644 --- a/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/search/run.html.tmpl +++ b/mozilla/webtools/testopia/extensions/Testopia/template/en/default/testopia/search/run.html.tmpl @@ -19,7 +19,8 @@ #%] [% IF report %] -
+ + [% PROCESS "testopia/search/report-matrix.html.tmpl" obj = run %] diff --git a/mozilla/webtools/testopia/tr_run_reports.cgi b/mozilla/webtools/testopia/tr_run_reports.cgi deleted file mode 100644 index 7da8e089806..00000000000 --- a/mozilla/webtools/testopia/tr_run_reports.cgi +++ /dev/null @@ -1,397 +0,0 @@ -#!/usr/bin/perl -wT -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Testopia System. -# -# The Initial Developer of the Original Code is Greg Hendricks. -# Portions created by Greg Hendricks are Copyright (C) 2006 -# Novell. All Rights Reserved. -# -# Contributor(s): Greg Hendricks - -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Error; -use Bugzilla::Util; -use Bugzilla::User; - -BEGIN { Bugzilla->extensions } - -use Bugzilla::Extension::Testopia::Util; -use Bugzilla::Extension::Testopia::Constants; -use Bugzilla::Extension::Testopia::Report; -use Bugzilla::Extension::Testopia::TestRun; -use Bugzilla::Extension::Testopia::Search; - -use JSON; - -my $vars = {}; -my $template = Bugzilla->template; -my $cgi = Bugzilla->cgi; - -Bugzilla->login(LOGIN_REQUIRED); - -my $type = $cgi->param('type') || ''; -$vars->{'qname'} = $cgi->param('qname'); - -if ($type eq 'completion'){ - print $cgi->header; - my $dbh = Bugzilla->dbh; - my @r = $cgi->param('run_ids'); - my @p = $cgi->param('plan_ids'); - - my ($runs, $run_ids) = get_runs(\@p, \@r); - my @runs = @$runs; - my @run_ids = @$run_ids; - - my $bugs = $dbh->selectcol_arrayref(" - SELECT DISTINCT tcb.bug_id - FROM test_case_bugs AS tcb - INNER JOIN test_case_runs AS tcr ON tcr.case_run_id = tcb.case_run_id - INNER JOIN bugs on tcb.bug_id = bugs.bug_id - INNER JOIN test_case_run_status AS tcrs ON tcr.case_run_status_id = tcrs.case_run_status_id - WHERE tcr.run_id in (" . join (',',@run_ids) . ") AND tcr.iscurrent = 1", - {"Slice" =>{}}); - - my $total = $runs[0]->case_run_count(undef, \@runs); - my $passed = $runs[0]->case_run_count(PASSED, \@runs); - my $failed = $runs[0]->case_run_count(FAILED, \@runs); - my $blocked = $runs[0]->case_run_count(BLOCKED, \@runs); - - my $completed = $passed + $failed + $blocked; - my $unfinished = $total - $completed; - - $vars->{'total'} = $total; - $vars->{'completed'} = $completed; - $vars->{'uncompleted'} = $unfinished; - $vars->{'passed'} = $passed; - $vars->{'failed'} = $failed; - $vars->{'blocked'} = $blocked; - - $vars->{'percent_completed'} = calculate_percent($total, $completed); - $vars->{'percent_passed'} = calculate_percent($completed, $passed); - $vars->{'percent_failed'} = calculate_percent($completed, $failed); - $vars->{'percent_blocked'} = calculate_percent($completed, $blocked); - $vars->{'percent_idle'} = calculate_percent($total, $unfinished); - - $vars->{'runs'} = join(',',@run_ids); - $vars->{'plans'} = join(',',@p); - $vars->{'bugs'} = join(',',@$bugs); - $vars->{'bug_count'} = scalar @$bugs; - $vars->{'run_count'} = scalar @run_ids; - - $template->process("testopia/reports/completion.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; -} -elsif ($type eq 'status'){ - print $cgi->header; - my $dbh = Bugzilla->dbh; - my @r = $cgi->param('run_ids'); - my @p = $cgi->param('plan_ids'); - - my ($runs, $run_ids) = get_runs(\@p, \@r); - my @runs = @$runs; - my @run_ids = @$run_ids; - - $vars->{'total'} = $runs[0]->case_run_count(undef, \@runs); - $vars->{'passed'} = $runs[0]->case_run_count(PASSED, \@runs); - $vars->{'failed'} = $runs[0]->case_run_count(FAILED, \@runs); - $vars->{'blocked'} = $runs[0]->case_run_count(BLOCKED, \@runs); - $vars->{'idle'} = $runs[0]->case_run_count(IDLE, \@runs); - $vars->{'running'} = $runs[0]->case_run_count(RUNNING, \@runs); - $vars->{'paused'} = $runs[0]->case_run_count(PAUSED, \@runs); - $vars->{'error'} = $runs[0]->case_run_count(ERROR, \@runs); - - $vars->{'runs'} = join(',',@run_ids); - $vars->{'plans'} = join(',',@p); - $vars->{'run_count'} = scalar @run_ids; - - $template->process("testopia/reports/status.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; -} -elsif ($type eq 'execution'){ - print $cgi->header; - my $dbh = Bugzilla->dbh; - my @run_ids = $cgi->param('run_ids'); - my @plan_ids = $cgi->param('plan_ids'); - my @runs; - - foreach my $g (@plan_ids){ - foreach my $id (split(',', $g)){ - my $obj = Bugzilla::Extension::Testopia::TestPlan->new($id); - push @runs, @{$obj->test_runs} if $obj && $obj->canview; - } - } - foreach my $g (@run_ids){ - foreach my $id (split(',', $g)){ - my $obj = Bugzilla::Extension::Testopia::TestRun->new($id); - push @runs, $obj if $obj && $obj->canview; - } - } - - unless (scalar @runs){ - print "No runs found"; - exit; - } - - @run_ids = (); - foreach my $r (@runs){ - push @run_ids, $r->id; - } - my $chfieldfrom = trim(lc($cgi->param('chfieldfrom'))) || ''; - my $chfieldto = trim(lc($cgi->param('chfieldto'))) || ''; - my $tester; - if ($cgi->param('tester')){ - $tester = login_to_id(trim($cgi->param('tester')), 'THROW_ERROR'); - } - - trick_taint($chfieldfrom); - trick_taint($chfieldto); - my $sql_chfrom = Bugzilla::Extension::Testopia::Search::SqlifyDate($chfieldfrom); - my $sql_chto = Bugzilla::Extension::Testopia::Search::SqlifyDate($chfieldto); - - my $total = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, undef, $tester, \@runs); - my $passed = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, PASSED, $tester, \@runs); - my $failed = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, FAILED, $tester, \@runs); - my $blocked = $runs[0]->case_run_count_by_date($sql_chfrom, $sql_chto, BLOCKED, $tester, \@runs); - - $vars->{'total'} = $total; - $vars->{'passed'} = $passed; - $vars->{'failed'} = $failed; - $vars->{'blocked'} = $blocked; - $vars->{'closed_from'} = $chfieldfrom; - $vars->{'closed_to'} = $chfieldto; - $vars->{'closed_from_converted'} = $sql_chfrom; - $vars->{'closed_to_converted'} = $sql_chto; - $vars->{'runs'} = \@run_ids; - $vars->{'plans'} = \@plan_ids; - - $template->process("testopia/reports/execution.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - - exit; - -} -elsif ($type eq 'bar'){ - - $vars->{'total'} = $cgi->param('t'); -# $vars->{'data'} = [ -# ["Total", "Completed", "Passed", "Failed", "Blocked"], -# [ $cgi->param('t'), $cgi->param('c'), $cgi->param('p'), $cgi->param('f'), $cgi->param('b') ], -# ]; - - $vars->{'colors'} = (['#B8A0D2', '#56e871', '#ed3f58','#e17a56']); - $vars->{'legend'} = ["Complete", "PASSED", "FAILED", "BLOCKED"]; - $vars->{'data'} = [ - ["CASES"], - [$cgi->param('c')], - [$cgi->param('p')], - [$cgi->param('f')], - [$cgi->param('b')], - ]; - - print $cgi->header; - $template->process("testopia/reports/completion.png.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; - -} -elsif ($type eq 'bug'){ - print $cgi->header; - my @run_ids = $cgi->param('run_ids'); - my @plan_ids = $cgi->param('plan_ids'); - my @runs; - my $dbh = Bugzilla->dbh; - - foreach my $g (@plan_ids){ - foreach my $id (split(',', $g)){ - my $obj = Bugzilla::Extension::Testopia::TestPlan->new($id); - push @runs, @{$obj->test_runs} if $obj && $obj->canview; - } - } - foreach my $g (@run_ids){ - foreach my $id (split(',', $g)){ - my $obj = Bugzilla::Extension::Testopia::TestRun->new($id); - push @runs, $obj if $obj && $obj->canview; - } - } - - unless (scalar @runs){ - print "No runs found"; - exit; - } - my @ids; - foreach my $r (@runs){ - push @ids, $r->id; - } - my $ref = $dbh->selectall_arrayref(" - SELECT DISTINCT tcb.bug_id, bugs.bug_status, bugs.bug_severity, tcr.run_id, tcr.case_id, tcrs.name AS case_status - FROM test_case_bugs AS tcb - INNER JOIN test_case_runs AS tcr ON tcr.case_run_id = tcb.case_run_id - INNER JOIN bugs on tcb.bug_id = bugs.bug_id - INNER JOIN test_case_run_status AS tcrs ON tcr.case_run_status_id = tcrs.case_run_status_id - WHERE tcr.run_id in (" . join (',',@ids) . ") AND tcr.iscurrent = 1", - {"Slice" =>{}}); - - my $json = new JSON; - print "{Result:"; - print $json->encode($ref); - print "}"; - exit; -} - -elsif ($type eq 'bug_grid'){ - $vars->{'runs'} = $cgi->param('run_ids'); - $vars->{'plans'} = $cgi->param('plan_ids'); - $vars->{'stripheader'} = 1 if $cgi->param('noheader'); - $vars->{'uid'} = rand(10000); - - print $cgi->header; - $template->process("testopia/reports/bug-count.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; -} - -elsif ($type eq 'priority'){ - print $cgi->header; - my $dbh = Bugzilla->dbh; - my @r = $cgi->param('run_ids'); - my @plans = $cgi->param('plan_ids'); - - my ($runs, $run_ids) = get_runs(\@plans, \@r); - my @runs = @$runs; - my @run_ids = @$run_ids; - my $priorities; - - foreach my $p (@{$dbh->selectall_arrayref("SELECT id, value FROM priority")}){ - $priorities->{$p->[1]}->{'total'} = $runs[0]->case_run_count_by_priority($p->[0], undef, \@runs); - $priorities->{$p->[1]}->{'passed'} = $runs[0]->case_run_count_by_priority($p->[0], PASSED, \@runs); - $priorities->{$p->[1]}->{'failed'} = $runs[0]->case_run_count_by_priority($p->[0], FAILED, \@runs); - $priorities->{$p->[1]}->{'blocked'} = $runs[0]->case_run_count_by_priority($p->[0], BLOCKED, \@runs); - $priorities->{$p->[1]}->{'idle'} = $runs[0]->case_run_count_by_priority($p->[0], IDLE, \@runs); - $priorities->{$p->[1]}->{'running'} = $runs[0]->case_run_count_by_priority($p->[0], RUNNING, \@runs); - $priorities->{$p->[1]}->{'paused'} = $runs[0]->case_run_count_by_priority($p->[0], PAUSED, \@runs); - $priorities->{$p->[1]}->{'error'} = $runs[0]->case_run_count_by_priority($p->[0], ERROR, \@runs); - } - $vars->{'priorities'} = $priorities; - $vars->{'runs'} = join(',',@run_ids); - $vars->{'plans'} = join(',',@plans); - $vars->{'run_count'} = scalar @run_ids; - - $template->process("testopia/reports/priority-breakdown.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; - -} -elsif ($type eq 'worst'){ - print $cgi->header; - my $dbh = Bugzilla->dbh; - my @r = $cgi->param('run_ids'); - my @plans = $cgi->param('plan_ids'); - - my ($runs, $run_ids) = get_runs(\@plans, \@r); - my @runs = @$runs; - my @run_ids = @$run_ids; - my $json = new JSON; - - my $query = - "SELECT COUNT(case_id) AS top, case_id - FROM test_case_runs - WHERE run_id IN (". join(',', @$run_ids) .") - AND case_run_status_id = ? - GROUP BY case_id - ORDER BY top DESC - LIMIT ?"; - my $ref = $dbh->selectall_arrayref($query, {'Slice' =>{}}, (FAILED, 10)); - foreach my $row (@$ref){ - $row->{top} = int($row->{top}); - } - - $vars->{'stripheader'} = 1 if $cgi->param('noheader'); - $vars->{'uid'} = int(rand(10000)); - $vars->{'data'} = $json->encode($ref); - $vars->{'runs'} = join(',',@run_ids); - $vars->{'plans'} = join(',',@plans); - - $template->process("testopia/reports/bar.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; - -} -elsif ($type eq 'changed'){ - my $query = - "SELECT case_run_id, case_run_status_id, close_date, from test_case_runs t - INNER JOIN test_runs on test_runs.run_id = t.run_id - WHERE test_runs.plan_id = ? - ORDER BY case_id, close_date DESC"; -} - -$cgi->param('current_tab', 'run'); -$cgi->param('viewall', 1); -my $report = Bugzilla::Extension::Testopia::Report->new('run', 'tr_list_runs.cgi', $cgi); -$vars->{'report'} = $report; - -### From Bugzilla report.cgi by Gervase Markham -my $formatparam = $cgi->param('format'); -my $report_action = $cgi->param('report_action'); -if ($report_action eq "data") { - # So which template are we using? If action is "wrap", we will be using - # no format (it gets passed through to be the format of the actual data), - # and either report.csv.tmpl (CSV), or report.html.tmpl (everything else). - # report.html.tmpl produces an HTML framework for either tables of HTML - # data, or images generated by calling report.cgi again with action as - # "plot". - $formatparam =~ s/[^a-zA-Z\-]//g; - trick_taint($formatparam); - $vars->{'format'} = $formatparam; - $formatparam = ''; -} -elsif ($report_action eq "plot") { - # If action is "plot", we will be using a format as normal (pie, bar etc.) - # and a ctype as normal (currently only png.) - $vars->{'cumulate'} = $cgi->param('cumulate') ? 1 : 0; - $vars->{'x_labels_vertical'} = $cgi->param('x_labels_vertical') ? 1 : 0; - $vars->{'data'} = $report->{'image_data'}; -} -else { - ThrowUserError("unknown_action", {action => $cgi->param('report_action')}); -} - -my $format = $template->get_format("testopia/reports/report", $formatparam, - scalar($cgi->param('ctype'))); - -my @time = localtime(time()); -my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3]; -my $filename = "report-" . $date . ".$format->{extension}"; - -my $disp = "inline"; -# We set CSV files to be downloaded, as they are designed for importing -# into other programs. -if ( $format->{'extension'} eq "csv" || $format->{'extension'} eq "xml" ){ - $disp = "attachment"; -} - -print $cgi->header(-type => $format->{'ctype'}, - -content_disposition => "$disp; filename=$filename"); - -$vars->{'time'} = $date; -$template->process("$format->{'template'}", $vars) - || ThrowTemplateError($template->error()); - -exit; -