Author: cfinck
Date: Mon Jan 5 06:35:05 2009
New Revision: 38579
URL:
http://svn.reactos.org/svn/reactos?rev=38579&view=rev
Log:
Introducing "ReactOS Web Test Manager", an interface for finding, viewing and
comparing the results of automatic regression tests B-)
The interface mostly looks and works similar to the "getbuilds" one.
After you've selected the tests you want to view or compare, another page will be
opened showing all results in tabular form and each differences to the previous one.
It is also possible to drag & drop the column headers and all associated results to
get the table to look like you want it.
You can also get a detailed overview about a particular result including the original log.
But try that all for yourself, when it's on the server :-P
The results need to be submitted through a web service, which is also provided by this
commit.
The designed application for communicating with the web service and submitting the results
follows in my next commit.
Added:
trunk/web/reactos.org/htdocs/testman/ (with props)
trunk/web/reactos.org/htdocs/testman/ajax-search.php (with props)
trunk/web/reactos.org/htdocs/testman/compare.php (with props)
trunk/web/reactos.org/htdocs/testman/config.inc.php (with props)
trunk/web/reactos.org/htdocs/testman/css/ (with props)
trunk/web/reactos.org/htdocs/testman/css/compare.css (with props)
trunk/web/reactos.org/htdocs/testman/css/detail.css (with props)
trunk/web/reactos.org/htdocs/testman/css/index.css (with props)
trunk/web/reactos.org/htdocs/testman/detail.php (with props)
trunk/web/reactos.org/htdocs/testman/index.php (with props)
trunk/web/reactos.org/htdocs/testman/js/ (with props)
trunk/web/reactos.org/htdocs/testman/js/compare.js.php (with props)
trunk/web/reactos.org/htdocs/testman/js/detail.js.php (with props)
trunk/web/reactos.org/htdocs/testman/js/index.js.php (with props)
trunk/web/reactos.org/htdocs/testman/lang/ (with props)
trunk/web/reactos.org/htdocs/testman/lang/de.inc.php (with props)
trunk/web/reactos.org/htdocs/testman/lang/en.inc.php (with props)
trunk/web/reactos.org/htdocs/testman/languages.inc.php (with props)
trunk/web/reactos.org/htdocs/testman/utils.inc.php (with props)
trunk/web/reactos.org/htdocs/testman/webservice/ (with props)
trunk/web/reactos.org/htdocs/testman/webservice/index.php (with props)
trunk/web/reactos.org/htdocs/testman/webservice/lib/ (with props)
trunk/web/reactos.org/htdocs/testman/webservice/lib/WineTest.class.php (with props)
trunk/web/reactos.org/resources/testman/ (with props)
trunk/web/reactos.org/resources/testman/testman.sql (with props)
Propchange:
trunk/web/reactos.org/htdocs/testman/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/ajax-search.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/aja…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/ajax-search.php (added)
+++
trunk/web/reactos.org/htdocs/testman/ajax-search.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,131 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: AJAX backend for the Search feature
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ header("Content-type: text/xml");
+
+ if(!isset($_GET["startrev"]) || !isset($_GET["endrev"]) ||
!isset($_GET["platform"]))
+ die("<error>Necessary information not
specified!</error>");
+
+
+ require_once("config.inc.php");
+ require_once("utils.inc.php");
+
+ try
+ {
+ $dbh = new PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
+ }
+ catch(PDOException $e)
+ {
+ // Give no exact error message here, so no server internals are exposed
+ die("<error>Could not establish the DB
connection</error>");
+ }
+
+ // Prepare the WHERE clause
+ $where = "";
+
+ if($_GET["startrev"] || $_GET["startid"] ||
$_GET["platform"])
+ {
+ // Begin the WHERE clause with "WHERE 1 ", so we can begin all
following statements with AND :-)
+ $where = "WHERE 1 ";
+
+ if($_GET["startrev"])
+ $where .= "AND revision >= " .
(int)$_GET["startrev"] . " AND revision <= " .
(int)$_GET["endrev"] . " ";
+
+ if($_GET["startid"])
+ $where .= "AND id >= " .
(int)$_GET["startid"] . " ";
+
+ if($_GET["platform"])
+ $where .= "AND platform LIKE " .
$dbh->quote($_GET["platform"] . "%") . " ";
+ }
+
+ // Prepare the ORDER clause
+ $order = "ORDER BY revision ASC, id ASC ";
+
+ echo "<results>";
+
+ // First determine how many results we would get in total with this query
+ $stmt = $dbh->query("SELECT COUNT(*) FROM " . DB_TESTMAN .
".winetest_runs " . $where) or die("<error>Query failed
#1</error>");
+ $result_count = $stmt->fetchColumn();
+
+ if($result_count > RESULTS_PER_PAGE)
+ {
+ // The number of results exceeds the number of results per page.
+ // Therefore we will only output all results up to the maximum number of
results per page with this call.
+ $result_count = RESULTS_PER_PAGE;
+ echo "<moreresults>1</moreresults>";
+ }
+ else
+ {
+ echo "<moreresults>0</moreresults>";
+ }
+
+ printf("<resultcount>%d</resultcount>", $result_count);
+
+ $first_id = 0;
+ $first_revision = 0;
+ $last_revision = 0;
+ $next_id = 0;
+
+ if($result_count)
+ {
+ if($_GET["resultlist"])
+ {
+ $stmt = $dbh->query(
+ "SELECT r.id, UNIX_TIMESTAMP(r.timestamp) timestamp,
u.user_name, r.revision, r.platform " .
+ "FROM " . DB_TESTMAN . ".winetest_runs r
" .
+ "JOIN " . DB_ROSCMS . ".users u ON
r.user_id = u.user_id " .
+ $where .
+ $order .
+ "LIMIT " . RESULTS_PER_PAGE
+ ) or die("<error>Query failed #2</error>");
+
+ $first = true;
+
+ while($row = $stmt->fetch(PDO::FETCH_ASSOC))
+ {
+ if($first)
+ {
+ $first_id = $row["id"];
+ $first_revision = $row["revision"];
+ $first = false;
+ }
+
+ echo "<result>";
+ printf("<id>%d</id>",
$row["id"]);
+ printf("<date>%s</date>",
GetDateString($row["timestamp"]));
+ printf("<user>%s</user>",
htmlspecialchars($row["user_name"]));
+ printf("<revision>%d</revision>",
$row["revision"]);
+ printf("<platform>%s</platform>",
GetPlatformString($row["platform"]));
+ echo "</result>";
+
+ $last_revision = $row["revision"];
+ }
+ }
+ else
+ {
+ // Get the first and last revision belonging to this call
+ $stmt = $dbh->query("SELECT id, revision FROM " .
DB_TESTMAN . ".winetest_runs " . $where . $order . "LIMIT 1") or
die("<error>Query failed #3</error>");
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $first_id = $row["id"];
+ $first_revision = $row["revision"];
+
+ $stmt = $dbh->query("SELECT revision FROM " .
DB_TESTMAN . ".winetest_runs " . $where . $order . "LIMIT " .
($result_count - 1) . ", 1") or die("<error>Query failed
#4</error>");
+ $last_revision = $stmt->fetchColumn();
+ }
+
+ $stmt = $dbh->query("SELECT id FROM " . DB_TESTMAN .
".winetest_runs " . $where . $order . "LIMIT " . $result_count .
", 1") or die("<error>Query failed #5</error>");
+ $next_id = $stmt->fetchColumn();
+ }
+
+ printf("<firstid>%d</firstid>", $first_id);
+ printf("<firstrev>%d</firstrev>", $first_revision);
+ printf("<lastrev>%d</lastrev>", $last_revision);
+ printf("<nextid>%d</nextid>", $next_id);
+
+ echo "</results>";
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/ajax-search.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/compare.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/com…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/compare.php (added)
+++
trunk/web/reactos.org/htdocs/testman/compare.php [iso-8859-1] Mon Jan 5 06:35:05 2009
@@ -1,0 +1,263 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Compare Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8 without BOM
+*/
+
+ define("ROOT_PATH", "../");
+
+ require_once("config.inc.php");
+ require_once("utils.inc.php");
+ require_once("languages.inc.php");
+ require_once(ROOT_PATH . "shared/subsys_layout.php");
+
+ GetLanguage();
+ require_once("lang/$lang.inc.php");
+
+
+ function GetDifference(&$current_result_row, &$prev_result_row, $subject)
+ {
+ if(!$prev_result_row["id"] || $current_result_row[$subject] ==
$prev_result_row[$subject])
+ return " ";
+
+ $diff = $current_result_row[$subject] - $prev_result_row[$subject];
+
+ if($diff > 0)
+ return "(+$diff)";
+ else
+ return "($diff)";
+ }
+
+ function CheckIfChanged(&$changed, &$temp, &$current)
+ {
+ if($changed)
+ return;
+
+ if($temp == -1)
+ $temp = $current;
+ else if($current != $temp)
+ $changed = true;
+ }
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="content-type" content="text/html;
charset=utf-8" />
+ <title><?php echo $testman_langres["compare_title"];
?></title>
+ <link rel="stylesheet" type="text/css"
href="../shared/css/basic.css" />
+ <link rel="stylesheet" type="text/css"
href="../shared/css/reactos.css" />
+ <link rel="stylesheet" type="text/css"
href="css/compare.css" />
+ <script type="text/javascript">
+ //<![CDATA[
+ <?php require_once("js/compare.js.php"); ?>
+ //]]>
+ </script>
+</head>
+<body onload="Load()">
+
+<h2><?php echo $testman_langres["compare_title"]; ?></h2>
+
+<?php
+ if(!isset($_GET["ids"]))
+ die("Necessary information not specified");
+
+ $id_array = explode(",", $_GET["ids"]);
+
+ if(!$id_array)
+ die("<i>ids</i> parameter is no array");
+
+ // Verify that the array only contains numeric values to prevent SQL injections
+ foreach($id_array as $id)
+ if(!is_numeric($id))
+ die("<i>ids</i> parameter is not entirely
numeric!");
+
+ if(count($id_array) > MAX_COMPARE_RESULTS)
+ die(sprintf($testman_langres["maxselection"],
MAX_COMPARE_RESULTS));
+
+ if(count($id_array) > 1)
+ {
+ echo '<div>';
+ printf('<input type="checkbox" id="showchanged"
onclick="ShowChangedCheckbox_OnClick(this)" /> %s',
$testman_langres["showchanged"]);
+ echo '</div><br />';
+ }
+?>
+
+<table id="legend" cellspacing="5">
+ <tr>
+ <td id="intro"><?php echo
$testman_langres["legend"]; ?>:</td>
+
+ <td class="box" style="background:
black;"></td>
+ <td><?php echo $testman_langres["totaltests"];
?></td>
+
+ <td class="box" style="background:
#BF0A00;"></td>
+ <td><?php echo $testman_langres["failedtests"];
?></td>
+
+ <td class="box" style="background:
#1701E4;"></td>
+ <td><?php echo $testman_langres["todotests"];
?></td>
+
+ <td class="box" style="background:
#818181;"></td>
+ <td><?php echo $testman_langres["skippedtests"];
?></td>
+
+ <td class="box" style="background:
green;"></td>
+ <td><?php echo $testman_langres["difference"];
?></td>
+ </tr>
+</table>
+
+<?php
+ // Establish a DB connection
+ try
+ {
+ $dbh = new PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
+ }
+ catch(PDOException $e)
+ {
+ // Give no exact error message here, so no server internals are exposed
+ die("Could not establish the DB connection");
+ }
+
+ // Get all test suites for which we have at least one result in our ID list
+ $suites_stmt = $dbh->query(
+ "SELECT DISTINCT s.id, s.module, s.test " .
+ "FROM " . DB_TESTMAN . ".winetest_suites s " .
+ "JOIN " . DB_TESTMAN . ".winetest_results e ON e.suite_id =
s.id " .
+ "WHERE test_id IN (" . $_GET["ids"] . ") " .
+ "ORDER BY s.module ASC, s.test ASC"
+ ) or die("Query failed #1");
+
+ // Get the test results for each column
+ $result_stmt = array();
+ $i = 0;
+
+ foreach($id_array as $id)
+ {
+ $result_stmt[$i] = $dbh->prepare(
+ "SELECT e.id, e.count, e.todo, e.failures, e.skipped " .
+ "FROM " . DB_TESTMAN . ".winetest_suites s " .
+ "LEFT JOIN " . DB_TESTMAN . ".winetest_results e ON
e.suite_id = s.id AND e.test_id = :testid " .
+ "WHERE s.id IN (" .
+ "SELECT s.id " .
+ "FROM " . DB_TESTMAN . ".winetest_suites s
" .
+ "JOIN " . DB_TESTMAN . ".winetest_results e
ON e.suite_id = s.id " .
+ "WHERE e.test_id IN (" . $_GET["ids"]
. ") " .
+ ") " .
+ "ORDER BY s.module, s.test"
+ );
+ $result_stmt[$i]->bindParam(":testid", $id);
+ $result_stmt[$i]->execute() or die("Query failed #2 for statement
$i" . print_r($result_stmt[$i]->errorInfo(), true));
+
+ $i++;
+ }
+
+ echo '<table id="comparetable" class="datatable"
cellspacing="0" cellpadding="0">';
+ echo '<thead><tr class="head">';
+ printf('<th class="TestSuite">%s</th>',
$testman_langres["testsuite"]);
+
+ $stmt = $dbh->prepare(
+ "SELECT UNIX_TIMESTAMP(r.timestamp) timestamp, u.user_name,
r.revision, r.platform " .
+ "FROM " . DB_TESTMAN . ".winetest_runs r " .
+ "JOIN " . DB_ROSCMS . ".users u ON r.user_id = u.user_id
" .
+ "WHERE r.id = :id"
+ );
+
+ foreach($id_array as $id)
+ {
+ $stmt->bindParam(":id", $id);
+ $stmt->execute() or die("Query failed #3");
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ echo '<th
onmousedown="ResultHead_OnMouseDown(this)">';
+ printf($testman_langres["resulthead"],
$row["revision"], GetPlatformString($row["platform"]),
$row["user_name"], GetDateString($row["timestamp"]));
+ echo '</th>';
+ }
+
+ echo '</tr></thead>';
+ echo '<tbody>';
+
+ $oddeven = false;
+ $unchanged = array();
+
+ while($suites_row = $suites_stmt->fetch(PDO::FETCH_ASSOC))
+ {
+ printf('<tr id="suite_%s" class="%s">',
$suites_row["id"], ($oddeven ? "odd" : "even"));
+ printf('<td onmouseover="Cell_OnMouseOver(this)"
onmouseout="Cell_OnMouseOut(this)">%s:%s</td>',
$suites_row["module"], $suites_row["test"]);
+
+ $changed = false;
+ $prev_result_row = null;
+ $temp_totaltests = -1;
+ $temp_failedtests = -1;
+ $temp_todotests = -1;
+ $temp_skippedtests = -1;
+
+ for($i = 0; $i < count($result_stmt); $i++)
+ {
+ $result_row = $result_stmt[$i]->fetch(PDO::FETCH_ASSOC);
+
+ echo '<td onmouseover="Cell_OnMouseOver(this)"
onmouseout="Cell_OnMouseOut(this)"';
+
+ if($result_row["id"])
+ printf(' class="clickable"
onclick="Result_OnClick(%d)"', $result_row["id"]);
+
+ echo '>';
+
+ if($result_row["id"])
+ {
+ // Check whether there are any changes within the test
results of several runs
+ CheckIfChanged($changed, $temp_totaltests,
$result_row["count"]);
+ CheckIfChanged($changed, $temp_failedtests,
$result_row["failedtests"]);
+ CheckIfChanged($changed, $temp_todotests,
$result_row["todo"]);
+ CheckIfChanged($changed, $temp_skippedtests,
$result_row["skipped"]);
+
+ echo '<table class="celltable">';
+ echo '<tr>';
+ printf('<td colspan="3"
title="%s" class="totaltests">%d <span
class="diff">%s</span></td>',
$testman_langres["totaltests"], $result_row["count"],
GetDifference($result_row, $prev_result_row, "count"));
+ echo '</tr><tr>';
+ printf('<td title="%s"
class="failedtests">%d <span
class="diff">%s</span></td>',
$testman_langres["failedtests"], $result_row["failed"],
GetDifference($result_row, $prev_result_row, "failedtests"));
+ printf('<td title="%s"
class="todotests">%d <span
class="diff">%s</span></td>',
$testman_langres["todotests"], $result_row["todo"],
GetDifference($result_row, $prev_result_row, "todotests"));
+ printf('<td title="%s"
class="skippedtests">%d <span
class="diff">%s</span></td>',
$testman_langres["skippedtests"], $result_row["skipped"],
GetDifference($result_row, $prev_result_row, "skippedtests"));
+ echo '</tr></table>';
+ }
+ else
+ {
+ // Bloody IE Hack
+ echo " ";
+ }
+
+ echo '</td>';
+
+ $prev_result_row = $result_row;
+ }
+
+ echo '</tr>';
+
+ if(!$changed)
+ $unchanged[] = $suites_row["id"];
+
+ $oddeven = !$oddeven;
+ }
+
+ echo '</tbody></table>';
+
+ // Prepare the array containing all "unchanged" rows
+ echo "<script type=\"text/javascript\">\n";
+ echo "//<![CDATA[\n";
+ echo "var UnchangedRows = Array(";
+
+ for($i = 0; $i < count($unchanged); $i++)
+ {
+ if($i)
+ echo "," . $unchanged[$i];
+ else
+ echo $unchanged[$i];
+ }
+
+ echo ");\n";
+ echo "//]]>\n";
+ echo "</script>";
+?>
+
+</body>
+</html>
Propchange:
trunk/web/reactos.org/htdocs/testman/compare.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/config.inc.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/con…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/config.inc.php (added)
+++
trunk/web/reactos.org/htdocs/testman/config.inc.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,22 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Configuration settings
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ // DB Settings
+ // The user entered here must have:
+ // * SELECT, INSERT, UPDATE and DELETE privileges to $DB_TESTMAN
+ // * SELECT privileges to $DB_ROSCMS
+ define("DB_HOST", "localhost");
+ define("DB_USER", "root");
+ define("DB_PASS", "");
+
+ define("DB_ROSCMS", "roscms");
+ define("DB_TESTMAN", "testman");
+
+ define("RESULTS_PER_PAGE", 100);
+ define("MAX_COMPARE_RESULTS", 5);
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/config.inc.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/htdocs/testman/css/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/css/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/css/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/css/compare.css
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/css…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/css/compare.css (added)
+++
trunk/web/reactos.org/htdocs/testman/css/compare.css [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,85 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Stylesheet for the Compare Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+#legend {
+ border: solid 1px black;
+ margin-bottom: 1em;
+}
+
+#legend #intro {
+ font-weight: bold;
+ padding-right: 10px;
+}
+
+#legend td {
+ padding-right: 5px;
+}
+
+#legend td.box {
+ border: solid 1px black;
+ padding: 0;
+ width: 15px;
+}
+
+.totaltests {
+ color: black;
+}
+
+.failedtests {
+ color: #BF0A00;
+}
+
+.todotests {
+ color: #1701E4;
+}
+
+.skippedtests {
+ color: #818181;
+}
+
+.diff {
+ color: green;
+}
+
+#TempBlock {
+ background: #5984C3;
+ color: white;
+ font-weight: bold;
+}
+
+#comparetable th, #TempBlock {
+ cursor: move;
+ padding: 3px 8px 3px 3px;
+ vertical-align: bottom;
+}
+
+#comparetable th.TestSuite {
+ cursor: default;
+ width: 200px;
+}
+
+#comparetable td {
+ border-right: solid 1px #BBBBBB;
+ border-bottom: solid 1px #BBBBBB;
+ padding: 3px;
+}
+
+#comparetable td.clickable {
+ cursor: pointer;
+}
+
+.celltable {
+ width: 215px;
+}
+
+.celltable td {
+ text-align: center;
+}
+
+.celltable td.totaltests {
+ font-weight: bold;
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/css/compare.css
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/css/detail.css
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/css…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/css/detail.css (added)
+++
trunk/web/reactos.org/htdocs/testman/css/detail.css [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,20 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Stylesheet for the Result Details Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+.datatable {
+ width: 800px;
+}
+
+.datatable th, .datatable td {
+ padding: 3px;
+ vertical-align: top;
+}
+
+.datatable td.info {
+ font-weight: bold;
+ width: 200px;
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/css/detail.css
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/css/index.css
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/css…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/css/index.css (added)
+++
trunk/web/reactos.org/htdocs/testman/css/index.css [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,59 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Stylesheet for the Index Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+button {
+ font-weight: bold;
+}
+
+.datatable {
+ cursor: pointer;
+}
+
+#js_stuff {
+ /* Will be shown by the JavaScript */
+ display: none;
+}
+
+#mainbox_td, #rightbox_td {
+ vertical-align: top;
+}
+
+#rightbox_td {
+ width: 300px;
+ padding-left: 7px;
+}
+
+.datatable {
+ width: 100%;
+}
+
+th.TestCheckbox {
+ width: 30px;
+}
+
+#searchform tr td {
+ vertical-align: top;
+}
+
+#ajax_loading_search {
+ font-weight: bold;
+ margin-left: 20px;
+ visibility: hidden;
+}
+
+#infotable {
+ margin-top: 2em;
+}
+
+#infotable {
+ width: 100%;
+}
+
+#pagesbox {
+ font-weight: bold;
+ text-align: right;
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/css/index.css
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/detail.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/det…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/detail.php (added)
+++
trunk/web/reactos.org/htdocs/testman/detail.php [iso-8859-1] Mon Jan 5 06:35:05 2009
@@ -1,0 +1,123 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Result Details Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8 without BOM
+*/
+
+ define("ROOT_PATH", "../");
+
+ require_once("config.inc.php");
+ require_once("utils.inc.php");
+ require_once("languages.inc.php");
+ require_once(ROOT_PATH . "shared/subsys_layout.php");
+
+ GetLanguage();
+ require_once("lang/$lang.inc.php");
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="content-type" content="text/html;
charset=utf-8" />
+ <title><?php echo $testman_langres["detail_title"];
?></title>
+ <link rel="stylesheet" type="text/css"
href="../shared/css/basic.css" />
+ <link rel="stylesheet" type="text/css"
href="../shared/css/reactos.css" />
+ <link rel="stylesheet" type="text/css"
href="css/detail.css" />
+ <script type="text/javascript">
+ //<![CDATA[
+ <?php require_once("js/detail.js.php"); ?>
+ //]]>
+ </script>
+</head>
+<body>
+
+<h2><?php echo $testman_langres["detail_title"]; ?></h2>
+
+<?php
+ if(!isset($_GET["id"]))
+ die("Necessary information not specified");
+
+ // Establish a DB connection
+ try
+ {
+ $dbh = new PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
+ }
+ catch(PDOException $e)
+ {
+ // Give no exact error message here, so no server internals are exposed
+ die("Could not establish the DB connection");
+ }
+
+ // Get information about this result
+ $stmt = $dbh->prepare(
+ "SELECT e.log, e.count, e.todo, e.failures, e.skipped, s.module,
s.test, UNIX_TIMESTAMP(r.timestamp) timestamp, r.revision, r.platform, u.user_name "
.
+ "FROM " . DB_TESTMAN . ".winetest_results e " .
+ "JOIN " . DB_TESTMAN . ".winetest_suites s ON e.suite_id =
s.id " .
+ "JOIN " . DB_TESTMAN . ".winetest_runs r ON e.test_id =
r.id " .
+ "JOIN " . DB_ROSCMS . ".users u ON r.user_id = u.user_id
" .
+ "WHERE e.id = :id"
+ );
+ $stmt->bindParam(":id", $_GET["id"]);
+ $stmt->execute() or die("Query failed #1");
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+?>
+
+<table class="datatable" cellspacing="0"
cellpadding="0">
+ <tr class="head">
+ <th colspan="2"><?php echo
$testman_langres["thisresult"]; ?></th>
+ </tr>
+
+ <tr class="even" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["testsuite"]; ?>:</td>
+ <td><?php echo $row["module"]; ?>:<?php echo
$row["test"]; ?></td>
+ </tr>
+ <tr class="odd" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["totaltests"]; ?>:</td>
+ <td><?php echo $row["count"]; ?></td>
+ </tr>
+ <tr class="even" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["failedtests"]; ?>:</td>
+ <td><?php echo $row["failures"]; ?></td>
+ </tr>
+ <tr class="odd" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["todotests"]; ?>:</td>
+ <td><?php echo $row["todo"]; ?></td>
+ </tr>
+ <tr class="even" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["skippedtests"]; ?>:</td>
+ <td><?php echo $row["skipped"]; ?></td>
+ </tr>
+ <tr class="odd" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["log"]; ?>:</td>
+ <td><pre><?php echo $row["log"];
?></pre></td>
+ </tr>
+</table><br />
+
+<table class="datatable" cellspacing="0"
cellpadding="0">
+ <tr class="head">
+ <th colspan="2"><?php echo
$testman_langres["associatedtest"]; ?></th>
+ </tr>
+
+ <tr class="even" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["revision"]; ?>:</td>
+ <td><?php echo $row["revision"]; ?></td>
+ </tr>
+ <tr class="odd" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["platform"]; ?>:</td>
+ <td><?php echo GetPlatformString($row["platform"]);
?></td>
+ </tr>
+ <tr class="even" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["user"]; ?>:</td>
+ <td><?php echo $row["user_name"]; ?></td>
+ </tr>
+ <tr class="odd" onmouseover="Row_OnMouseOver(this)"
onmouseout="Row_OnMouseOut(this)">
+ <td class="info"><?php echo
$testman_langres["date"]; ?>:</td>
+ <td><?php echo GetDateString($row["timestamp"]);
?></td>
+ </tr>
+</table>
+
+</body>
+</html>
Propchange:
trunk/web/reactos.org/htdocs/testman/detail.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/index.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/ind…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/index.php (added)
+++
trunk/web/reactos.org/htdocs/testman/index.php [iso-8859-1] Mon Jan 5 06:35:05 2009
@@ -1,0 +1,242 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Main Page
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8 without BOM
+*/
+
+ define("ROOT_PATH", "../");
+
+ require_once("config.inc.php");
+ require_once("utils.inc.php");
+ require_once("languages.inc.php");
+ require_once(ROOT_PATH . "shared/subsys_layout.php");
+ require_once(ROOT_PATH . "shared/svn.php");
+
+ GetLanguage();
+ require_once(ROOT_PATH . "shared/lang/$lang.inc.php");
+ require_once("lang/$lang.inc.php");
+
+ $rev = GetLatestRevision();
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="content-type" content="text/html;
charset=utf-8" />
+ <title><?php echo $testman_langres["index_title"];
?></title>
+ <link rel="stylesheet" type="text/css"
href="../shared/css/menu.css" />
+ <link rel="stylesheet" type="text/css"
href="../shared/css/reactos.css" />
+ <link rel="stylesheet" type="text/css"
href="css/index.css" />
+ <script type="text/javascript">
+ //<![CDATA[
+ document.write('<style type="text/css">');
+ document.write('#js_stuff {display: block;}');
+ document.write('<\/style>');
+ //]]>
+ </script>
+ <script type="text/javascript"
src="../shared/js/ajax.js"></script>
+ <script type="text/javascript">
+ //<![CDATA[
+ <?php require_once("js/index.js.php"); ?>
+ //]]>
+ </script>
+</head>
+<body>
+
+<?php
+ BasicLayout($lang);
+ LanguageBox($lang);
+?>
+</td>
+<td id="content">
+
+<h1><?php echo $testman_langres["index_header"]; ?></h1>
+<h2><?php echo $testman_langres["index_title"]; ?></h2>
+
+<p><?php echo $testman_langres["index_intro"]; ?></p>
+
+<noscript>
+ <div class="bubble_bg">
+ <div class="rounded_ll">
+ <div class="rounded_lr">
+ <div class="rounded_ul">
+ <div class="rounded_ur">
+
+ <div class="bubble">
+ <b><?php echo
$testman_langres["js_disclaimer"]; ?></b>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</noscript>
+
+<div id="js_stuff">
+ <table width="100%" cellspacing="0"
cellpadding="0">
+ <tr>
+ <td id="mainbox_td">
+ <div class="bubble_bg">
+ <div class="rounded_ll">
+ <div class="rounded_lr">
+ <div class="rounded_ul">
+ <div class="rounded_ur">
+
+ <div class="bubble">
+ <h1><?php echo
$testman_langres["lastresults_header"]; ?></h1>
+
+ <table class="datatable"
cellspacing="0" cellpadding="0">
+ <thead>
+ <tr
class="head">
+ <th
class="TestCheckbox"></th>
+ <th><?php
echo $testman_langres["date"]; ?></th>
+ <th><?php
echo $testman_langres["revision"]; ?></th>
+ <th><?php
echo $testman_langres["user"]; ?></th>
+ <th><?php
echo $testman_langres["platform"]; ?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ try
+ {
+ $dbh = new
PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
+ }
+ catch(PDOException
$e)
+ {
+ // Give no
exact error message here, so no server internals are exposed
+
die("<error>Could not establish the DB connection</error>");
+ }
+
+ $stmt =
$dbh->query(
+
"SELECT r.id, UNIX_TIMESTAMP(r.timestamp) timestamp, u.user_name, r.revision,
r.platform " .
+ "FROM
" . DB_TESTMAN . ".winetest_runs r " .
+ "JOIN
" . DB_ROSCMS . ".users u ON r.user_id = u.user_id " .
+
"ORDER BY revision DESC, id DESC " .
+
"LIMIT 10"
+ ) or
die("Query failed #1");
+
+ $oddeven = false;
+ $ids = array();
+
+ while($row =
$stmt->fetch(PDO::FETCH_ASSOC))
+ {
+ $ids[] =
$row["id"];
+
+
printf('<tr class="%s" onmouseover="Result_OnMouseOver(this)"
onmouseout="Result_OnMouseOut(this)">', ($oddeven ? "odd" :
"even"));
+
printf('<td><input onclick="Result_OnCheckboxClick(this)"
type="checkbox" name="test_%s" /></td>',
$row["id"]);
+
printf('<td onclick="Result_OnCellClick(this)">%s</td>',
GetDateString($row["timestamp"]));
+
printf('<td onclick="Result_OnCellClick(this)">%s</td>',
$row["revision"]);
+
printf('<td onclick="Result_OnCellClick(this)">%s</td>',
htmlspecialchars($row["user_name"]));
+
printf('<td onclick="Result_OnCellClick(this)">%s</td>',
GetPlatformString($row["platform"]));
+ echo
"</tr>";
+
+ $oddeven =
!$oddeven;
+ }
+ ?>
+ </tbody>
+ </table>
+
+ <?php
+ // Ensure that all checkboxes are
unchecked with a JavaScript (some browsers keep them checked after a reload)
+ echo "<script
type=\"text/javascript\">\n";
+ echo "//<![CDATA[\n";
+
+ foreach($ids as $id)
+
printf('document.getElementsByName("test_%s")[0].checked = false;',
$id);
+
+ echo "\n//]]>\n";
+ echo "</script>";
+ ?>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="bubble_bg">
+ <div class="rounded_ll">
+ <div class="rounded_lr">
+ <div class="rounded_ul">
+ <div class="rounded_ur">
+
+ <div class="bubble">
+ <h1><?php echo
$testman_langres["search_header"]; ?></h1>
+
+ <table id="searchform">
+ <tr>
+ <td><?php echo
$testman_langres["search_revision"]; ?>:</td>
+ <td>
+ <input
type="text" id="search_revision" value=""
size="12" onkeyup="SearchRevisionInput_OnKeyUp(this)" /><br
/>
+
+ <img
src="../shared/images/info.gif" alt="" /> <?php
printf($shared_langres["rangeinfo"], $rev, ($rev - 50), $rev); ?>
+ </td>
+ </tr>
+ <tr>
+ <td><?php echo
$testman_langres["search_platform"]; ?>:</td>
+ <td>
+ <select
id="search_platform" size="1">
+
<option></option>
+ <option
value="reactos">ReactOS</option>
+ <option
value="5.0">Windows 2000</option>
+ <option
value="5.1">Windows XP</option>
+ <option
value="5.2">Windows XP x64/Server 2003</option>
+ <option
value="6.0">Windows Vista/Server 2008</option>
+ <option
value="6.1">Windows 7</option>
+ </select>
+ </td>
+ </tr>
+ </table><br />
+
+ <button
onclick="SearchButton_OnClick()"><?php echo
$testman_langres["search_button"]; ?></button>
+
+ <span
id="ajax_loading_search">
+ <img
src="../shared/images/ajax_loading.gif" alt="" /> <?php echo
$testman_langres["searching"]; ?>...
+ </span>
+
+ <div id="searchtable">
+ <!-- Filled by the JavaScript
-->
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </td>
+
+ <td id="rightbox_td">
+ <div class="bubble_bg">
+ <div class="rounded_ll">
+ <div class="rounded_lr">
+ <div class="rounded_ul">
+ <div class="rounded_ur">
+
+ <div class="bubble">
+ <div id="status"><?php
printf($testman_langres["status"], "<b>0</b>");
?></div><br />
+
+ <button
onclick="CompareButton_OnClick()"><?php echo
$testman_langres["compare_button"]; ?></button>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </td>
+ </tr>
+ </table>
+</div>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
Propchange:
trunk/web/reactos.org/htdocs/testman/index.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/htdocs/testman/js/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/js/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/js/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/js/compare.js.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/js/…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/js/compare.js.php (added)
+++
trunk/web/reactos.org/htdocs/testman/js/compare.js.php [iso-8859-1] Mon Jan 5
06:35:05 2009
@@ -1,0 +1,333 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: JavaScript file for the Compare Page (parsed by PHP before)
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8
+*/
+
+var CurrentLeftDragBorder;
+var CurrentRightDragBorder;
+var DragColumn;
+var DragX;
+var DragOffset;
+var MaxLeftDragBorder;
+var MaxRightDragBorder;
+var MouseX;
+var OverlappedForSwap;
+var SwapColumn;
+var TableRowEquiv;
+var TempBlock;
+
+var ColumnDefaultColor = "#5984C3";
+var ColumnDragColor = "#8AA9D5";
+var ColumnOverlapColor = "#D0DDEE";
+
+function Cell_OnMouseOver(elem)
+{
+ elem.style.background = "#FFFFCC";
+}
+
+function Cell_OnMouseOut(elem)
+{
+ if(elem.parentNode.className == "odd")
+ elem.style.background = "#DDDDDD";
+ else
+ elem.style.background = "#EEEEEE";
+}
+
+function GetColumnIndex(th)
+{
+ var childs = th.parentNode.childNodes;
+
+ for(var i = 0; i < childs.length; i++)
+ if(childs[i] == th)
+ return i;
+}
+
+function ShowChangedCheckbox_OnClick(checkbox)
+{
+ var value = (checkbox.checked ? "none" : TableRowEquiv);
+
+ for(var i = 0; i < UnchangedRows.length; i++)
+ document.getElementById("suite_" +
UnchangedRows[i]).style.display = value;
+
+ document.cookie = "showchanged=" + (checkbox.checked ? "1" :
"0");
+}
+
+function AddDifferenceForColumn(th)
+{
+ var Index = GetColumnIndex(th);
+ var trs =
document.getElementById("comparetable").childNodes[1].childNodes;
+
+ // Check whether this is the first real column
+ if(Index == 1)
+ {
+ // Remove all difference data in this case as there is no previous element
+ for(var i = 0; i < trs.length; i++)
+ {
+ var tds =
trs[i].childNodes[Index].getElementsByTagName("td");
+
+ for(var j = 0; j < tds.length; j++)
+ {
+ // \u00A0 =
+
tds[j].getElementsByTagName("span")[0].firstChild.data = "\u00A0";
+ }
+ }
+
+ return;
+ }
+
+ // No, then add the difference data accordingly
+ for(var i = 0; i < trs.length; i++)
+ {
+ // We can only add difference data if the current table and the previous
one contain tables with result data
+ if(trs[i].childNodes[Index].firstChild.nodeName != "TABLE" ||
trs[i].childNodes[Index - 1].firstChild.nodeName != "TABLE")
+ continue;
+
+ var tds = trs[i].childNodes[Index].getElementsByTagName("td");
+
+ for(var j = 0; j < tds.length; j++)
+ {
+ var CurrentValue = parseInt(tds[j].firstChild.data);
+ var PreviousValue = parseInt(trs[i].childNodes[Index -
1].getElementsByTagName("td")[j].firstChild.data);
+
+ // Calculate the difference
+ var Diff = CurrentValue - PreviousValue;
+
+ if(Diff > 0)
+ var DiffString = String("(+" + Diff +
")");
+ else if(Diff < 0)
+ var DiffString = String("(" + Diff +
")");
+ else
+ var DiffString = "\u00A0";
+
+ tds[j].getElementsByTagName("span")[0].firstChild.data =
DiffString;
+ }
+ }
+}
+
+function GetAbsoluteOffsetLeft(elem)
+{
+ var left = 0;
+
+ while(elem)
+ {
+ left += elem.offsetLeft;
+ elem = elem.offsetParent;
+ }
+
+ return left;
+}
+
+function GetAbsoluteOffsetTop(elem)
+{
+ var top = 0;
+
+ while(elem)
+ {
+ top += elem.offsetTop;
+ elem = elem.offsetParent;
+ }
+
+ return top;
+}
+
+function Document_OnMouseMove(event)
+{
+ // IE stores the event in window.event...
+ if(!event)
+ event = window.event;
+
+ MouseX = event.clientX;
+
+ // Drag if there's something to do
+ if(!DragColumn)
+ return;
+
+ var PosX = MouseX - DragOffset;
+
+ // Check whether the user is allowed to move anything to the current mouse
position
+ if(PosX < CurrentLeftDragBorder || PosX > CurrentRightDragBorder)
+ return;
+
+ // Check whether the user is moving to left or right
+ if(MouseX - DragX > 0)
+ var NewSwapColumn = DragColumn.nextSibling;
+ else if(MouseX - DragX < 0)
+ var NewSwapColumn = DragColumn.previousSibling;
+
+ // If we have any other swap column, reset it to the default color
+ if(SwapColumn && NewSwapColumn != SwapColumn)
+ SwapColumn.style.background = ColumnDefaultColor;
+
+ SwapColumn = NewSwapColumn;
+
+ if(!SwapColumn)
+ return;
+
+ SwapColumn.style.background = ColumnDragColor;
+
+ if(!TempBlock)
+ {
+ // The only way we can "move the column header" flawlessy and
compatible with all major browsers is emulating the behaviour :-)
+ // Therefore we create a <div> element for moving and set the column
header to move invisible
+ TempBlock = document.createElement("div");
+
+ for(var i = 0; i < DragColumn.childNodes.length; i++)
+ TempBlock.appendChild(DragColumn.childNodes[i].cloneNode(true));
+
+ TempBlock.id = "TempBlock";
+ TempBlock.style.position = "absolute";
+ TempBlock.style.top = GetAbsoluteOffsetTop(DragColumn) + "px";
+
+ document.body.insertBefore(TempBlock,
document.getElementById("comparetable"));
+ DragColumn.style.visibility = "hidden";
+ }
+
+ // Move the block
+ TempBlock.style.left = PosX + "px";
+
+ var TempOffsetLeft = GetAbsoluteOffsetLeft(TempBlock);
+ var SwapOffsetLeft = GetAbsoluteOffsetLeft(SwapColumn);
+
+ // Check if the dragged column overlaps the swap column by at least the half
+ OverlappedForSwap = (NewSwapColumn == DragColumn.nextSibling)
+ ? (TempOffsetLeft + TempBlock.offsetWidth > SwapOffsetLeft +
SwapColumn.offsetWidth / 2)
+ : (TempOffsetLeft < SwapOffsetLeft + SwapColumn.offsetWidth / 2);
+
+ // Set the swap column to the overlap color in this case
+ if(OverlappedForSwap)
+ SwapColumn.style.background = ColumnOverlapColor;
+}
+
+function SwapElements(elem1, elem2)
+{
+ // outerHTML is too unsupported, so we have to copy all column's attributes
one after another
+ var TempClass = elem1.className;
+ var TempHTML = elem1.innerHTML;
+ var TempOnClick = elem1.onclick;
+ var TempOnMouseOver = elem1.onmouseover;
+ var TempOnMouseOut = elem1.onmouseout;
+
+ elem1.className = elem2.className;
+ elem1.innerHTML = elem2.innerHTML;
+ elem1.onclick = elem2.onclick;
+ elem1.onmouseover = elem2.onmouseover;
+ elem1.onmouseout = elem2.onmouseout;
+
+ elem2.className = TempClass;
+ elem2.innerHTML = TempHTML;
+ elem2.onclick = TempOnClick;
+ elem2.onmouseover = TempOnMouseOver;
+ elem2.onmouseout = TempOnMouseOut;
+}
+
+function Document_OnMouseUp()
+{
+ if(!DragColumn)
+ return;
+
+ // This marks the end of a Drag & Drop operation
+ if(SwapColumn)
+ {
+ if(OverlappedForSwap)
+ {
+ // Swap the column headers
+ SwapElements(DragColumn, SwapColumn);
+
+ // Swap all cells of these columns
+ var DragColumnIndex = GetColumnIndex(DragColumn);
+ var SwapColumnIndex = GetColumnIndex(SwapColumn);
+ var tbody_trs =
document.getElementById("comparetable").childNodes[1].childNodes;
+
+ for(var i = 0; i < tbody_trs.length; i++)
+ SwapElements(tbody_trs[i].childNodes[DragColumnIndex],
tbody_trs[i].childNodes[SwapColumnIndex]);
+
+ AddDifferenceForColumn(DragColumn);
+ AddDifferenceForColumn(SwapColumn);
+
+ if(DragColumnIndex > SwapColumnIndex)
+ var NextColumn = DragColumn.nextSibling;
+ else
+ var NextColumn = SwapColumn.nextSibling;
+
+ if(NextColumn)
+ AddDifferenceForColumn(NextColumn);
+ }
+
+ // Reset everything
+ DragColumn.style.visibility = "visible";
+ document.body.removeChild(TempBlock);
+ SwapColumn.style.background = ColumnDefaultColor;
+ }
+
+ // Cleanup
+ DragColumn = null;
+ SwapColumn = null;
+ TempBlock = null;
+}
+
+function ResultHead_OnMouseDown(th)
+{
+ DragColumn = th;
+ DragX = MouseX;
+ DragOffset = DragX - GetAbsoluteOffsetLeft(th);
+
+ // The drag borders are set to the previous and next "real" columns
+ // If there are no more "real" columns, they are set to the maximum
borders
+ CurrentLeftDragBorder = Math.max(GetAbsoluteOffsetLeft(th.previousSibling),
MaxLeftDragBorder);
+
+ if(th.nextSibling)
+ CurrentRightDragBorder = Math.min(GetAbsoluteOffsetLeft(th.nextSibling),
MaxRightDragBorder);
+ else
+ CurrentRightDragBorder = MaxRightDragBorder;
+}
+
+function GetCookieValue(cookie)
+{
+ var cookies = document.cookie.split(";");
+
+ for(var i = 0; i < cookies.length; i++)
+ {
+ var data = cookies[i].split("=");
+
+ if(data[0] == cookie)
+ return data[1];
+ }
+
+ return null;
+}
+
+function Load()
+{
+ // Prepare the Drag & Drop feature
+ document.onmousemove = Document_OnMouseMove;
+ document.onmouseup = Document_OnMouseUp;
+
+ var ths =
document.getElementById("comparetable").firstChild.firstChild.childNodes;
+ MaxLeftDragBorder = GetAbsoluteOffsetLeft(ths[1]);
+ MaxRightDragBorder = GetAbsoluteOffsetLeft(ths[ths.length - 1]);
+
+ // As always, IE needs a special handling (this time for the style of table rows)
+ if(navigator.appName == "Microsoft Internet Explorer")
+ TableRowEquiv = "block";
+ else
+ TableRowEquiv = "table-row";
+
+ // The "showchanged" checkbox will only be available if we have more
than one result
+ var checkbox = document.getElementById("showchanged");
+
+ if(checkbox)
+ {
+ // Get its value from the cookie
+ checkbox.checked = parseInt(GetCookieValue("showchanged"));
+ ShowChangedCheckbox_OnClick(checkbox);
+ }
+}
+
+function Result_OnClick(id)
+{
+ window.open("detail.php?id=" + id);
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/js/compare.js.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/js/detail.js.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/js/…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/js/detail.js.php (added)
+++
trunk/web/reactos.org/htdocs/testman/js/detail.js.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,29 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: JavaScript file for the Result Details Page (parsed by PHP before)
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8
+*/
+
+function SetRowColor(elem, color)
+{
+ tdl = elem.getElementsByTagName("td");
+
+ for(var i = 0; i < tdl.length; i++)
+ tdl[i].style.background = color;
+}
+
+function Row_OnMouseOver(elem)
+{
+ SetRowColor(elem, "#FFFFCC");
+}
+
+function Row_OnMouseOut(elem)
+{
+ if(elem.className == "odd")
+ SetRowColor(elem, "#DDDDDD");
+ else
+ SetRowColor(elem, "#EEEEEE");
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/js/detail.js.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/js/index.js.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/js/…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/js/index.js.php (added)
+++
trunk/web/reactos.org/htdocs/testman/js/index.js.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,408 @@
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: JavaScript file for the Index Page (parsed by PHP before)
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+
+ charset=utf-8
+*/
+
+var CurrentPage;
+var data;
+var FullRange;
+var inputbox_startrev;
+var inputbox_endrev;
+var PageCount;
+var ResultCount;
+var SelectedResults = new Array();
+var SelectedResultCount = 0;
+
+var REQUESTTYPE_FULLLOAD = 1;
+var REQUESTTYPE_ADDPAGE = 2;
+var REQUESTTYPE_PAGESWITCH = 3;
+
+function SetRowColor(elem, color)
+{
+ tdl = elem.getElementsByTagName("td");
+
+ for(var i = 0; i < tdl.length; i++)
+ tdl[i].style.background = color;
+}
+
+function Result_OnMouseOver(elem)
+{
+ SetRowColor(elem, "#FFFFCC");
+}
+
+function Result_OnMouseOut(elem)
+{
+ if(elem.className == "odd")
+ SetRowColor(elem, "#DDDDDD");
+ else
+ SetRowColor(elem, "#EEEEEE");
+}
+
+/**
+ * Make sure that all checkboxes for the result identified by the given checkbox are
checked.
+ * Also update our SelectedResults array appropriately.
+ */
+function UpdateSelectedResults(checkbox)
+{
+ // Make sure the user doesn't select more than he's allowed to :-)
+ if(checkbox.checked && SelectedResultCount == <?php echo
MAX_COMPARE_RESULTS; ?>)
+ {
+ alert("<?php
printf(addslashes($testman_langres["maxselection"]), MAX_COMPARE_RESULTS);
?>");
+ checkbox.checked = false;
+ return;
+ }
+
+ var id = checkbox.name.substr(5);
+
+ // Make sure all checkboxes belonging to this test show the same state
+ var elems = document.getElementsByName(checkbox.name);
+
+ for(var i = 0; i < elems.length; i++)
+ elems[i].checked = checkbox.checked;
+
+ if(checkbox.checked)
+ {
+ SelectedResults[id] = true;
+ SelectedResultCount++;
+ }
+ else
+ {
+ delete SelectedResults[id];
+ SelectedResultCount--;
+ }
+
+ // Update the status message
+ document.getElementById("status").innerHTML = "<?php
printf($testman_langres["status"], '<b>" + SelectedResultCount +
"<\/b>'); ?>";
+}
+
+/**
+ * Make sure that all checkboxes for the results in SelectedResults are checked.
+ */
+function UpdateAllCheckboxes()
+{
+ for(id in SelectedResults)
+ {
+ var elems = document.getElementsByName("test_" + id);
+
+ for(var i = 0; i < elems.length; i++)
+ elems[i].checked = true;
+ }
+}
+
+function Result_OnCheckboxClick(checkbox)
+{
+ UpdateSelectedResults(checkbox);
+}
+
+function Result_OnCellClick(elem)
+{
+ var checkbox = elem.parentNode.firstChild.firstChild;
+ checkbox.checked = !checkbox.checked;
+
+ UpdateSelectedResults(checkbox);
+}
+
+function SearchRevisionInput_OnKeyUp(elem)
+{
+ var val = elem.value.replace(/[^[0-9-]/g, "");
+
+ // First check if something was changed by the replace function.
+ // If not, don't set elem.value = val. Otherwise the cursor would always jump
to the last character in IE, when you press any key.
+ if(elem.value != val)
+ elem.value = val;
+}
+
+function GetRevNums()
+{
+ var rev = document.getElementById("search_revision").value;
+
+ // If the user didn't enter any revision number at all, he doesn't want to
search for a specific revision
+ if(!rev)
+ {
+ inputbox_startrev = "";
+ inputbox_endrev = "";
+ return true;
+ }
+
+ if(isNaN(rev) || rev < 1)
+ {
+ // Maybe the user entered a revision range
+ var hyphen = rev.indexOf("-");
+
+ if(hyphen > 0)
+ {
+ inputbox_startrev = rev.substr(0, hyphen);
+ inputbox_endrev = rev.substr(hyphen + 1);
+ }
+
+ if(hyphen <= 0 || isNaN(inputbox_startrev) || isNaN(inputbox_endrev))
+ {
+ alert("Invalid revision number!");
+ return false;
+ }
+ }
+ else
+ {
+ inputbox_startrev = rev;
+ inputbox_endrev = rev;
+ }
+
+ return true;
+}
+
+function SearchCall()
+{
+ document.getElementById("ajax_loading_search").style.visibility =
"visible";
+ AjaxGet("ajax-search.php", "SearchCallback", data);
+}
+
+function SearchButton_OnClick()
+{
+ if(!GetRevNums())
+ return;
+
+ data = new Array();
+
+ CurrentPage = 1;
+ FullRange = document.getElementById("search_revision").value;
+
+ data["startrev"] = inputbox_startrev;
+ data["endrev"] = inputbox_endrev;
+ data["platform"] =
document.getElementById("search_platform").value;
+
+ data["resultlist"] = 1;
+ data["requesttype"] = REQUESTTYPE_FULLLOAD;
+
+ SearchCall();
+}
+
+function SearchCallback(HttpRequest)
+{
+ // Check for an error
+ if(HttpRequest.responseXML.getElementsByTagName("error").length > 0)
+ {
+
alert(HttpRequest.responseXML.getElementsByTagName("error")[0].firstChild.data)
+ return;
+ }
+
+ var html = "";
+
+ if(data["resultlist"])
+ {
+ // Build a new infobox
+ html += '<table id="infotable" cellspacing="0"
cellpadding="0"><tr><td id="infobox">';
+
+ if(data["requesttype"] == REQUESTTYPE_FULLLOAD)
+ {
+ ResultCount =
parseInt(HttpRequest.responseXML.getElementsByTagName("resultcount")[0].firstChild.data);
+ html += '<?php
printf(addslashes($testman_langres["foundresults"]), "<span
id=\"resultcount\">' + ResultCount + '<\/span>");
?>';
+ }
+ else
+ {
+ html += document.getElementById("infobox").innerHTML;
+ }
+
+ html += '<\/td>';
+
+ // Page number boxes
+ html += '<td id="pagesbox">';
+
+ if(CurrentPage == 1)
+ {
+ html += '« ';
+ html += '‹ <?php echo
addslashes($shared_langres["prevpage"]); ?> ';
+ }
+ else
+ {
+ html += '<a href="javascript:FirstPage_OnClick()"
title="<?php echo addslashes($shared_langres["firstpage_title"]);
?>">«<\/a> ';
+ html += '<a href="javascript:PrevPage_OnClick()"
title="<?php echo addslashes($shared_langres["prevpage_title"]);
?>">‹ <?php echo
addslashes($shared_langres["prevpage"]); ?><\/a> ';
+ }
+
+ html += '<select id="pagesel" size="1"
onchange="PageBox_OnChange(this)">';
+
+ if(data["requesttype"] == REQUESTTYPE_FULLLOAD)
+ {
+ PageCount = 1;
+
+ html += '<option value="' + CurrentPage +
'-' +
HttpRequest.responseXML.getElementsByTagName("firstid")[0].firstChild.data +
'"><?php echo addslashes($shared_langres["page"]); ?> ' +
CurrentPage;
+
+
if(HttpRequest.responseXML.getElementsByTagName("resultcount")[0].firstChild.data
> 0)
+ html += ' - ' +
HttpRequest.responseXML.getElementsByTagName("firstrev")[0].firstChild.data +
' ... ' +
HttpRequest.responseXML.getElementsByTagName("lastrev")[0].firstChild.data +
'<\/option>';
+ }
+ else
+ {
+ html += document.getElementById("pagesel").innerHTML;
+ }
+
+ html += '<\/select> ';
+
+
if(HttpRequest.responseXML.getElementsByTagName("moreresults")[0].firstChild.data
== 0)
+ {
+ html += '<?php echo
addslashes($shared_langres["nextpage"]); ?> › ';
+ html += '»';
+ }
+ else
+ {
+ html += '<a href="javascript:NextPage_OnClick()"
title="<?php echo addslashes($shared_langres["nextpage_title"]);
?>"><?php echo addslashes($shared_langres["nextpage"]); ?>
›<\/a> ';
+ html += '<a href="javascript:LastPage_OnClick()"
title="<?php echo addslashes($shared_langres["lastpage_title"]);
?>">»<\/a>';
+ }
+
+ html += '<\/td><\/tr><\/table>';
+
+ // File table
+ html += '<table class="datatable"
cellspacing="0" cellpadding="0">';
+
+ html += '<thead><tr class="head">';
+ html += '<th class="TestCheckbox"><\/th>';
+ html += '<th><?php echo
addslashes($testman_langres["date"]); ?><\/th>';
+ html += '<th><?php echo
addslashes($testman_langres["revision"]); ?><\/th>';
+ html += '<th><?php echo
addslashes($testman_langres["user"]); ?><\/th>';
+ html += '<th><?php echo
addslashes($testman_langres["platform"]); ?><\/th>';
+ html += '<\/tr><\/thead>';
+ html += '<tbody>';
+
+ var results =
HttpRequest.responseXML.getElementsByTagName("result");
+
+ if(!results.length)
+ {
+ html += '<tr class="even"><td
colspan="5"><?php echo
addslashes($testman_langres["noresults"]); ?><\/td><\/tr>';
+ }
+ else
+ {
+ var oddeven = false;
+
+ for(var i = 0; i < results.length; i++)
+ {
+ var ResultID =
results[i].getElementsByTagName("id")[0].firstChild.data;
+ var ResultDate =
results[i].getElementsByTagName("date")[0].firstChild.data;
+ var ResultUser =
results[i].getElementsByTagName("user")[0].firstChild.data;
+ var ResultRevision =
results[i].getElementsByTagName("revision")[0].firstChild.data;
+ var ResultPlatform =
results[i].getElementsByTagName("platform")[0].firstChild.data;
+
+ html += '<tr class="' + (oddeven ?
"odd" : "even") + '"
onmouseover="Result_OnMouseOver(this)"
onmouseout="Result_OnMouseOut(this)">';
+ html += '<td><input
onclick="Result_OnCheckboxClick(this)" type="checkbox"
name="test_' + ResultID + '" \/><\/td>';
+ html += '<td
onclick="Result_OnCellClick(this)">' + ResultDate +
'<\/td>';
+ html += '<td
onclick="Result_OnCellClick(this)">' + ResultRevision +
'<\/td>';
+ html += '<td
onclick="Result_OnCellClick(this)">' + ResultUser +
'<\/td>';
+ html += '<td
onclick="Result_OnCellClick(this)">' + ResultPlatform +
'<\/td>';
+ html += '<\/tr>';
+
+ oddeven = !oddeven;
+ }
+ }
+
+ html += '<\/tbody><\/table>';
+
+ document.getElementById("searchtable").innerHTML = html;
+
+ if(data["requesttype"] == REQUESTTYPE_PAGESWITCH)
+ {
+ // Switch the selected page in the Page ComboBox
+
document.getElementById("pagesel").getElementsByTagName("option")[CurrentPage
- 1].selected = true;
+ }
+
+ UpdateAllCheckboxes();
+ }
+ else
+ {
+ // Just add a new page to the Page combo box and the information for it
+ PageCount++;
+ ResultCount +=
parseInt(HttpRequest.responseXML.getElementsByTagName("resultcount")[0].firstChild.data);
+
+ document.getElementById("resultcount").firstChild.data =
ResultCount;
+
+ // As always, we have to work around an IE bug
+ // If I use "innerHTML" here, the first <OPTION> start tag
gets dropped in the IE...
+ // Therefore I have to use the DOM functions in this case.
+ var OptionElem = document.createElement("option");
+ var OptionText = document.createTextNode('<?php echo
addslashes($shared_langres["page"]); ?> ' + PageCount + ' - ' +
HttpRequest.responseXML.getElementsByTagName("firstrev")[0].firstChild.data +
' ... ' +
HttpRequest.responseXML.getElementsByTagName("lastrev")[0].firstChild.data);
+
+ OptionElem.value = PageCount + "-" +
HttpRequest.responseXML.getElementsByTagName("firstid")[0].firstChild.data;
+ OptionElem.appendChild(OptionText);
+
+ document.getElementById("pagesel").appendChild(OptionElem);
+ }
+
+
if(HttpRequest.responseXML.getElementsByTagName("moreresults")[0].firstChild.data
== 1 && (data["requesttype"] == REQUESTTYPE_FULLLOAD ||
data["requesttype"] == REQUESTTYPE_ADDPAGE))
+ {
+ // There are more results available in the full range. Therefore we have
to start another request and add a new page.
+ data["resultlist"] = 0;
+ data["startid"] =
HttpRequest.responseXML.getElementsByTagName("nextid")[0].firstChild.data;
+ data["requesttype"] = REQUESTTYPE_ADDPAGE;
+ SearchCall();
+ return;
+ }
+
+ document.getElementById("ajax_loading_search").style.visibility =
"hidden";
+}
+
+function PageSwitch(NewPage, StartID)
+{
+ CurrentPage = NewPage;
+ data["resultlist"] = 1;
+ data["startid"] = StartID;
+ data["requesttype"] = REQUESTTYPE_PAGESWITCH;
+
+ SearchCall();
+}
+
+function FirstPage_OnClick()
+{
+ var info =
document.getElementById("pagesel").getElementsByTagName("option")[0].value.split("-");
+ PageSwitch(info[0], info[1]);
+}
+
+function PrevPage_OnClick()
+{
+ var info =
document.getElementById("pagesel").getElementsByTagName("option")[CurrentPage
- 2].value.split("-");
+ PageSwitch(info[0], info[1]);
+}
+
+function PageBox_OnChange(elem)
+{
+ var info = elem.value.split("-");
+ PageSwitch(info[0], info[1]);
+}
+
+function NextPage_OnClick()
+{
+ var info =
document.getElementById("pagesel").getElementsByTagName("option")[CurrentPage].value.split("-");
+ PageSwitch(info[0], info[1]);
+}
+
+function LastPage_OnClick()
+{
+ var info =
document.getElementById("pagesel").getElementsByTagName("option")[
document.getElementById("pagesel").getElementsByTagName("option").length
- 1 ].value.split("-");
+ PageSwitch(info[0], info[1]);
+}
+
+function CompareButton_OnClick()
+{
+ var first = true;
+ var parameters = "ids=";
+
+ for(id in SelectedResults)
+ {
+ if(first)
+ {
+ parameters += id;
+ first = false;
+ continue;
+ }
+
+ parameters += "," + id;
+ }
+
+ // If first is still true, no results were selected at all
+ if(first)
+ {
+ alert("<?php echo
addslashes($testman_langres["noselection"]); ?>");
+ return;
+ }
+
+ window.open("compare.php?" + parameters);
+}
Propchange:
trunk/web/reactos.org/htdocs/testman/js/index.js.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/htdocs/testman/lang/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/lang/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/lang/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/lang/de.inc.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/lan…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/lang/de.inc.php (added)
+++
trunk/web/reactos.org/htdocs/testman/lang/de.inc.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,61 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Translation
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+ TRANSLATOR: Colin Finck
+
+ charset=utf-8 without BOM
+*/
+
+ $testman_langres = array(
+ // Index page
+ "index_header" => '<a
href="http://www.reactos.org/">Startseite</a> > ReactOS Web Test
Manager',
+ "index_title" => "ReactOS Web Test Manager",
+ "index_intro" => "Mit dieser Oberfläche können Sie die
Ergebnisse automatisch ausgeführter Regression-Tests suchen, anzeigen und
vergleichen.",
+ "js_disclaimer" => "Sie müssen JavaScript aktivieren,
um die Oberfläche zu benutzen!",
+
+ "lastresults_header" => "Letzte 10 Testergebnisse",
+ "date" => "Datum",
+ "revision" => "Revision",
+ "user" => "Benutzer",
+ "platform" => "Plattform",
+
+ "search_header" => "Nach Testergebnissen suchen",
+ "search_revision" => "Revision",
+ "search_platform" => "Plattform",
+ "search_button" => "Suchen",
+ "searching" => "Testergebnisse werden gesucht...",
+
+ "foundresults" => "%s Ergebnisse gefunden!",
+ "noresults" => "Keine Suchergebnisse!",
+
+ "status" => "<b>%s</b> Tests zum Vergleich
ausgewählt",
+ "compare_button" => "Jetzt vergleichen",
+
+ "noselection" => "Sie haben keine Ergebnisse
ausgewählt!",
+ "maxselection" => "Sie dürfen nur bis zu %d Ergebnisse
zum Vergleich auswählen!",
+
+ // Compare page
+ "compare_title" => "Ergebnisse vergleichen",
+ "showchanged" => "Nur geänderte Ergebnisse
anzeigen",
+
+ "legend" => "Legende",
+ "totaltests" => "Alle Tests",
+ "failedtests" => "Fehlgeschlagene Tests",
+ "todotests" => "Als TODO markierte Tests",
+ "skippedtests" => "Ãbersprungene Tests",
+ "difference" => "Unterschied zum vorherigen
Ergebnis",
+
+ "testsuite" => "Test Suite",
+ "resulthead" => "Revision %d<br />unter %s<br
/>von %s<br />am %s",
+
+ // Result Details page
+ "detail_title" => "Ergebnis-Details",
+
+ "thisresult" => "Informationen über dieses
Ergebnis",
+ "log" => "Log",
+ "associatedtest" => "Information über den zugeordneten
Test",
+ );
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/lang/de.inc.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/lang/en.inc.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/lan…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/lang/en.inc.php (added)
+++
trunk/web/reactos.org/htdocs/testman/lang/en.inc.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,62 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Translation
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+ TRANSLATOR: Colin Finck
+
+ charset=utf-8 without BOM
+*/
+
+ $testman_langres = array(
+ // Index page
+ "index_header" => '<a
href="http://www.reactos.org/">Home</a> > ReactOS Web Test
Manager',
+ "index_title" => "ReactOS Web Test Manager",
+ "index_intro" => "This interface enables you to find,
view and compare Results of automatically performed Regression Tests.",
+ "js_disclaimer" => "You have to activate JavaScript to
use the interface!",
+
+ "lastresults_header" => "Last 10 Test Results",
+ "date" => "Date",
+ "revision" => "Revision",
+ "user" => "User",
+ "platform" => "Platform",
+
+ "search_header" => "Search for Test Results",
+ "search_revision" => "Revision",
+ "rangeinfo" => "You can enter a revision number (e.g.
%s) or a revision range (e.g. %s-%s)",
+ "search_platform" => "Platform",
+ "search_button" => "Search",
+ "searching" => "Searching for Test Results",
+
+ "foundresults" => "Found %s Results!",
+ "noresults" => "No Search Results!",
+
+ "status" => "<b>%s</b> Tests selected for
comparison",
+ "compare_button" => "Compare Now",
+
+ "noselection" => "You did not select any results!",
+ "maxselection" => "You may only select up to %d results
for comparison!",
+
+ // Compare page
+ "compare_title" => "Comparing Results",
+ "showchanged" => "Show only changed results",
+
+ "legend" => "Legend",
+ "totaltests" => "Total Tests",
+ "failedtests" => "Failed Tests",
+ "todotests" => "Tests marked as TODO",
+ "skippedtests" => "Skipped tests",
+ "difference" => "Difference to the previous
result",
+
+ "testsuite" => "Test Suite",
+ "resulthead" => "Revision %d<br />under %s<br
/>by %s<br />at %s",
+
+ // Result Details page
+ "detail_title" => "Result Details",
+
+ "thisresult" => "Information about this Result",
+ "log" => "Log",
+ "associatedtest" => "Information about the associated
Test",
+ );
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/lang/en.inc.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/languages.inc.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/lan…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/languages.inc.php (added)
+++
trunk/web/reactos.org/htdocs/testman/languages.inc.php [iso-8859-1] Mon Jan 5
06:35:05 2009
@@ -1,0 +1,14 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Language list
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ // The language names have to be saved in an UTF-8 file without the
Byte-Order-Mark
+ $supported_languages = array(
+ "en" => "English",
+ "de" => "Deutsch (German)",
+ );
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/languages.inc.php
------------------------------------------------------------------------------
svn:eol-style = native
Added:
trunk/web/reactos.org/htdocs/testman/utils.inc.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/uti…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/utils.inc.php (added)
+++
trunk/web/reactos.org/htdocs/testman/utils.inc.php [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,128 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Utility functions shared among several PHP files
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ function GetPlatformString($platform)
+ {
+ // First get the main operating system
+ if(substr($platform, 0, 7) == "reactos")
+ {
+ $str = "ReactOS";
+ $arch = (int)substr($platform, 8);
+ }
+ else
+ {
+ sscanf($platform, "%u.%u.%u.%u.%u.%c.%u", $major,
$minor, $build, $sp_major, $sp_minor, $type, $arch);
+
+ switch($major)
+ {
+ case 5:
+ switch($minor)
+ {
+ case 0:
+ $str = "Windows 2000";
+ $final_builds = array(2195);
+
+ if($type == "s")
+ $str .= "
Server";
+
+ break;
+
+ case 1:
+ $str = "Windows XP";
+ $final_builds = array(2600);
+ break;
+
+ case 2:
+ $final_builds = array(3790);
+
+ if($type == "s")
+ $str = "Windows
Server 2003";
+ else
+ $str = "Windows
XP";
+
+ break;
+
+ default:
+ return $platform;
+ }
+
+ break;
+
+ case 6:
+ switch($minor)
+ {
+ case 0:
+ $final_builds = array(6000, 6001);
+
+ if($type = "s")
+ $str = "Windows
Server 2008";
+ else
+ $str = "Windows
Vista";
+
+ break;
+
+ case 1:
+ $final_builds = array();
+
+ $str = "Windows 7";
+ break;
+
+ default:
+ return $platform;
+ }
+
+ break;
+
+ default:
+ return $platform;
+ }
+
+ // Check if our current build is a final build. If it's not,
also show the build number.
+ $found = false;
+
+ foreach($final_builds as $b)
+ {
+ if($b == $build)
+ {
+ $found = true;
+ break;
+ }
+ }
+
+ if(!$found)
+ $str .= " - Build " . $build;
+
+ // Add the service pack information if we have any
+ if($sp_major)
+ {
+ $str .= " SP" . $sp_major;
+
+ if($sp_minor)
+ $str .= "." . $sp_minor;
+ }
+ }
+
+ // Now get the processor architecture
+ // The values for $arch are Windows PROCESSOR_ARCHITECTURE_* constants
+ $str .= " - ";
+
+ switch($arch)
+ {
+ case 0: $str .= "i386"; break;
+ case 9: $str .= "AMD64"; break;
+ default: return $platform;
+ }
+
+ return $str;
+ }
+
+ function GetDateString($timestamp)
+ {
+ return date("Y-m-d H:i", $timestamp);
+ }
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/utils.inc.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/webservice/index.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/web…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/webservice/index.php (added)
+++
trunk/web/reactos.org/htdocs/testman/webservice/index.php [iso-8859-1] Mon Jan 5
06:35:05 2009
@@ -1,0 +1,79 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Web Service for receiving test results from "rosautotest"
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ require_once("../config.inc.php");
+
+ // All classes are autoloaded through this magic function
+ function __autoload($class)
+ {
+ require_once("lib/$class.class.php");
+ }
+
+ // What one of these classes has to look like
+ interface Test
+ {
+ public function GetTestID();
+ public function Submit();
+ public function Finish();
+ }
+
+
+ // Entry point
+ if(!isset($_POST["username"]) ||
!isset($_POST["passwordhash"]) || !isset($_POST["testtype"]))
+ die("Necessary information not specified!");
+
+ // Check the login credentials
+ try
+ {
+ $dbh = new PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
+ }
+ catch(PDOException $e)
+ {
+ // Give no exact error message here, so no server internals are exposed
+ die("Could not establish the DB connection");
+ }
+
+ $stmt = $dbh->prepare("SELECT user_id FROM " . DB_ROSCMS .
".users WHERE user_name = :username AND user_roscms_password = :passwordhash AND
user_account_enabled = 'yes'");
+ $stmt->bindParam(":username", $_POST["username"]);
+ $stmt->bindParam(":passwordhash", $_POST["passwordhash"]);
+ $stmt->execute() or die("SQL failed #1");
+ $user_id = (int)$stmt->fetchColumn();
+
+ if(!$user_id)
+ die("Invalid Login credentials!");
+
+ // Check if the user is permitted to submit test results
+ $stmt = $dbh->prepare("SELECT COUNT(*) FROM " . DB_TESTMAN .
".permitted_users WHERE user_id = :userid");
+ $stmt->bindParam(":userid", $user_id);
+ $stmt->execute() or die("SQL failed #2");
+
+ if(!$stmt->fetchColumn())
+ die("User is not permitted to submit test results");
+
+ switch($_POST["testtype"])
+ {
+ case "wine":
+ $t = new WineTest();
+ break;
+
+ default:
+ die("Invalid test type!");
+ }
+
+ // What shall we do?
+ switch($_POST["action"])
+ {
+ case "gettestid": die($t->GetTestID());
+ case "getsuiteid": die($t->GetSuiteID());
+ case "submit": die($t->Submit());
+ case "finish": die($t->Finish());
+
+ default:
+ die("Invalid action");
+ }
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/index.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/lib/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/lib/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/lib/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/htdocs/testman/webservice/lib/WineTest.class.php
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/htdocs/testman/web…
==============================================================================
---
trunk/web/reactos.org/htdocs/testman/webservice/lib/WineTest.class.php (added)
+++
trunk/web/reactos.org/htdocs/testman/webservice/lib/WineTest.class.php [iso-8859-1]
Mon Jan 5 06:35:05 2009
@@ -1,0 +1,112 @@
+<?php
+/*
+ PROJECT: ReactOS Web Test Manager
+ LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
+ PURPOSE: Class for submitting Wine Test results
+ COPYRIGHT: Copyright 2008-2009 Colin Finck <colin(a)reactos.org>
+*/
+
+ class WineTest implements Test
+ {
+ public function GetTestID()
+ {
+ global $dbh;
+ global $user_id;
+
+ if(!isset($_POST["revision"]) ||
!isset($_POST["platform"]))
+ return "Necessary sub-information not
specified!";
+
+ // Add a new Test ID with the given information
+ $stmt = $dbh->prepare("INSERT INTO " . DB_TESTMAN .
".winetest_runs (user_id, revision, platform) VALUES (:userid, :revision,
:platform)");
+ $stmt->bindParam(":userid", $user_id);
+ $stmt->bindParam(":revision",
$_POST["revision"]);
+ $stmt->bindParam(":platform",
$_POST["platform"]);
+ $stmt->execute() or die("GetTestID(): SQL failed
#1");
+
+ return $dbh->lastInsertId();
+ }
+
+ public function GetSuiteID()
+ {
+ global $dbh;
+
+ if(!isset($_POST["module"]) ||
!isset($_POST["test"]))
+ return "Necessary sub-information not
specified!";
+
+ // Determine whether we already have a suite ID for this
combination
+ $stmt = $dbh->prepare("SELECT id FROM " . DB_TESTMAN
. ".winetest_suites WHERE module = :module AND test = :test");
+ $stmt->bindParam(":module",
$_POST["module"]);
+ $stmt->bindParam(":test", $_POST["test"]);
+ $stmt->execute() or die("GetSuiteID(): SQL failed
#1");
+ $id = $stmt->fetchColumn();
+
+ if($id)
+ return $id;
+
+ // Add this combination to the table and return the ID for it
+ $stmt = $dbh->prepare("INSERT INTO " . DB_TESTMAN .
".winetest_suites (module, test) VALUES (:module, :test)");
+ $stmt->bindParam(":module",
$_POST["module"]);
+ $stmt->bindParam(":test", $_POST["test"]);
+ $stmt->execute() or die("GetSuiteID(): SQL failed
#2");
+
+ return $dbh->lastInsertId();
+ }
+
+ public function Submit()
+ {
+ global $dbh;
+ global $user_id;
+
+ if(!isset($_POST["testid"]) ||
!isset($_POST["suiteid"]) || !isset($_POST["log"]))
+ return "Necessary sub-information not
specified!";
+
+ // Make sure we may add information to the test with this Test ID
+ $stmt = $dbh->prepare("SELECT COUNT(*) FROM " .
DB_TESTMAN . ".winetest_runs WHERE id = :testid AND finished = 0 AND user_id =
:userid");
+ $stmt->bindParam(":testid",
$_POST["testid"]);
+ $stmt->bindParam(":userid", $user_id);
+ $stmt->execute() or die("Submit(): SQL failed #1");
+
+ if(!$stmt->fetchColumn())
+ return "No such test or no permissions!";
+
+ // Validate and parse the log
+ $line = strrchr($_POST["log"], ":");
+
+ if(sscanf($line, ": %u tests executed (%u marked as todo, %u
failures), %u skipped.", $count, $todo, $failures, $skipped) != 4)
+ return "Log is invalid!";
+
+ // Add the information into the DB
+ $stmt = $dbh->prepare("INSERT INTO " . DB_TESTMAN .
".winetest_results (test_id, suite_id, log, count, todo, failures, skipped) VALUES
(:testid, :suiteid, :log, :count, :todo, :failures, :skipped)");
+ $stmt->bindValue(":testid",
(int)$_POST["testid"]);
+ $stmt->bindValue(":suiteid",
(int)$_POST["suiteid"]);
+ $stmt->bindParam(":log", $_POST["log"]);
+ $stmt->bindParam(":count", $count);
+ $stmt->bindParam(":todo", $todo);
+ $stmt->bindParam(":failures", $failures);
+ $stmt->bindParam(":skipped", $skipped);
+ $stmt->execute() or die("Submit(): SQL failed #2");
+
+ return "OK";
+ }
+
+ public function Finish()
+ {
+ global $dbh;
+ global $user_id;
+
+ if(!isset($_POST["testid"]))
+ return "Necessary sub-information not
specified!";
+
+ // Mark this test as finished, so no more results can be submitted
for it
+ $stmt = $dbh->prepare("UPDATE " . DB_TESTMAN .
".winetest_runs SET finished = 1 WHERE id = :testid AND user_id = :userid");
+ $stmt->bindParam(":userid", $user_id);
+ $stmt->bindParam(":testid",
$_POST["testid"]);
+ $stmt->execute() or die("Finish(): SQL failed #1");
+
+ if(!$stmt->rowCount())
+ return "Did not update anything!";
+
+ return "OK";
+ }
+ }
+?>
Propchange:
trunk/web/reactos.org/htdocs/testman/webservice/lib/WineTest.class.php
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
trunk/web/reactos.org/resources/testman/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Jan 5 06:35:05 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange:
trunk/web/reactos.org/resources/testman/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange:
trunk/web/reactos.org/resources/testman/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Added:
trunk/web/reactos.org/resources/testman/testman.sql
URL:
http://svn.reactos.org/svn/reactos/trunk/web/reactos.org/resources/testman/…
==============================================================================
---
trunk/web/reactos.org/resources/testman/testman.sql (added)
+++
trunk/web/reactos.org/resources/testman/testman.sql [iso-8859-1] Mon Jan 5 06:35:05
2009
@@ -1,0 +1,35 @@
+-- SQL Dump for the "testman" database
+
+CREATE TABLE `permitted_users` (
+ `user_id` bigint(20) unsigned NOT NULL,
+ PRIMARY KEY (`user_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+
+CREATE TABLE `winetest_results` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `test_id` int(10) unsigned NOT NULL,
+ `suite_id` int(10) unsigned NOT NULL,
+ `log` longtext collate latin1_general_ci NOT NULL,
+ `count` int(10) unsigned NOT NULL COMMENT 'Number of all executed tests',
+ `todo` int(10) unsigned NOT NULL COMMENT 'Tests marked as TODO',
+ `failures` int(10) unsigned NOT NULL COMMENT 'Number of failed tests',
+ `skipped` int(10) unsigned NOT NULL COMMENT 'Number of skipped tests',
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+
+CREATE TABLE `winetest_runs` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
+ `finished` tinyint(1) NOT NULL default '0',
+ `user_id` bigint(20) unsigned NOT NULL,
+ `revision` int(9) unsigned NOT NULL,
+ `platform` varchar(24) collate latin1_general_ci NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+
+CREATE TABLE `winetest_suites` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `module` varchar(50) collate latin1_general_ci NOT NULL,
+ `test` varchar(50) collate latin1_general_ci NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Propchange:
trunk/web/reactos.org/resources/testman/testman.sql
------------------------------------------------------------------------------
svn:eol-style = native