Difference between revisions of "Extension:Selenium.php"
(begin changing over to new tag structure) |
|||
Line 10: | Line 10: | ||
define('SELENIUM_VERSION', '0.8.0, 2008-08-01'); | define('SELENIUM_VERSION', '0.8.0, 2008-08-01'); | ||
− | |||
$egSeleniumPath = preg_replace('|^.+(?=[/\\\\]extensions)|', $wgScriptPath, dirname(__FILE__)) . 'selenium-core'; | $egSeleniumPath = preg_replace('|^.+(?=[/\\\\]extensions)|', $wgScriptPath, dirname(__FILE__)) . 'selenium-core'; | ||
$egResultsUrlPath = "../../tmp/results.php"; | $egResultsUrlPath = "../../tmp/results.php"; | ||
$egSeleniumCategory = "Selenium"; | $egSeleniumCategory = "Selenium"; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
$wgExtensionFunctions[] = 'efSetupSelenium'; | $wgExtensionFunctions[] = 'efSetupSelenium'; | ||
Line 32: | Line 25: | ||
); | ); | ||
− | + | /** | |
− | + | * Define the class for rendering selenium test tables | |
− | + | */ | |
class Selenium { | class Selenium { | ||
− | |||
− | |||
# Constructor | # Constructor | ||
function __construct() { | function __construct() { | ||
− | global | + | global $wgParser; |
− | # Add the | + | # Add the tag hooks |
− | $wgParser->setHook($ | + | $wgParser->setHook('body', array($this, 'tagBody')); |
− | } | + | $wgParser->setHook('head', array($this, 'tagHead')); |
+ | $wgParser->setHook('html', array($this, 'tagParseContent')); | ||
+ | $wgParser->setHook('thead', array($this, 'tagParseContent')); | ||
+ | $wgParser->setHook('tbody', array($this, 'tagParseContent')); | ||
+ | |||
+ | # todo: check the schedule and see if any test-runs should be spawned | ||
+ | |||
+ | } | ||
/** | /** | ||
− | * | + | * Body tags surround the main test table and should be converted to a div of class "selenium" |
+ | * - this tag also handles the categorisation of the article into Category:Selenium | ||
*/ | */ | ||
− | public function | + | public function tagBody($text, &$argv, &$parser) { |
− | global $ | + | global $egSeleniumCategory; |
+ | $text .= "[[Category:$egSeleniumCategory]]"; | ||
+ | $text = $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false)->getText(); | ||
+ | return "<div class=\"selenium\">$text</div>"; | ||
+ | } | ||
− | + | /** | |
− | + | * The head tag of a selenium test doesn't need to be rendered, so simply returns an empty string | |
− | + | */ | |
− | + | public function tagHead(&$text, &$argv, &$parser) { | |
− | + | return ''; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | /** | |
− | + | * The html, thead and tbody tags need to parse and return their content | |
− | + | */ | |
− | + | public function tagParseContent(&$text, &$argv, &$parser) { | |
− | + | return $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false)->getText(); | |
} | } | ||
Line 94: | Line 82: | ||
* Define a new class based on the SpecialPage class | * Define a new class based on the SpecialPage class | ||
*/ | */ | ||
+ | require_once "$IP/includes/SpecialPage.php"; | ||
class SpecialSelenium extends SpecialPage { | class SpecialSelenium extends SpecialPage { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
function __construct() { | function __construct() { | ||
− | SpecialPage::SpecialPage( | + | SpecialPage::SpecialPage('Selenium', '', true, false, false, false); |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
public function execute() { | public function execute() { | ||
global $wgOut, $wgParser, $wgRequest, $egResultsUrlPath; | global $wgOut, $wgParser, $wgRequest, $egResultsUrlPath; | ||
Line 134: | Line 98: | ||
$suiteTitle = Title::newFromText($wgRequest->getText('suite')); | $suiteTitle = Title::newFromText($wgRequest->getText('suite')); | ||
− | # | + | # get the content of the suite article and expand braces |
− | + | $suiteArticle = new Article($suiteTitle); | |
− | + | $wikitext = $wgParser->preprocess($suiteArticle->getContent(), $suiteTitle, new ParserOptions()); | |
− | |||
− | $ | ||
− | |||
− | $wikitext = $wgParser->preprocess($ | ||
# Preparse encapsulations around Selenium tags e.g. <nowiki><selenium></nowiki> | # Preparse encapsulations around Selenium tags e.g. <nowiki><selenium></nowiki> | ||
Line 152: | Line 112: | ||
# Determine whether suite or test from ?suite=article_name&test=section_num in query string | # Determine whether suite or test from ?suite=article_name&test=section_num in query string | ||
− | |||
if ($wgRequest->getText('test')) { | if ($wgRequest->getText('test')) { | ||
$testTitle = Title::newFromText($wgRequest->getText('test')); | $testTitle = Title::newFromText($wgRequest->getText('test')); | ||
Line 171: | Line 130: | ||
} | } | ||
} | } | ||
− | else $this -> build404("Specified test does not exist in " . $wgRequest->getText('suite')); | + | else $this->build404("Specified test does not exist in ".$wgRequest->getText('suite')); |
} | } | ||
else { | else { | ||
Line 185: | Line 144: | ||
global $egSeleniumCategory, $egSeleniumPath; | global $egSeleniumCategory, $egSeleniumPath; | ||
− | # Retrieve articles in category labelled $egSeleniumCategory | + | # Retrieve articles in category labelled $egSeleniumCategory |
− | $list = $ | + | $list = array(); |
+ | $dbr = &wfGetDB(DB_SLAVE); | ||
+ | $cl = $dbr->tableName('categorylinks'); | ||
+ | $res = $dbr->select($cl, 'cl_from', "cl_to = '$egSeleniumCategory'", __METHOD__, array('ORDER BY' => 'cl_sortkey')); | ||
+ | while ($row = $dbr->fetchRow($res)) $list[] = Title::newFromID($row[0])->getPrefixedText(); | ||
# Grab article $param and process contents | # Grab article $param and process contents | ||
Line 192: | Line 155: | ||
foreach ($list as $articleName) { | foreach ($list as $articleName) { | ||
$suiteTitle = Title::newFromText($articleName); | $suiteTitle = Title::newFromText($articleName); | ||
− | $ | + | $suiteArticle = new Article($suiteTitle); |
− | if ($this->articleRegex($ | + | if ($this->articleRegex($suiteTitle->getContent(), $matches)) $suites[] = $articleName; |
} | } | ||
Line 207: | Line 170: | ||
$form = wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null); | $form = wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null); | ||
$form .= '<fieldset><legend>Select a suite to run</legend>'; | $form .= '<fieldset><legend>Select a suite to run</legend>'; | ||
− | $form .= $selectTag; | + | $form .= "$selectTag<br />"; |
$form .= wfElement('input', array('type' => 'submit')); | $form .= wfElement('input', array('type' => 'submit')); | ||
$form .= "<br /><br />" . wfCheckLabel("Run automatically", "wfRunAuto" , "wfRunAuto", $checked = false); | $form .= "<br /><br />" . wfCheckLabel("Run automatically", "wfRunAuto" , "wfRunAuto", $checked = false); | ||
Line 226: | Line 189: | ||
$wgOut->addHTML($form_link); | $wgOut->addHTML($form_link); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
/** | /** | ||
− | * | + | * Bypass $wgOut -must be called early to avoid conflict with other extensions |
*/ | */ | ||
static function disableHTML(&$wgOut) { | static function disableHTML(&$wgOut) { | ||
Line 259: | Line 201: | ||
/** | /** | ||
− | * | + | * Generate 404 error |
*/ | */ | ||
private function build404($message) { | private function build404($message) { | ||
Line 270: | Line 212: | ||
/** | /** | ||
− | * | + | * Build a suite from an array of tests |
*/ | */ | ||
private function buildSuite($tests, $article) { | private function buildSuite($tests, $article) { | ||
+ | $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>$article</b></td></tr>"; | ||
$title = Title::makeTitle(NS_SPECIAL, 'Selenium'); | $title = Title::makeTitle(NS_SPECIAL, 'Selenium'); | ||
− | |||
− | |||
foreach ($tests as $element) { | foreach ($tests as $element) { | ||
$url = $title->getLocalURL("suite=$article&test=$element"); | $url = $title->getLocalURL("suite=$article&test=$element"); | ||
$html .= "\n<tr><td><a href=\"$url\">$element</a></td></tr>"; | $html .= "\n<tr><td><a href=\"$url\">$element</a></td></tr>"; | ||
} | } | ||
− | $html | + | return "$html\n</tbody></table></body></html>"; |
− | |||
} | } | ||
} | } | ||
Line 292: | Line 234: | ||
# Process suite or test if ?suite=article_name in query string | # Process suite or test if ?suite=article_name in query string | ||
− | if ($wgRequest->getText('suite')) | + | if ($wgRequest->getText('suite')) SpecialSelenium::disableHTML($wgOut); |
− | |||
− | |||
$egSelenium = new Selenium(); | $egSelenium = new Selenium(); | ||
Line 300: | Line 240: | ||
# Add the messages used by the specialpage | # Add the messages used by the specialpage | ||
if ($wgLanguageCode == 'en') { | if ($wgLanguageCode == 'en') { | ||
− | $wgMessageCache->addMessages(array( | + | $wgMessageCache->addMessages(array('selenium' => 'Selenium testing environment')); |
− | |||
− | |||
} | } | ||
Revision as of 07:57, 1 August 2008
<?php /**
* Extension:SeleniumTemplate:Php
Category:Extensions in progress
* Category:SeleniumCategory:Extensions created with Template:SpecialPage * - Licenced under LGPL http://www.gnu.org/copyleft/lesser.html * - Author: http://www.organicdesign.co.nz/User:Sven (M Davy) */
if (!defined('MEDIAWIKI')) die('Not an entry point.'); define('SELENIUM_VERSION', '0.8.0, 2008-08-01');
$egSeleniumPath = preg_replace('|^.+(?=[/\\\\]extensions)|', $wgScriptPath, dirname(__FILE__)) . 'selenium-core'; $egResultsUrlPath = "../../tmp/results.php"; $egSeleniumCategory = "Selenium";
$wgExtensionFunctions[] = 'efSetupSelenium'; $wgHooks['LanguageGetMagic'][] = 'efSeleniumLanguageGetMagic';
$wgExtensionCredits['specialpage'][] = array( 'name' => 'Special:Selenium', 'author' => 'Sven (M Davy)', 'description' => 'Incorporating Selenium tests into the MediaWiki environment', 'url' => 'http://www.organicdesign.co.nz/Extension:Selenium.php', 'version' => SELENIUM_VERSION );
/**
* Define the class for rendering selenium test tables */
class Selenium {
# Constructor function __construct() { global $wgParser;
# Add the tag hooks $wgParser->setHook('body', array($this, 'tagBody')); $wgParser->setHook('head', array($this, 'tagHead')); $wgParser->setHook('html', array($this, 'tagParseContent')); $wgParser->setHook('thead', array($this, 'tagParseContent')); $wgParser->setHook('tbody', array($this, 'tagParseContent'));
# todo: check the schedule and see if any test-runs should be spawned
}
/** * Body tags surround the main test table and should be converted to a div of class "selenium" * - this tag also handles the categorisation of the article into Category:Selenium */ public function tagBody($text, &$argv, &$parser) { global $egSeleniumCategory; $text .= ""; $text = $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false)->getText();
return "
";
}
/** * The head tag of a selenium test doesn't need to be rendered, so simply returns an empty string */ public function tagHead(&$text, &$argv, &$parser) { return ; }
/** * The html, thead and tbody tags need to parse and return their content */ public function tagParseContent(&$text, &$argv, &$parser) { return $parser->parse($text, $parser->mTitle, $parser->mOptions, false, false)->getText(); }
/** * Needed in some versions to prevent Special:Version from breaking */ private function __toString() { return __CLASS__; } }
/**
* Define a new class based on the SpecialPage class */
require_once "$IP/includes/SpecialPage.php"; class SpecialSelenium extends SpecialPage {
function __construct() { SpecialPage::SpecialPage('Selenium', , true, false, false, false); }
public function execute() { global $wgOut, $wgParser, $wgRequest, $egResultsUrlPath;
# Process suite or test if ?suite=article_name in query string if ($wgRequest->getText('suite')) {
# Grab article $param and process contents $suiteTitle = Title::newFromText($wgRequest->getText('suite'));
# get the content of the suite article and expand braces $suiteArticle = new Article($suiteTitle); $wikitext = $wgParser->preprocess($suiteArticle->getContent(), $suiteTitle, new ParserOptions());
# Preparse encapsulations around Selenium tags e.g. <selenium> $wikitext = preg_replace("|</?selenium>|", "<selenium>", $wikitext);
$matches = array(); if (!$this->articleRegex($wikitext, $matches)) { $this -> build404('Specified suite contains no selenium test tags'); } else {
# Determine whether suite or test from ?suite=article_name&test=section_num in query string if ($wgRequest->getText('test')) { $testTitle = Title::newFromText($wgRequest->getText('test')); if (in_array($testTitle->getText(), $matches[1])) { $counter = 0; foreach ($matches[1] as $value) { if ($value == $testTitle->getText()) { # Generating test html $matches[2][$counter] = preg_replace( '|.+?<selenium>\n?(.+?)</selenium>|ms', "$1", $matches[2][$counter] ); print $matches[2][$counter]; break; #exit foreach loop when test is found } $counter++; } } else $this->build404("Specified test does not exist in ".$wgRequest->getText('suite')); } else { # Obtain suite section headers $suite_urls = array(); foreach ($matches[1] as $value) array_push($suite_urls, $value); print $this->buildSuite($suite_urls, $wgRequest->getText('suite')); } } }
else { global $egSeleniumCategory, $egSeleniumPath;
# Retrieve articles in category labelled $egSeleniumCategory $list = array(); $dbr = &wfGetDB(DB_SLAVE); $cl = $dbr->tableName('categorylinks'); $res = $dbr->select($cl, 'cl_from', "cl_to = '$egSeleniumCategory'", __METHOD__, array('ORDER BY' => 'cl_sortkey')); while ($row = $dbr->fetchRow($res)) $list[] = Title::newFromID($row[0])->getPrefixedText();
# Grab article $param and process contents $suites = array(); foreach ($list as $articleName) { $suiteTitle = Title::newFromText($articleName); $suiteArticle = new Article($suiteTitle); if ($this->articleRegex($suiteTitle->getContent(), $matches)) $suites[] = $articleName; }
$selectTag = '<select name="selenium">'; foreach ($suites as $suite) $selectTag .= "<option>$suite</option>"; $selectTag .= '</select>';
$this->setHeaders(); $title = Title::makeTitle(NS_SPECIAL, 'Selenium');
$path = "$egSeleniumPath?test=".urlencode($title->getLocalURL());
$form = wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null);
$form .= '<fieldset><legend>Select a suite to run</legend>';
$form .= "$selectTag
";
$form .= wfElement('input', array('type' => 'submit'));
$form .= "
" . wfCheckLabel("Run automatically", "wfRunAuto" , "wfRunAuto", $checked = false);
$form .= '</fieldset></form>';
$wgOut->addHTML($form);
if ($wgRequest->getText('action')) {
# foreach($_REQUEST as $key=>$value) {
# print "$key>$value" . "
";
}
$path .= urlencode($wgRequest->getText('selenium'));
if ($wgRequest->getBool('wfRunAuto')) $path .= "&auto=true&resultsUrl=$egResultsUrlPath";
$form_link = '<fieldset><legend>Click link to run selenium-core</legend>'; $form_link .= "<a href=\"$path\">" . $wgRequest->getText('selenium') . '</a></fieldset>'; $wgOut->addHTML($form_link); } }
/** * Bypass $wgOut -must be called early to avoid conflict with other extensions */ static function disableHTML(&$wgOut) { $wgOut->disable(); wfResetOutputBuffers(); return; }
/** * Generate 404 error */ private function build404($message) { header('HTTP/1.0 404 not Found'); $err = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
$message
The requested URL was not found on this server.
"; print $err; return; }
/** * Build a suite from an array of tests */ private function buildSuite($tests, $article) { $html = "
$article |
$element |
"; } }
/**
* Called from $wgExtensionFunctions array when initialising extensions */
function efSetupSelenium() { global $wgRequest, $wgOut, $egSelenium, $wgLanguageCode, $wgMessageCache;
# Process suite or test if ?suite=article_name in query string if ($wgRequest->getText('suite')) SpecialSelenium::disableHTML($wgOut);
$egSelenium = new Selenium();
# Add the messages used by the specialpage if ($wgLanguageCode == 'en') { $wgMessageCache->addMessages(array('selenium' => 'Selenium testing environment')); }
# Add the specialpage to the environment SpecialPage::addPage(new SpecialSelenium()); }
/**
* Needed in MediaWiki >1.8.0 for magic word hooks to work properly */
function efSeleniumLanguageGetMagic(&$magicWords, $langCode = 0) { global $egSeleniumMagic; $magicWords[$egSeleniumMagic] = array($langCode, $egSeleniumMagic); return true; }