Difference between revisions of "Selenium.class.php"
From Organic Design wiki
(do need to wrap in selenium tags afterall) |
m |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | <?php | + | {{legacy}} |
+ | <source lang="php"><?php | ||
/** | /** | ||
* Selenium extension | * Selenium extension | ||
− | * | + | * |
* See http://www.mediawiki.org/Extension:Selenium for installation and usage details | * See http://www.mediawiki.org/Extension:Selenium for installation and usage details | ||
* See http://www.organicdesign.co.nz/Extension_talk:Selenium.php for development notes and disucssion | * See http://www.organicdesign.co.nz/Extension_talk:Selenium.php for development notes and disucssion | ||
Line 15: | Line 16: | ||
class Selenium { | class Selenium { | ||
− | + | ||
+ | var $testCount = array(); # keep track of number of tests in each suite processed | ||
+ | |||
function __construct() { | function __construct() { | ||
global $wgParser, $egSeleniumTag; | global $wgParser, $egSeleniumTag; | ||
# Add the tag hook | # Add the tag hook | ||
− | $wgParser->setHook( | + | $wgParser->setHook($egSeleniumTag, array($this, 'tagSelenium')); |
− | + | ||
# Check the schedule and see if any test-runs should be spawned | # Check the schedule and see if any test-runs should be spawned | ||
$this->checkSchedule(); | $this->checkSchedule(); | ||
Line 31: | Line 34: | ||
*/ | */ | ||
public function tagSelenium($text, &$argv, &$parser) { | public function tagSelenium($text, &$argv, &$parser) { | ||
− | global $ | + | global $wgOut, $egSeleniumSuiteCat, $egSeleniumTestCat; |
+ | |||
+ | # The suite being processed is the article title text, keep track of number of tests in it | ||
+ | $suite = $parser->mTitle->getPrefixedText(); | ||
+ | $this->testCount[$suite] = array_key_exists($suite, $this->testCount) ? $this->testCount[$suite]+1 : 1; | ||
+ | |||
+ | # Get name of test from title tag | ||
+ | $name = preg_match("|<title>(.+?)</title>|i", $text, $match) ? $match[1] : 'untitled'; | ||
# Get rid of unwanted tags | # Get rid of unwanted tags | ||
− | $text = preg_replace("#\\s*<head>.+ | + | $text = preg_replace("#\\s*<head>.+</head>\\s*#is", "", $text); |
$text = preg_replace("#\\s*</?t?(html|head|body)>\\s*#i", "", $text); | $text = preg_replace("#\\s*</?t?(html|head|body)>\\s*#i", "", $text); | ||
− | # Categorise the article into Selenium tests category | + | # Categorise the article into Selenium tests category if more than one test in this suite |
− | $text .= "[[Category:$ | + | # - todo: and also remove from the cat for individual tests |
+ | if ($this->testCount[$suite] > 1) $text .= "[[Category:$egSeleniumSuiteCat]]"; | ||
− | # Parse the content normally and return wrapped in a div of class selenium | + | # Parse the content normally and return wrapped in a div of class selenium and id of test name |
− | $ | + | $out = $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false); |
− | return "<div class=\"selenium\">$text</div>"; | + | $text = $out->getText(); |
+ | return "<div class=\"selenium\" id=\"$name\">$text</div><!-- selenium-end -->"; | ||
} | } | ||
/** | /** | ||
− | * | + | * Extract the individual tests from the suite indexed by name in selenese HTML format |
+ | * - also add the selenese HTML for the whole suite under index of suite name | ||
*/ | */ | ||
− | public function | + | public static function selenese($suite, $path = false) { |
+ | global $wgParser; | ||
+ | |||
+ | # Get the content of the suite article and parse it | ||
+ | # NOTE: parsing the content results in the head, body, thead, tbody etc being removed, | ||
+ | # but it seems that the TestRunner doesn't care and can work with the basic table structure | ||
+ | $suiteTitle = Title::newFromText($suite); | ||
+ | $suiteArticle = new Article($suiteTitle); | ||
+ | $text = $wgParser->parse($suiteArticle->getContent(), $suiteTitle, new ParserOptions(), true, true)->getText(); | ||
+ | |||
+ | # extract the name and content of the individual tests in the suite | ||
+ | $numTests = preg_match_all( | ||
+ | "|<div class=\"selenium\" id=\"(.+?)\">\\s*(.+?)\\s*</div><!-- selenium-end -->|is", | ||
+ | $text, | ||
+ | $matches, | ||
+ | PREG_PATTERN_ORDER | ||
+ | ); | ||
+ | |||
+ | # Re-organise the matched test content into a hash indexed by test name | ||
+ | $tests = array(); | ||
+ | for ($i = 0; $i < $numTests; $i++) $tests[$matches[1][$i]] = $matches[2][$i]; | ||
+ | |||
+ | # Create the HTML for the entire suite under index of suite name | ||
+ | $html = "<html><head><meta content=\"text/html; charset=ISO-8859-1\" http-equiv=\"content-type\"> | ||
+ | <title>Selenium</title></head><body><table cellpadding=\"1\" cellspacing=\"1\" border=\"1\"> | ||
+ | <tbody><tr><td><b>$suite</b></td></tr>\n"; | ||
+ | $title = Title::makeTitle(NS_SPECIAL, 'Selenium'); | ||
+ | foreach (array_keys($tests) as $test) { | ||
+ | $url = $path ? "$path/wiki-".urlencode($test).".html" : $title->getLocalURL("suite=$suite&test=$test"); | ||
+ | $html .= "<tr><td><a href=\"$url\">$test</a></td></tr>\n"; | ||
+ | } | ||
+ | $tests[$suite] = "$html</tbody></table></body></html>"; | ||
+ | |||
+ | return $tests; | ||
} | } | ||
/** | /** | ||
− | * | + | * Check whether any tests should run |
*/ | */ | ||
− | public function | + | public function checkSchedule() { |
+ | global $egSeleniumSchdeule; | ||
+ | if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'runtests') $this->runTests(); | ||
+ | $ts = date('H:i'); | ||
+ | if (in_array($ts, $egSeleniumSchdeule)) { | ||
+ | $ts = date('d M Y').", $ts"; | ||
+ | |||
+ | # Get the last log entry | ||
+ | |||
+ | # If tests for this time and day haven't run yet, run them now | ||
+ | if ("Last log entry time stamp not equal to current") $this->runTests(); | ||
+ | } | ||
} | } | ||
/** | /** | ||
− | * | + | * Run all the tests in the schedule in Selenium Remote Control (SRC) |
*/ | */ | ||
− | public function | + | public function runTests() { |
+ | global $IP, $egSeleniumSchedule, $egSeleniumPath, $egSeleniumDir; | ||
+ | |||
+ | # Update the log with tests start message | ||
+ | |||
+ | # Define paths for the java server, the HTML test files and the results file | ||
+ | $jar = "$egSeleniumDir/selenium-server/selenium-server.jar"; | ||
+ | $tests = "$egSeleniumDir/selenium-core/tests"; | ||
+ | $out = "$egSeleniumDir/selenium-core/tests/results.txt"; | ||
+ | |||
+ | # We need to flip the operation to work by domain on the outer loop | ||
+ | # - because it needs to build a set of selenese suite/test files for each site | ||
+ | # since the parser-functions used in the tests must be resolved my the wiki being tested | ||
+ | |||
+ | foreach ($egSeleniumSchedule as $suite => $domains) if (!is_numeric($suite)) { | ||
+ | $es = urlencode($suite); | ||
+ | |||
+ | # Copy the suite and its tests as selenese HTML into the place SRC expects to find them | ||
+ | foreach (Selenium::selenese($suite, "/selenium-server/tests") as $k => $v) { | ||
+ | $ek = urlencode($k); | ||
+ | file_put_contents("$tests/wiki-$ek.html", $v); | ||
+ | } | ||
+ | |||
+ | # Run the suite for each domain | ||
+ | foreach ($domains as $domain) { | ||
+ | shell_exec("java -jar $jar -htmlSuite \"*custom /usr/bin/firefox\" \"$domain\" \"$tests/wiki-$es.html\" \"$out\""); | ||
+ | $results = file_get_contents($out); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # Update the log with test results | ||
} | } | ||
Line 70: | Line 157: | ||
} | } | ||
} | } | ||
+ | </source> |
Latest revision as of 14:56, 27 February 2020
<?php
/**
* Selenium extension
*
* See http://www.mediawiki.org/Extension:Selenium for installation and usage details
* See http://www.organicdesign.co.nz/Extension_talk:Selenium.php for development notes and disucssion
*
* @package MediaWiki
* @subpackage Extensions
* @author Marcus Davy [http://www.organicdesign.co.nz/User:Sven User:Sven]
* @copyright © 2007 Marcus Davy
* @licence GNU General Public Licence 2.0 or later
*/
if (!defined('MEDIAWIKI')) die('Not an entry point.');
class Selenium {
var $testCount = array(); # keep track of number of tests in each suite processed
function __construct() {
global $wgParser, $egSeleniumTag;
# Add the tag hook
$wgParser->setHook($egSeleniumTag, array($this, 'tagSelenium'));
# Check the schedule and see if any test-runs should be spawned
$this->checkSchedule();
}
/**
* Process a selenium tag with test syntax in it
* - this tag also handles the categorisation of the article into Category:Selenium
*/
public function tagSelenium($text, &$argv, &$parser) {
global $wgOut, $egSeleniumSuiteCat, $egSeleniumTestCat;
# The suite being processed is the article title text, keep track of number of tests in it
$suite = $parser->mTitle->getPrefixedText();
$this->testCount[$suite] = array_key_exists($suite, $this->testCount) ? $this->testCount[$suite]+1 : 1;
# Get name of test from title tag
$name = preg_match("|<title>(.+?)</title>|i", $text, $match) ? $match[1] : 'untitled';
# Get rid of unwanted tags
$text = preg_replace("#\\s*<head>.+</head>\\s*#is", "", $text);
$text = preg_replace("#\\s*</?t?(html|head|body)>\\s*#i", "", $text);
# Categorise the article into Selenium tests category if more than one test in this suite
# - todo: and also remove from the cat for individual tests
if ($this->testCount[$suite] > 1) $text .= "[[Category:$egSeleniumSuiteCat]]";
# Parse the content normally and return wrapped in a div of class selenium and id of test name
$out = $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false);
$text = $out->getText();
return "<div class=\"selenium\" id=\"$name\">$text</div><!-- selenium-end -->";
}
/**
* Extract the individual tests from the suite indexed by name in selenese HTML format
* - also add the selenese HTML for the whole suite under index of suite name
*/
public static function selenese($suite, $path = false) {
global $wgParser;
# Get the content of the suite article and parse it
# NOTE: parsing the content results in the head, body, thead, tbody etc being removed,
# but it seems that the TestRunner doesn't care and can work with the basic table structure
$suiteTitle = Title::newFromText($suite);
$suiteArticle = new Article($suiteTitle);
$text = $wgParser->parse($suiteArticle->getContent(), $suiteTitle, new ParserOptions(), true, true)->getText();
# extract the name and content of the individual tests in the suite
$numTests = preg_match_all(
"|<div class=\"selenium\" id=\"(.+?)\">\\s*(.+?)\\s*</div><!-- selenium-end -->|is",
$text,
$matches,
PREG_PATTERN_ORDER
);
# Re-organise the matched test content into a hash indexed by test name
$tests = array();
for ($i = 0; $i < $numTests; $i++) $tests[$matches[1][$i]] = $matches[2][$i];
# Create the HTML for the entire suite under index of suite name
$html = "<html><head><meta content=\"text/html; charset=ISO-8859-1\" http-equiv=\"content-type\">
<title>Selenium</title></head><body><table cellpadding=\"1\" cellspacing=\"1\" border=\"1\">
<tbody><tr><td><b>$suite</b></td></tr>\n";
$title = Title::makeTitle(NS_SPECIAL, 'Selenium');
foreach (array_keys($tests) as $test) {
$url = $path ? "$path/wiki-".urlencode($test).".html" : $title->getLocalURL("suite=$suite&test=$test");
$html .= "<tr><td><a href=\"$url\">$test</a></td></tr>\n";
}
$tests[$suite] = "$html</tbody></table></body></html>";
return $tests;
}
/**
* Check whether any tests should run
*/
public function checkSchedule() {
global $egSeleniumSchdeule;
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'runtests') $this->runTests();
$ts = date('H:i');
if (in_array($ts, $egSeleniumSchdeule)) {
$ts = date('d M Y').", $ts";
# Get the last log entry
# If tests for this time and day haven't run yet, run them now
if ("Last log entry time stamp not equal to current") $this->runTests();
}
}
/**
* Run all the tests in the schedule in Selenium Remote Control (SRC)
*/
public function runTests() {
global $IP, $egSeleniumSchedule, $egSeleniumPath, $egSeleniumDir;
# Update the log with tests start message
# Define paths for the java server, the HTML test files and the results file
$jar = "$egSeleniumDir/selenium-server/selenium-server.jar";
$tests = "$egSeleniumDir/selenium-core/tests";
$out = "$egSeleniumDir/selenium-core/tests/results.txt";
# We need to flip the operation to work by domain on the outer loop
# - because it needs to build a set of selenese suite/test files for each site
# since the parser-functions used in the tests must be resolved my the wiki being tested
foreach ($egSeleniumSchedule as $suite => $domains) if (!is_numeric($suite)) {
$es = urlencode($suite);
# Copy the suite and its tests as selenese HTML into the place SRC expects to find them
foreach (Selenium::selenese($suite, "/selenium-server/tests") as $k => $v) {
$ek = urlencode($k);
file_put_contents("$tests/wiki-$ek.html", $v);
}
# Run the suite for each domain
foreach ($domains as $domain) {
shell_exec("java -jar $jar -htmlSuite \"*custom /usr/bin/firefox\" \"$domain\" \"$tests/wiki-$es.html\" \"$out\"");
$results = file_get_contents($out);
}
}
# Update the log with test results
}
/**
* Needed in some versions to prevent Special:Version from breaking
*/
private function __toString() {
return __CLASS__;
}
}