Selenium.class.php

From Organic Design wiki
Revision as of 00:18, 4 August 2008 by Nad (talk | contribs) (schedule loop needs to be structured with domain as outer loop)

<?php /**

* Selenium extension
* Template:Php
* 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 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 $egSeleniumCategory;

# 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 if ($this->testCount[$suite] > 1) $text .= "";

# Parse the content normally and return wrapped in a div of class selenium and id of test name $text = $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false)->getText();

return "

$text

";

}

/** * 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(

"|

\\s*(.+?)\\s*

|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 = " Selenium

\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 .= "\n"; } $tests[$suite] = "$html
$suite
$test

";

return $tests; }

/** * Check whether any tests should run */ public function checkSchedule() { global $egSeleniumSchdeule; if ($_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__; } }