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