* Removed the insecure web entry point hiding in the maintenance directory, in RunSeleniumTests.php. Replaced it with a special page interface, with CSRF protection and access control. If you wanted a secure web entry point, then I suppose this is how it would be done, but I think it should be killed ASAP.
* As in r68544, removed as many require() calls as possible, since nobody seems to know how to do them properly. Made the usual changes to make classes autoloader-compatible: class constants instead of define(), no file-scope registration code.
'SpecialRecentChanges' => 'includes/specials/SpecialRecentchanges.php',
'SpecialRecentchangeslinked' => 'includes/specials/SpecialRecentchangeslinked.php',
'SpecialSearch' => 'includes/specials/SpecialSearch.php',
+ 'SpecialSelenium' => 'includes/specials/SpecialSelenium.php',
'SpecialStatistics' => 'includes/specials/SpecialStatistics.php',
'SpecialTags' => 'includes/specials/SpecialTags.php',
'SpecialUnlockdb' => 'includes/specials/SpecialUnlockdb.php',
# maintenance
'AnsiTermColorer' => 'maintenance/parserTests.inc',
- 'ApiTestSetup' => 'maintenance/tests/ApiSetup.php',
'DbTestPreviewer' => 'maintenance/parserTests.inc',
'DbTestRecorder' => 'maintenance/parserTests.inc',
'DeleteArchivedFilesImplementation' => 'maintenance/deleteArchivedFiles.inc',
'DeleteArchivedRevisionsImplementation' => 'maintenance/deleteArchivedRevisions.inc',
'DummyTermColorer' => 'maintenance/parserTests.inc',
- 'MediaWikiTestSetup' => 'maintenance/tests/MediaWiki_Setup.php',
- 'PHPUnitTestRecorder' => 'maintenance/tests/ParserHelpers.php',
'ParserTest' => 'maintenance/parserTests.inc',
'ParserTestParserHook' => 'maintenance/parserTestsParserHook.php',
'ParserTestStaticParserHook' => 'maintenance/parserTestsStaticParserHook.php',
- 'ParserTestSuiteBackend' => 'maintenance/tests/ParserHelpers.php',
- 'ParserUnitTest' => 'maintenance/tests/ParserHelpers.php',
'RemoteTestRecorder' => 'maintenance/parserTests.inc',
- 'SearchEngineTest' => 'maintenance/tests/SearchEngineTest.php',
'SevenZipStream' => 'maintenance/7zip.inc',
'TestFileIterator' => 'maintenance/parserTests.inc',
'TestRecorder' => 'maintenance/parserTests.inc',
+
+ # maintenance/tests
+ 'ApiTestSetup' => 'maintenance/tests/ApiSetup.php',
+ 'MediaWikiTestSetup' => 'maintenance/tests/MediaWiki_Setup.php',
+ 'PHPUnitTestRecorder' => 'maintenance/tests/ParserHelpers.php',
+ 'ParserTestSuiteBackend' => 'maintenance/tests/ParserHelpers.php',
+ 'ParserUnitTest' => 'maintenance/tests/ParserHelpers.php',
+ 'SearchEngineTest' => 'maintenance/tests/SearchEngineTest.php',
'UploadFromUrlTest' => 'maintenance/tests/UploadFromUrlTest.php',
+
+ # maintenance/tests/selenium
+ 'SimpleSeleniumTest' => 'maintenance/tests/selenium/SimpleSeleniumTest.php',
+ 'Selenium' => 'maintenance/tests/selenium/Selenium.php',
+ 'SeleniumLoader' => 'maintenance/tests/selenium/SeleniumLoader.php',
+ 'SeleniumTestCase' => 'maintenance/tests/selenium/SeleniumTestCase.php',
+ 'SeleniumTestConsoleLogger' => 'maintenance/tests/selenium/SeleniumTestConsoleLogger.php',
+ 'SeleniumTestHTMLLogger' => 'maintenance/tests/selenium/SeleniumTestHTMLLogger.php',
+ 'SeleniumTestListener' => 'maintenance/tests/selenium/SeleniumTestListener.php',
+ 'SeleniumTestSuite' => 'maintenance/tests/selenium/SeleniumTestSuite.php',
+ 'SimpleSeleniumTest' => 'maintenance/tests/selenium/SimpleSeleniumTest.php',
+
+ # maintenance/language
'csvStatsOutput' => 'maintenance/language/StatOutputs.php',
'statsOutput' => 'maintenance/language/StatOutputs.php',
'textStatsOutput' => 'maintenance/language/StatOutputs.php',
*/
$wgParserTestRemote = false;
+/**
+ * Enable Selenium test framework.
+ * This enables maintenance/tests/RunSeleniumTests.php and [[Special:Selenium]].
+ */
+$wgEnableSelenium = false;
+
+/** List of Selenium test classes. These must be registered with the autoloader. */
+$wgSeleniumTests = array(
+ 'SimpleSeleniumTest'
+);
+
+
+/** Hostname of selenium server */
+$wgSeleniumTestsSeleniumHost = 'localhost';
+
+/** URL of the wiki to be tested. By default, the local wiki is used. */
+$wgSeleniumTestsWikiUrl = false;
+
+/** Port used by selenium server. */
+$wgSeleniumServerPort = 4444;
+
+/** Wiki login username. Used by Selenium to log onto the wiki. */
+$wgSeleniumTestsWikiUser = 'Wikiuser';
+
+/** Wiki login password. Used by Selenium to log onto the wiki. */
+$wgSeleniumTestsWikiPassword = '';
+
+/**
+ * Common browsers on Windows platform. Modify for other platforms or
+ * other Windows browsers.
+ * Use the *chrome handler in order to be able to test file uploads.
+ * Further solution suggestions: http://www.brokenbuild.com/blog/2007/06/07/testing-file-uploads-with-selenium-rc-and-firefoxor-reducing-javascript-security-in-firefox-for-fun-and-profit/
+ */
+$wgSeleniumTestsBrowsers = array(
+ 'firefox' => '*firefox /usr/bin/firefox',
+ 'iexplorer' => '*iexploreproxy',
+ 'opera' => '*chrome /usr/bin/opera',
+);
+
+/** Actually, use this browser */
+$wgSeleniumTestsUseBrowser = 'firefox';
+
+
+
/** @} */ # end of profiling, testing and debugging }
/************************************************************************//**
static function initList() {
global $wgSpecialPages;
global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
+ global $wgEnableSelenium;
if ( self::$mListInitialised ) {
return;
self::$mList['Invalidateemail'] = 'EmailInvalidation';
}
+ if ( $wgEnableSelenium ) {
+ self::$mList['Selenium'] = 'SpecialSelenium';
+ }
+
# Add extension special pages
self::$mList = array_merge( self::$mList, $wgSpecialPages );
'reupload',
'reupload-shared',
'rollback',
+ 'selenium',
'sendemail',
'siteadmin',
'suppressionlog',
--- /dev/null
+<?php
+
+/**
+ * TODO: remove this feature
+ */
+
+class SpecialSelenium extends SpecialPage {
+ function __construct() {
+ parent::__construct( 'Selenium', 'selenium', false );
+ }
+
+ function getDescription() {
+ return 'Selenium';
+ }
+
+ function execute() {
+ global $wgUser, $wgOut, $wgEnableSelenium, $wgRequest;
+
+ if ( !$wgEnableSelenium ) {
+ throw new MWException(
+ 'Selenium special page invoked when it should not be registered!' );
+ }
+
+ $this->setHeaders();
+ if ( !$this->userCanExecute( $wgUser ) ) {
+ $this->displayRestrictionError();
+ return;
+ }
+
+ if ( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) {
+ $this->runTests();
+ }
+ $wgOut->addHTML(
+ Html::openElement( 'form', array(
+ 'method' => 'POST',
+ 'action' => $this->getTitle()->getLocalUrl(),
+ ) ) .
+ Html::input( 'submit', 'Run tests', 'submit' ) .
+ Html::hidden( 'token', $wgUser->editToken() ) .
+ '</form>'
+ );
+ }
+
+ function runTests() {
+ global $wgSeleniumTests, $wgOut;
+ SeleniumLoader::load();
+
+ $result = new PHPUnit_Framework_TestResult;
+ $logger = new SeleniumTestHTMLLogger;
+ $result->addListener( new SeleniumTestListener( $logger ) );
+
+ // run tests
+ $suite = new SeleniumTestSuite;
+ foreach ( $wgSeleniumTests as $testClass ) {
+ $suite->addTest( new $testClass );
+ }
+ $wgOut->addHTML( '<div class="selenium">' );
+ $suite->run( $result );
+ $wgOut->addHTML( '</div>' );
+ }
+}
+
'right-override-export-depth' => 'Export pages including linked pages up to a depth of 5',
'right-sendemail' => 'Send e-mail to other users',
'right-revisionmove' => 'Move revisions',
+'right-selenium' => 'Run Selenium tests',
# User rights log
'rightslog' => 'User rights log',
* http://www.gnu.org/copyleft/gpl.html
*/
-define( 'MEDIAWIKI', true );
define( 'SELENIUMTEST', true );
-// Here, you can override standard setting
-if ( file_exists( 'selenium/LocalSeleniumSettings.php' ) ) {
- include_once 'selenium/LocalSeleniumSettings.php';
-} else {
- echo "You must provide local settings in LocalSeleniumSettings.php\n";
- die( -1 );
-}
-
-// Command line only
-if ( $wgSeleniumTestsRunMode == 'cli' && php_sapi_name() != 'cli' ) {
- echo "Must be run from the command line.\n";
- die( -1 );
-}
-
-// Get command line parameters
-if ( $wgSeleniumTestsRunMode == 'cli' ) {
- require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
- if ( isset( $options['help'] ) ) {
- echo <<<ENDS
+require( dirname( __FILE__ ) . "/../commandLine.inc" );
+if ( isset( $options['help'] ) ) {
+ echo <<<ENDS
MediaWiki $wgVersion Selenium Framework tester
Usage: php RunSeleniumTests.php [options...]
Options:
- --port=<TCP port> Port used by selenium server to accept commands
- --help Show this help message
+--port=<TCP port> Port used by selenium server to accept commands
+--help Show this help message
ENDS;
- exit( 0 );
- }
-
- if ( isset( $options['port'] ) ) {
- $wgSeleniumServerPort = (int) $options['port'];
- }
+ exit( 1 );
}
-// requires PHPUnit 3.4
-require_once 'Testing/Selenium.php';
-require_once 'PHPUnit/Framework.php';
-require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
+if ( isset( $options['port'] ) ) {
+ $wgSeleniumServerPort = (int) $options['port'];
+}
-// include seleniumTestsuite
-require_once 'selenium/SeleniumTestHTMLLogger.php';
-require_once 'selenium/SeleniumTestConsoleLogger.php';
-require_once 'selenium/SeleniumTestListener.php';
-require_once 'selenium/Selenium.php';
-require_once 'selenium/SeleniumTestSuite.php';
-require_once 'selenium/SeleniumTestCase.php';
+SeleniumLoader::load();
$result = new PHPUnit_Framework_TestResult;
-switch ( $wgSeleniumTestsRunMode ) {
- case 'html':
- $logger = new SeleniumTestHTMLLogger;
- break;
- case 'cli':
- $logger = new SeleniumTestConsoleLogger;
- break;
-}
-
+$logger = new SeleniumTestConsoleLogger;
$result->addListener( new SeleniumTestListener( $logger ) );
-$wgSeleniumTestSuites = array();
-
-// include tests
-// Todo: include automatically
-if ( is_array( $wgSeleniumTestIncludes ) ) {
- foreach ( $wgSeleniumTestIncludes as $include ) {
- include_once $include;
- }
-}
-
-// run tests
-foreach ( $wgSeleniumTestSuites as $suite ) {
- $suite->run( $result );
+$suite = new SeleniumTestSuite;
+foreach ( $wgSeleniumTests as $testClass ) {
+ $suite->addTest( new $testClass );
}
+$suite->run( $result );
+++ /dev/null
-<?php
-// This template file contains variables that should be localized.
-// The line (specifying the location of the PHP/PEAR libraries) must be
-// first. Moving it to a position later in the file will almost certainly
-// cause an error.
-
-// In order to use this file, first copy it to LocalSeleniumSettings.php.
-// Then edit the information to conform to the local environment. You
-// will almost certainly have to uncomment the line set_include_path ... and
-// change the string 'PEAR' to the path to your PEAR library, e.g.,
-// '/usr/share/php/PEAR' for a Debian based Linux system.
-// The edited file must appear in the ../tests/selenium directory.
-
-// include path. Set 'PEAR" to '/path/to/PEAR/library'
-
-// URL: http://localhost/tests/RunSeleniumTests.php
-#set_include_path( get_include_path() . PATH_SEPARATOR . 'PEAR' );
-
-// Hostname of selenium server
-$wgSeleniumTestsSeleniumHost = 'localhost';
-
-// URL of the wiki to be tested. Consult web server configuration.
-$wgSeleniumTestsWikiUrl = 'http://localhost';
-
-// Port used by selenium server (optional - default is 4444)
-$wgSeleniumServerPort = 4444;
-
-// Wiki login. Used by Selenium to log onto the wiki
-$wgSeleniumTestsWikiUser = 'Wikisysop';
-$wgSeleniumTestsWikiPassword = 'password';
-
-// Common browsers on Windows platform. Modify for other platforms or
-// other Windows browsers
-// Use the *chrome handler in order to be able to test file uploads
-// further solution suggestions: http://www.brokenbuild.com/blog/2007/06/07/testing-file-uploads-with-selenium-rc-and-firefoxor-reducing-javascript-security-in-firefox-for-fun-and-profit/
-// $wgSeleniumTestsBrowsers['firefox'] = '*firefox c:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe';
-$wgSeleniumTestsBrowsers['firefox'] = '*firefox /usr/bin/firefox';
-$wgSeleniumTestsBrowsers['iexplorer'] = '*iexploreproxy';
-$wgSeleniumTestsBrowsers['opera'] = '*chrome /usr/bin/opera';
-
-// Actually, use this browser
-$wgSeleniumTestsUseBrowser = 'firefox';
-
-// Set command line mode
-$wgSeleniumTestsRunMode = 'cli';
-
-// List of tests to be included by default
-$wgSeleniumTestIncludes = array(
- 'selenium/SimpleSeleniumTest.php'
-);
-?>
\ No newline at end of file
* This is implemented as a singleton.
*/
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
-
class Selenium extends Testing_Selenium {
protected static $_instance = null;
public $isStarted = false;
public static function getInstance() {
global $wgSeleniumTestsBrowsers, $wgSeleniumTestsSeleniumHost, $wgSeleniumTestsUseBrowser;
- global $wgSeleniumTestsWikiUrl, $wgSeleniumServerPort;
+ global $wgSeleniumServerPort;
if ( null === self::$_instance ) {
self::$_instance = new self( $wgSeleniumTestsBrowsers[$wgSeleniumTestsUseBrowser],
- $wgSeleniumTestsWikiUrl,
+ self::getBaseUrl(),
$wgSeleniumTestsSeleniumHost,
$wgSeleniumServerPort );
}
$this->isStarted = false;
}
+ static function getBaseUrl() {
+ global $wgSeleniumTestsWikiUrl, $wgServer, $wgScriptPath;
+ if ( $wgSeleniumTestsWikiUrl ) {
+ return $wgSeleniumTestsWikiUrl;
+ } else {
+ return $wgServer . $wgScriptPath;
+ }
+ }
+
public function login() {
- global $wgSeleniumTestsWikiUser, $wgSeleniumTestsWikiPassword, $wgSeleniumTestsWikiUrl, $wgVersion;
+ global $wgSeleniumTestsWikiUser, $wgSeleniumTestsWikiPassword;
- $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Special:Userlogin' );
+ $this->open( self::getBaseUrl() . '/index.php?title=Special:Userlogin' );
$this->type( 'wpName1', $wgSeleniumTestsWikiUser );
$this->type( 'wpPassword1', $wgSeleniumTestsWikiPassword );
- if (version_compare($wgVersion, '1.15.2', '>=')) {
- $this->click( "//input[@id='wpLoginAttempt']" );
- } else {
- $this->click( "//input[@id='wpLoginattempt']" );
- }
+ $this->click( "//input[@id='wpLoginAttempt']" );
$value = $this->doCommand( 'assertTitle', array( 'Login successful*' ) );
}
public function loadPage( $title, $action ) {
- global $wgSeleniumTestsWikiUrl;
- $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=' . $title . '&action=' . $action );
+ $this->open( self::getBaseUrl() . '/index.php?title=' . $title . '&action=' . $action );
}
// Prevent external cloning
--- /dev/null
+<?php
+
+class SeleniumLoader {
+ static function load() {
+ require_once( 'Testing/Selenium.php' );
+ require_once( 'PHPUnit/Framework.php' );
+ require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' );
+ }
+}
<?php
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
-
class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extensions_SeleniumTestCase
protected $selenium;
$this->assertRegExp( "/$text/", $innerHTML );
}
-}
\ No newline at end of file
+}
<?php
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
class SeleniumTestConsoleLogger {
public function __construct() {
public function write( $message, $mode = false ) {
$out = '';
- // if ( $mode == MW_TESTLOGGER_RESULT_OK ) $out .= '<font color="green">';
+ // if ( $mode == SeleniumTestSuite::RESULT_OK ) $out .= '<font color="green">';
$out .= htmlentities( $message );
- // if ( $mode == MW_TESTLOGGER_RESULT_OK ) $out .= '</font>';
- if ( $mode != MW_TESTLOGGER_CONTINUE_LINE ) {
+ // if ( $mode == SeleniumTestSuite::RESULT_OK ) $out .= '</font>';
+ if ( $mode != SeleniumTestSuite::CONTINUE_LINE ) {
$out .= "\n";
}
echo $out;
}
-}
\ No newline at end of file
+}
<?php
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
class SeleniumTestHTMLLogger {
- public function __construct() {
- // Prepare testsuite for immediate output
- @ini_set( 'zlib.output_compression', 0 );
- @ini_set( 'implicit_flush', 1 );
- for ( $i = 0; $i < ob_get_level(); $i++ ) {
- ob_end_flush();
- }
- ob_implicit_flush( 1 );
-
- // Output some style information
- echo '<style>
- pre {
+ public function setHeaders() {
+ global $wgOut;
+ $wgOut->addHeadItem( 'selenium', '<style>
+ .selenium pre {
overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not needed in Firefox 3 */
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
/* width: 99%; */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
- </style>';
+ </style>' );
}
public function write( $message, $mode = false ) {
+ global $wgOut;
$out = '';
- if ( $mode == MW_TESTLOGGER_RESULT_OK ) {
+ if ( $mode == SeleniumTestSuite::RESULT_OK ) {
$out .= '<font color="green">';
}
- $out .= htmlentities( $message );
- if ( $mode == MW_TESTLOGGER_RESULT_OK ) {
+ $out .= htmlspecialchars( $message );
+ if ( $mode == SeleniumTestSuite::RESULT_OK ) {
$out .= '</font>';
}
- if ( $mode != MW_TESTLOGGER_CONTINUE_LINE ) {
+ if ( $mode != SeleniumTestSuite::CONTINUE_LINE ) {
$out .= '<br />';
}
- echo $out;
+ $wgOut->addHTML( $out );
}
-}
\ No newline at end of file
+}
<?php
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
class SeleniumTestListener implements PHPUnit_Framework_TestListener {
private $logger;
public function startTest( PHPUnit_Framework_Test $test ) {
$this->logger->write(
'Testing ' . $test->getName() . ' ... ',
- MW_TESTLOGGER_CONTINUE_LINE
+ SeleniumTestSuite::CONTINUE_LINE
);
}
public function endTest( PHPUnit_Framework_Test $test, $time ) {
if ( !$test->hasFailed() ) {
- $this->logger->write( 'OK', MW_TESTLOGGER_RESULT_OK );
+ $this->logger->write( 'OK', SeleniumTestSuite::RESULT_OK );
$this->tests_ok++;
}
}
<?php
-if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
- echo "This script cannot be run standalone";
- exit( 1 );
-}
-
-// Do not add line break after test output
-define( 'MW_TESTLOGGER_CONTINUE_LINE', 1 );
-define( 'MW_TESTLOGGER_RESULT_OK', 2 );
-define( 'MW_TESTLOGGER_RESULT_ERROR', 3 );
class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
private $selenium;
+ // Do not add line break after test output
+ const CONTINUE_LINE = 1;
+ const RESULT_OK = 2;
+ const RESULT_ERROR = 3;
+
public function setUp() {
$this->selenium = Selenium::getInstance();
$this->selenium->start();
<?php
-if (!defined('MEDIAWIKI') || !defined('SELENIUMTEST')) {
- echo "This script cannot be run standalone";
- exit(1);
-}
-
-// create test suite
-$wgSeleniumTestSuites['SimpleSeleniumTest'] = new SeleniumTestSuite('Simple Selenium Test');
-$wgSeleniumTestSuites['SimpleSeleniumTest']->addTest(new SimpleSeleniumTest());
-
class SimpleSeleniumTest extends SeleniumTestCase
{
public $name = "Basic selenium test";
public function runTest()
{
- global $wgSeleniumTestsWikiUrl;
- $this->open($wgSeleniumTestsWikiUrl.'/index.php?title=Selenium&action=edit');
- $this->type("wpTextbox1", "This is a basic test");
- $this->click("wpPreview");
- $this->waitForPageToLoad(10000);
+ $this->open( Selenium::getBaseUrl() . '/index.php?title=Selenium&action=edit' );
+ $this->type( "wpTextbox1", "This is a basic test" );
+ $this->click( "wpPreview" );
+ $this->waitForPageToLoad( 10000 );
// check result
- $source = $this->getText("//div[@id='wikiPreview']/p");
- $correct = strstr($source, "This is a basic test");
- $this->assertEquals($correct, true);
+ $source = $this->getText( "//div[@id='wikiPreview']/p" );
+ $correct = strstr( $source, "This is a basic test" );
+ $this->assertEquals( $correct, true );
}
-}
\ No newline at end of file
+}