MediaWiki  REL1_21
RunSeleniumTests.php
Go to the documentation of this file.
00001 #!/usr/bin/env php
00002 <?php
00027 if ( PHP_SAPI != 'cli' ) {
00028         die( "Run me from the command line please.\n" );
00029 }
00030 
00031 define( 'SELENIUMTEST', true );
00032 
00033 require( __DIR__ . '/../maintenance/Maintenance.php' );
00034 
00035 require_once( 'PHPUnit/Runner/Version.php' );
00036 if ( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) {
00037         # PHPUnit 3.5.0 introduced a nice autoloader based on class name
00038         require_once( 'PHPUnit/Autoload.php' );
00039 } else {
00040         # Keep the old pre PHPUnit 3.5.0 behavior for compatibility
00041         require_once( 'PHPUnit/TextUI/Command.php' );
00042 }
00043 
00044 require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' );
00045 include_once( 'PHPUnit/Util/Log/JUnit.php' );
00046 
00047 require_once( __DIR__ . "/selenium/SeleniumServerManager.php" );
00048 
00049 class SeleniumTester extends Maintenance {
00050         protected $selenium;
00051         protected $serverManager;
00052         protected $seleniumServerExecPath;
00053 
00054         public function __construct() {
00055                 parent::__construct();
00056                 $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework";
00057                 $this->addOption( 'port', 'Port used by selenium server. Default: 4444', false, true );
00058                 $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath', false, true );
00059                 $this->addOption( 'testBrowser', 'The browser used during testing. Default: firefox', false, true );
00060                 $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost', false, true );
00061                 $this->addOption( 'username', 'The login username for sunning tests. Default: empty', false, true );
00062                 $this->addOption( 'userPassword', 'The login password for running tests. Default: empty', false, true );
00063                 $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty', false, true );
00064                 $this->addOption( 'list-browsers', 'List the available browsers.' );
00065                 $this->addOption( 'verbose', 'Be noisier.' );
00066                 $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' );
00067                 $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' );
00068                 $this->addOption( 'jUnitLogFile', 'Log results in a specified JUnit log file. Default: empty', false, true );
00069                 $this->addOption( 'runAgainstGrid', 'The test will be run against a Selenium Grid. Default: false.', false, true );
00070                 $this->deleteOption( 'dbpass' );
00071                 $this->deleteOption( 'dbuser' );
00072                 $this->deleteOption( 'globals' );
00073                 $this->deleteOption( 'wiki' );
00074         }
00075 
00076         public function listBrowsers() {
00077                 $desc = "Available browsers:\n";
00078 
00079                 foreach ( $this->selenium->getAvailableBrowsers() as $k => $v ) {
00080                         $desc .= "  $k => $v\n";
00081                 }
00082 
00083                 echo $desc;
00084         }
00085 
00086         protected function startServer() {
00087                 if ( $this->seleniumServerExecPath == '' ) {
00088                         die ( "The selenium server exec path is not set in " .
00089                                 "selenium_settings.ini. Cannot start server \n" .
00090                                 "as requested - terminating RunSeleniumTests\n" );
00091                 }
00092                 $this->serverManager = new SeleniumServerManager( 'true',
00093                         $this->selenium->getPort(),
00094                         $this->seleniumServerExecPath );
00095                 switch ( $this->serverManager->start() ) {
00096                         case 'started':
00097                                 break;
00098                         case 'failed':
00099                                 die ( "Unable to start the Selenium Server - " .
00100                                         "terminating RunSeleniumTests\n" );
00101                         case 'running':
00102                                 echo ( "Warning: The Selenium Server is " .
00103                                         "already running\n" );
00104                                 break;
00105                 }
00106 
00107                 return;
00108         }
00109 
00110         protected function stopServer() {
00111                 if ( !isset ( $this->serverManager ) ) {
00112                         echo ( "Warning: Request to stop Selenium Server, but it was " .
00113                                 "not stared by RunSeleniumTests\n" .
00114                                 "RunSeleniumTests cannot stop a Selenium Server it " .
00115                                 "did not start\n" );
00116                 } else {
00117                         switch ( $this->serverManager->stop() ) {
00118                                 case 'stopped':
00119                                         break;
00120                                 case 'failed':
00121                                         echo ( "unable to stop the Selenium Server\n" );
00122                         }
00123                 }
00124                 return;
00125         }
00126 
00127         protected function runTests( $seleniumTestSuites = array() ) {
00128                 $result = new PHPUnit_Framework_TestResult;
00129                 $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) );
00130                 if ( $this->selenium->getJUnitLogFile() ) {
00131                         $jUnitListener = new PHPUnit_Util_Log_JUnit( $this->selenium->getJUnitLogFile(), true );
00132                         $result->addListener( $jUnitListener );
00133                 }
00134 
00135                 foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) {
00136                         require( $testSuiteFile );
00137                         $suite = new $testSuiteName();
00138                         $suite->setName( $testSuiteName );
00139                         $suite->addTests();
00140 
00141                         try {
00142                                 $suite->run( $result );
00143                         } catch ( Testing_Selenium_Exception $e ) {
00144                                 $suite->tearDown();
00145                                 throw new MWException( $e->getMessage() );
00146                         }
00147                 }
00148 
00149                 if ( $this->selenium->getJUnitLogFile() ) {
00150                         $jUnitListener->flush();
00151                 }
00152         }
00153 
00154         public function execute() {
00155                 global $wgServer, $wgScriptPath, $wgHooks;
00156 
00157                 $seleniumSettings = array();
00158                 $seleniumBrowsers = array();
00159                 $seleniumTestSuites = array();
00160 
00161                 $configFile = $this->getOption( 'seleniumConfig', '' );
00162                 if ( strlen( $configFile ) > 0 ) {
00163                         $this->output( "Using Selenium Configuration file: " . $configFile . "\n" );
00164                         SeleniumConfig::getSeleniumSettings( $seleniumSettings,
00165                                 $seleniumBrowsers,
00166                                 $seleniumTestSuites,
00167                                 $configFile );
00168                 } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) {
00169                         $this->output( "No command line, configuration file or configuration hook found.\n" );
00170                         SeleniumConfig::getSeleniumSettings( $seleniumSettings,
00171                                 $seleniumBrowsers,
00172                                 $seleniumTestSuites
00173                         );
00174                 } else {
00175                         $this->output( "Using 'SeleniumSettings' hook for configuration.\n" );
00176                         wfRunHooks( 'SeleniumSettings', array( $seleniumSettings,
00177                                 $seleniumBrowsers,
00178                                 $seleniumTestSuites ) );
00179                 }
00180 
00181                 // State for starting/stopping the Selenium server has nothing to do with the Selenium
00182                 // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but
00183                 // the Maintenance class does not have a setOption()
00184                 if ( !isset( $seleniumSettings['startserver'] ) ) {
00185                         $this->getOption( 'startserver', true );
00186                 }
00187                 if ( !isset( $seleniumSettings['stopserver'] ) ) {
00188                         $this->getOption( 'stopserver', true );
00189                 }
00190                 if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) {
00191                         $seleniumSettings['seleniumserverexecpath'] = '';
00192                 }
00193                 $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath'];
00194 
00195                 //set reasonable defaults if we did not find the settings
00196                 if ( !isset( $seleniumBrowsers ) ) {
00197                         $seleniumBrowsers = array( 'firefox' => '*firefox' );
00198                 }
00199                 if ( !isset( $seleniumSettings['host'] ) ) {
00200                         $seleniumSettings['host'] = $wgServer . $wgScriptPath;
00201                 }
00202                 if ( !isset( $seleniumSettings['port'] ) ) {
00203                         $seleniumSettings['port'] = '4444';
00204                 }
00205                 if ( !isset( $seleniumSettings['wikiUrl'] ) ) {
00206                         $seleniumSettings['wikiUrl'] = 'http://localhost';
00207                 }
00208                 if ( !isset( $seleniumSettings['username'] ) ) {
00209                         $seleniumSettings['username'] = '';
00210                 }
00211                 if ( !isset( $seleniumSettings['userPassword'] ) ) {
00212                         $seleniumSettings['userPassword'] = '';
00213                 }
00214                 if ( !isset( $seleniumSettings['testBrowser'] ) ) {
00215                         $seleniumSettings['testBrowser'] = 'firefox';
00216                 }
00217                 if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) {
00218                         $seleniumSettings['jUnitLogFile'] = false;
00219                 }
00220                 if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) {
00221                         $seleniumSettings['runAgainstGrid'] = false;
00222                 }
00223 
00224                 // Setup Selenium class
00225                 $this->selenium = new Selenium();
00226                 $this->selenium->setAvailableBrowsers( $seleniumBrowsers );
00227                 $this->selenium->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) );
00228                 $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
00229                 $this->selenium->setBrowser( $this->getOption( 'testBrowser', $seleniumSettings['testBrowser'] ) );
00230                 $this->selenium->setPort( $this->getOption( 'port', $seleniumSettings['port'] ) );
00231                 $this->selenium->setHost( $this->getOption( 'host', $seleniumSettings['host'] ) );
00232                 $this->selenium->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) );
00233                 $this->selenium->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) );
00234                 $this->selenium->setVerbose( $this->hasOption( 'verbose' ) );
00235                 $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) );
00236 
00237                 if ( $this->hasOption( 'list-browsers' ) ) {
00238                         $this->listBrowsers();
00239                         exit( 0 );
00240                 }
00241                 if ( $this->hasOption( 'startserver' ) ) {
00242                         $this->startServer();
00243                 }
00244 
00245                 $logger = new SeleniumTestConsoleLogger;
00246                 $this->selenium->setLogger( $logger );
00247 
00248                 $this->runTests( $seleniumTestSuites );
00249 
00250                 if ( $this->hasOption( 'stopserver' ) ) {
00251                         $this->stopServer();
00252                 }
00253         }
00254 }
00255 
00256 $maintClass = "SeleniumTester";
00257 
00258 require_once( RUN_MAINTENANCE_IF_MAIN );