6 * @copyright Copyright © Wikimedia Deuschland, 2009
7 * @author Hallo Welt! Medienwerkstatt GmbH
8 * @author Markus Glaser, Dan Nessett, Priyanka Dhanda
9 * initial idea by Daniel Kinzler
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 * http://www.gnu.org/copyleft/gpl.html
27 $IP = dirname( dirname( __FILE__
) );
29 define( 'SELENIUMTEST', true );
31 //require_once( dirname( __FILE__ ) . '/../maintenance/commandLine.inc' );
32 require( dirname( __FILE__
) . '/../maintenance/Maintenance.php' );
34 require_once( 'PHPUnit/Runner/Version.php' );
35 if( version_compare( PHPUnit_Runner_Version
::id(), '3.5.0', '>=' ) ) {
36 # PHPUnit 3.5.0 introduced a nice autoloader based on class name
37 require_once( 'PHPUnit/Autoload.php' );
39 # Keep the old pre PHPUnit 3.5.0 behaviour for compatibility
40 require_once( 'PHPUnit/TextUI/Command.php' );
43 require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' );
44 include_once( 'PHPUnit/Util/Log/JUnit.php' );
46 require_once( dirname( __FILE__
) . "/selenium/SeleniumServerManager.php" );
48 class SeleniumTester
extends Maintenance
{
50 protected $serverManager;
51 protected $seleniumServerExecPath;
53 public function __construct() {
54 parent
::__construct();
55 $this->mDescription
= "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework";
56 $this->addOption( 'port', 'Port used by selenium server. Default: 4444', false, true );
57 $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath', false, true );
58 $this->addOption( 'testBrowser', 'The browser used during testing. Default: firefox', false, true );
59 $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost', false, true );
60 $this->addOption( 'username', 'The login username for sunning tests. Default: empty', false, true );
61 $this->addOption( 'userPassword', 'The login password for running tests. Default: empty', false, true );
62 $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty', false, true );
63 $this->addOption( 'list-browsers', 'List the available browsers.' );
64 $this->addOption( 'verbose', 'Be noisier.' );
65 $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' );
66 $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' );
67 $this->addOption( 'jUnitLogFile', 'Log results in a specified JUnit log file. Default: empty', false, true );
68 $this->addOption( 'runAgainstGrid', 'The test will be run against a Selenium Grid. Default: false.', false, true );
69 $this->deleteOption( 'dbpass' );
70 $this->deleteOption( 'dbuser' );
71 $this->deleteOption( 'globals' );
72 $this->deleteOption( 'wiki' );
75 public function listBrowsers() {
76 $desc = "Available browsers:\n";
78 foreach ($this->selenium
->getAvailableBrowsers() as $k => $v) {
79 $desc .= " $k => $v\n";
85 protected function startServer() {
86 if ( $this->seleniumServerExecPath
== '' ) {
87 die ( "The selenium server exec path is not set in " .
88 "selenium_settings.ini. Cannot start server \n" .
89 "as requested - terminating RunSeleniumTests\n" );
91 $this->serverManager
= new SeleniumServerManager( 'true',
92 $this->selenium
->getPort(),
93 $this->seleniumServerExecPath
);
94 switch ( $this->serverManager
->start() ) {
98 die ( "Unable to start the Selenium Server - " .
99 "terminating RunSeleniumTests\n" );
101 echo ( "Warning: The Selenium Server is " .
102 "already running\n" );
109 protected function stopServer() {
110 if ( !isset ( $this->serverManager
) ) {
111 echo ( "Warning: Request to stop Selenium Server, but it was " .
112 "not stared by RunSeleniumTests\n" .
113 "RunSeleniumTests cannot stop a Selenium Server it " .
116 switch ( $this->serverManager
->stop() ) {
120 echo ( "unable to stop the Selenium Server\n" );
126 protected function runTests( $seleniumTestSuites = array() ) {
127 $result = new PHPUnit_Framework_TestResult
;
128 $result->addListener( new SeleniumTestListener( $this->selenium
->getLogger() ) );
129 if ( $this->selenium
->getJUnitLogFile() ) {
130 $jUnitListener = new PHPUnit_Util_Log_JUnit( $this->selenium
->getJUnitLogFile(), true );
131 $result->addListener( $jUnitListener );
134 foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) {
135 require( $testSuiteFile );
136 $suite = new $testSuiteName();
137 $suite->setName( $testSuiteName );
141 $suite->run( $result );
142 } catch ( Testing_Selenium_Exception
$e ) {
144 throw new MWException( $e->getMessage() );
148 if ( $this->selenium
->getJUnitLogFile() ) {
149 $jUnitListener->flush();
153 public function execute() {
154 global $wgServer, $wgScriptPath, $wgHooks;
156 $seleniumSettings = array();
157 $seleniumBrowsers = array();
158 $seleniumTestSuites = array();
160 $configFile = $this->getOption( 'seleniumConfig', '' );
161 if ( strlen( $configFile ) > 0 ) {
162 $this->output("Using Selenium Configuration file: " . $configFile . "\n");
163 SeleniumConfig
::getSeleniumSettings( $seleniumSettings,
167 } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) {
168 $this->output("No command line, configuration file or configuration hook found.\n");
169 SeleniumConfig
::getSeleniumSettings( $seleniumSettings,
174 $this->output("Using 'SeleniumSettings' hook for configuration.\n");
175 wfRunHooks('SeleniumSettings', array( $seleniumSettings,
177 $seleniumTestSuites ) );
180 // State for starting/stopping the Selenium server has nothing to do with the Selenium
181 // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but
182 // the Maintenance class does not have a setOption()
183 if ( ! isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true );
184 if ( ! isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true );
185 if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = '';
186 $this->seleniumServerExecPath
= $seleniumSettings['seleniumserverexecpath'];
188 //set reasonable defaults if we did not find the settings
189 if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox');
190 if ( !isset( $seleniumSettings['host'] ) ) $seleniumSettings['host'] = $wgServer . $wgScriptPath;
191 if ( !isset( $seleniumSettings['port'] ) ) $seleniumSettings['port'] = '4444';
192 if ( !isset( $seleniumSettings['wikiUrl'] ) ) $seleniumSettings['wikiUrl'] = 'http://localhost';
193 if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = '';
194 if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = '';
195 if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox';
196 if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) $seleniumSettings['jUnitLogFile'] = false;
197 if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) $seleniumSettings['runAgainstGrid'] = false;
199 // Setup Selenium class
200 $this->selenium
= new Selenium( );
201 $this->selenium
->setAvailableBrowsers( $seleniumBrowsers );
202 $this->selenium
->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) );
203 $this->selenium
->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
204 $this->selenium
->setBrowser( $this->getOption( 'testBrowser', $seleniumSettings['testBrowser'] ) );
205 $this->selenium
->setPort( $this->getOption( 'port', $seleniumSettings['port'] ) );
206 $this->selenium
->setHost( $this->getOption( 'host', $seleniumSettings['host'] ) );
207 $this->selenium
->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) );
208 $this->selenium
->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) );
209 $this->selenium
->setVerbose( $this->hasOption( 'verbose' ) );
210 $this->selenium
->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) );
212 if( $this->hasOption( 'list-browsers' ) ) {
213 $this->listBrowsers();
216 if ( $this->hasOption( 'startserver' ) ) {
217 $this->startServer();
220 $logger = new SeleniumTestConsoleLogger
;
221 $this->selenium
->setLogger( $logger );
223 $this->runTests( $seleniumTestSuites );
225 if ( $this->hasOption( 'stopserver' ) ) {
231 $maintClass = "SeleniumTester";
233 require_once( RUN_MAINTENANCE_IF_MAIN
);