'SpecialRecentChanges' => 'includes/specials/SpecialRecentchanges.php',
'SpecialRecentchangeslinked' => 'includes/specials/SpecialRecentchangeslinked.php',
'SpecialSearch' => 'includes/specials/SpecialSearch.php',
- 'SpecialSelenium' => 'includes/specials/SpecialSelenium.php',
'SpecialSpecialpages' => 'includes/specials/SpecialSpecialpages.php',
'SpecialStatistics' => 'includes/specials/SpecialStatistics.php',
'SpecialTags' => 'includes/specials/SpecialTags.php',
'UserDupes' => 'maintenance/userDupes.inc',
# maintenance/tests/selenium
- 'SimpleSeleniumTestSuite' => 'maintenance/tests/selenium/SimpleSeleniumTestSuite.php',
'Selenium' => 'maintenance/tests/selenium/Selenium.php',
'SeleniumLoader' => 'maintenance/tests/selenium/SeleniumLoader.php',
'SeleniumTestCase' => 'maintenance/tests/selenium/SeleniumTestCase.php',
'SeleniumTestHTMLLogger' => 'maintenance/tests/selenium/SeleniumTestHTMLLogger.php',
'SeleniumTestListener' => 'maintenance/tests/selenium/SeleniumTestListener.php',
'SeleniumTestSuite' => 'maintenance/tests/selenium/SeleniumTestSuite.php',
+ 'SeleniumTestConfig' => 'maintenance/tests/selenium/SeleniumTestConfig.php',
# maintenance/language
'csvStatsOutput' => 'maintenance/language/StatOutputs.php',
//'deprecated',
);
+/**
+ * Allows running of selenium tests via maintenance/tests/RunSeleniumTests.php
+ */
+$wgEnableSelenium = false;
+
+
+
/**
* For really cool vim folding this needs to be at the end:
* vim: foldmarker=@{,@} foldmethod=marker
public function __construct() {
parent::__construct();
-
- $this->addOption( 'port', 'Port used by selenium server' );
- $this->addOption( 'host', 'Host selenium server' );
- $this->addOption( 'browser', 'The browser he used during testing' );
- $this->addOption( 'url', 'The Mediawiki installation to point to.' );
+ $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework";
+ $this->addOption( 'port', 'Port used by selenium server. Default: 4444' );
+ $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath' );
+ $this->addOption( 'testBrowser', 'The browser he used during testing. Default: firefox' );
+ $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost' );
+ $this->addOption( 'username', 'The login username for sunning tests. Default: empty' );
+ $this->addOption( 'userPassword', 'The login password for running tests. Default: empty' );
+ $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty' );
$this->addOption( 'list-browsers', 'List the available browsers.' );
$this->addOption( 'verbose', 'Be noisier.' );
public function listBrowsers() {
$desc = "Available browsers:\n";
- $sel = new Selenium;
- foreach ($sel->setupBrowsers() as $k => $v) {
+ foreach ($this->selenium->getAvailableBrowsers() as $k => $v) {
$desc .= " $k => $v\n";
}
echo $desc;
}
- protected function getTestSuites() {
- return array( 'SimpleSeleniumTestSuite' );
- }
-
- protected function runTests( ) {
+ protected function runTests( $seleniumTestSuites = array() ) {
$result = new PHPUnit_Framework_TestResult;
$result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) );
-
- foreach ( $this->getTestSuites() as $testSuiteName ) {
- $suite = new $testSuiteName;
+
+ foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) {
+ require( $testSuiteFile );
+ $suite = new $testSuiteName();
$suite->addTests();
+
try {
$suite->run( $result );
} catch ( Testing_Selenium_Exception $e ) {
+ $suite->tearDown();
throw new MWException( $e->getMessage() );
}
}
}
public function execute() {
- global $wgServer, $wgScriptPath;
-
- /**
- * @todo Add an alternative where settings are read from an INI file.
- */
+ global $wgServer, $wgScriptPath, $wgHooks;
+
+ $seleniumSettings;
+ $seleniumBrowsers;
+ $seleniumTestSuites;
+
+ $configFile = $this->getOption( 'seleniumConfig', '' );
+ if ( strlen( $configFile ) > 0 ) {
+ $this->output("Using Selenium Configuration file: " . $configFile . "\n");
+ SeleniumTestConfig::getSeleniumSettings( &$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites,
+ $configFile );
+ } else if ( !isset( $wgHooks['SeleniumSettings'] ) ) {
+ $this->output("Using default Selenium Configuration file: selenium_settings.ini in the root directory.\n");
+ SeleniumTestConfig::getSeleniumSettings( &$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites
+ );
+ } else {
+ $this->output("Using 'SeleniumSettings' hook for configuration.\n");
+ wfRunHooks('SeleniumSettings', array( &$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites ) );
+ }
+
+
+ //set reasonable defaults if we did not find the settings
+ if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox');
+ if ( !isset( $seleniumSettings['host'] ) ) $seleniumSettings['host'] = $wgServer . $wgScriptPath;
+ if ( !isset( $seleniumSettings['port'] ) ) $seleniumSettings['port'] = '4444';
+ if ( !isset( $seleniumSettings['wikiUrl'] ) ) $seleniumSettings['wikiUrl'] = 'http://localhost';
+ if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = '';
+ if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = '';
+ if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox';
+
$this->selenium = new Selenium( );
- $this->selenium->setUrl( $this->getOption( 'url', $wgServer . $wgScriptPath ) );
- $this->selenium->setBrowser( $this->getOption( 'browser', 'firefox' ) );
- $this->selenium->setPort( $this->getOption( 'port', 4444 ) );
- $this->selenium->setHost( $this->getOption( 'host', 'localhost' ) );
- $this->selenium->setUser( $this->getOption( 'user', 'WikiSysop' ) );
- $this->selenium->setPass( $this->getOption( 'pass', 'Password' ) );
+ $this->selenium->setAvailableBrowsers( $seleniumBrowsers );
+ $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
+ $this->selenium->setBrowser( $this->getOption( 'testBrowser', $seleniumSettings['testBrowser'] ) );
+ $this->selenium->setPort( $this->getOption( 'port', $seleniumSettings['port'] ) );
+ $this->selenium->setHost( $this->getOption( 'host', $seleniumSettings['host'] ) );
+ $this->selenium->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) );
+ $this->selenium->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) );
$this->selenium->setVerbose( $this->hasOption( 'verbose' ) );
if( $this->hasOption( 'list-browsers' ) ) {
$logger = new SeleniumTestConsoleLogger;
$this->selenium->setLogger( $logger );
- $this->runTests( );
+ $this->runTests( $seleniumTestSuites );
}
}
--- /dev/null
+<?php
+
+class SeleniumConfigurationTest extends PHPUnit_Framework_TestCase {
+
+ /*
+ * The file where the test temporarity stores the selenium config.
+ * This should be cleaned up as part of teardown.
+ */
+ private $tempFileName;
+
+ /*
+ * String containing the a sample selenium settings
+ */
+ private $testConfig0 =
+'
+[SeleniumSettings]
+browsers[firefox] = "*firefox"
+browsers[iexplorer] = "*iexploreproxy"
+browsers[chrome] = "*chrome"
+host = "localhost"
+port = "foobarr"
+wikiUrl = "http://localhost/deployment"
+username = "xxxxxxx"
+userPassword = ""
+testBrowser = "chrome"
+
+[SeleniumTests]
+testSuite[SimpleSeleniumTestSuite] = "maintenance/tests/selenium/SimpleSeleniumTestSuite.php"
+testSuite[TestSuiteName] = "testSuitePath"
+';
+ /*
+ * Array of expected browsers from $testConfig0
+ */
+ private $testBrowsers0 = array( 'firefox' => '*firefox',
+ 'iexplorer' => '*iexploreproxy',
+ 'chrome' => '*chrome'
+ );
+ /*
+ * Array of expected selenium settings from $testConfig0
+ */
+ private $testSettings0 = array(
+ 'host' => 'localhost',
+ 'port' => 'foobarr',
+ 'wikiUrl' => 'http://localhost/deployment',
+ 'username' => 'xxxxxxx',
+ 'userPassword' => '',
+ 'testBrowser' => 'chrome'
+ );
+ /*
+ * Array of expected testSuites from $testConfig0
+ */
+ private $testSuites0 = array(
+ 'SimpleSeleniumTestSuite' => 'maintenance/tests/selenium/SimpleSeleniumTestSuite.php',
+ 'TestSuiteName' => 'testSuitePath'
+ );
+
+
+ /*
+ * Another sample selenium settings file contents
+ */
+ private $testConfig1 =
+'
+[SeleniumSettings]
+host = "localhost"
+testBrowser = "firefox"
+';
+ /*
+ * Expected browsers from $testConfig1
+ */
+ private $testBrowsers1 = null;
+ /*
+ * Expected selenium settings from $testConfig1
+ */
+ private $testSettings1 = array(
+ 'host' => 'localhost',
+ 'port' => null,
+ 'wikiUrl' => null,
+ 'username' => null,
+ 'userPassword' => null,
+ 'testBrowser' => 'firefox'
+ );
+ /*
+ * Expected test suites from $testConfig1
+ */
+ private $testSuites1 = null;
+
+
+ /*
+ * Clean up the temporary file used to sore the selenium settings.
+ */
+ public function tearDown() {
+ if ( strlen( $this->tempFileName ) > 0 ) {
+ unlink( $this->tempFileName );
+ unset( $this->tempFileName );
+ }
+ parent::tearDown();
+ }
+
+ /**
+ * @expectedException MWException
+ * @group SeleniumFramework
+ * This test will throw warnings unless you have the following setting in your php.ini
+ * allow_call_time_pass_reference = On
+ */
+ public function testErrorOnMissingConfigFile() {
+ $seleniumSettings;
+ $seleniumBrowsers;
+ $seleniumTestSuites;
+
+ SeleniumTestConfig::getSeleniumSettings(&$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites,
+ "Some_fake_settings_file.ini" );
+ }
+
+ /**
+ * @group SeleniumFramework
+ * @dataProvider sampleConfigs
+ * This test will throw warnings unless you have the following setting in your php.ini
+ * allow_call_time_pass_reference = On
+ */
+ public function testgetSeleniumSettings($sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) {
+ //print "SAMPLE_CONFIG " . $sampleConfig . "\n\n";
+ $this->writeToTempFile( $sampleConfig );
+ $seleniumSettings;
+ $seleniumBrowsers;
+ $seleniumTestSuites;
+
+ SeleniumTestConfig::getSeleniumSettings(&$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites,
+ $this->tempFileName );
+
+
+ $this->assertEquals($seleniumSettings, $expectedSettings,
+ "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig
+ );
+ $this->assertEquals($seleniumBrowsers, $expectedBrowsers,
+ "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig
+ );
+ $this->assertEquals($seleniumTestSuites, $expectedSuites,
+ "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig
+ );
+
+
+ }
+
+ /*
+ * create a temp file and write text to it.
+ * @param $testToWrite the text to write to the temp file
+ */
+ private function writeToTempFile($textToWrite) {
+ $this->tempFileName = tempnam(sys_get_temp_dir(), 'test_settings.');
+ $tempFile = fopen( $this->tempFileName, "w" );
+ fwrite($tempFile , $textToWrite);
+ fclose($tempFile);
+ }
+
+ /*
+ * Returns an array containing:
+ * The contents of the selenium cingiguration ini file
+ * The expected selenium configuration array that getSeleniumSettings should return
+ * The expected available browsers array that getSeleniumSettings should return
+ * The expected test suites arrya that getSeleniumSettings should return
+ */
+ public function sampleConfigs() {
+ return array(
+ array($this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ),
+ array($this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 )
+ );
+ }
+
+
+}
\ No newline at end of file
class Selenium {
protected static $_instance = null;
+
public $isStarted = false;
public $tester;
$this->isStarted = false;
}
- protected function setupBrowsers() {
- /**
- * @todo This needs to be replaced with something not hard
- * coded. This would be entries in a .ini file or
- * screen-scraping
- * http://grid.tesla.usability.wikimedia.org:4444/console for
- * example.
- */
- return array(
- 'firefox' => 'Firefox 3.5 on Linux',
- 'iexplorer' => '*iexploreproxy',
- 'chrome' => '*googlechrome',
- );
- }
-
public function login() {
+ if ( strlen( $this->user ) == 0 ) {
+ return;
+ }
$this->open( self::$url . '/index.php?title=Special:Userlogin' );
$this->type( 'wpName1', $this->user );
$this->type( 'wpPassword1', $this->pass );
$this->click( "//input[@id='wpLoginAttempt']" );
- $this->waitForPageToLoad( 5000 );
+ $this->waitForPageToLoad( 10000 );
// after login we redirect to the main page. So check whether the "Prefernces" top menu item exists
$value = $this->isElementPresent( "//li[@id='pt-preferences']" );
public function setVerbose( $verbose ) {
$this->verbose = $verbose;
}
+
+ public function setAvailableBrowsers( $availableBrowsers ) {
+ $this->browsers = $availableBrowsers;
+ }
public function setBrowser( $b ) {
- $browsers = $this->setupBrowsers();
-
-
- if ( !isset( $browsers[$b] ) ) {
+ if ( !isset( $this->browsers[$b] ) ) {
throw new MWException( "Invalid Browser: $b.\n" );
}
- $this->browser = $browsers[$b];
+ $this->browser = $this->browsers[$b];
+ }
+
+ public function getAvailableBrowsers() {
+ return $this->browsers;
}
public function __call( $name, $args ) {
--- /dev/null
+<?php
+
+class SeleniumTestConfig {
+
+ /*
+ * Retreives the Selenium configuration values from an ini file.
+ * See sample config file in selenium_settings.ini.sample
+ *
+ */
+ public static function getSeleniumSettings ( &$seleniumSettings,
+ &$seleniumBrowsers,
+ &$seleniumTestSuites,
+ $seleniumConfigFile = null ) {
+ if ( $seleniumConfigFile == null ) {
+ global $wgSeleniumConfigFile;
+ $seleniumConfigFile = ( isset( $wgSeleniumConfigFile ) ) ?
+ $wgSeleniumConfigFile : dirname( __FILE__ ) . "/../../../selenium_settings.ini";
+ }
+
+ if ( !file_exists( $seleniumConfigFile ) ) {
+ throw new MWException( "Unable to read local Selenium Settings from " . $seleniumConfigFile . "\n" );
+ }
+
+ $configArray = parse_ini_file($seleniumConfigFile, true);
+ if ( array_key_exists( 'SeleniumSettings', $configArray) ) {
+ wfSuppressWarnings();
+ //we may need to change how this is set. But for now leave it in the ini file
+ $seleniumBrowsers = $configArray['SeleniumSettings']['browsers'];
+
+ $seleniumSettings['host'] = $configArray['SeleniumSettings']['host'];
+ $seleniumSettings['port'] = $configArray['SeleniumSettings']['port'];
+ $seleniumSettings['wikiUrl'] = $configArray['SeleniumSettings']['wikiUrl'];
+ $seleniumSettings['username'] = $configArray['SeleniumSettings']['username'];
+ $seleniumSettings['userPassword'] = $configArray['SeleniumSettings']['userPassword'];
+ $seleniumSettings['testBrowser'] = $configArray['SeleniumSettings']['testBrowser'];
+ wfRestoreWarnings();
+ }
+ if ( array_key_exists( 'SeleniumTests', $configArray) ) {
+ wfSuppressWarnings();
+ $seleniumTestSuites = $configArray['SeleniumTests']['testSuite'];
+ wfRestoreWarnings();
+ }
+ return true;
+ }
+
+}
public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) {
$this->logger->write( 'Testsuite ' . $suite->getName() . ' started.' );
$this->tests_ok = 0;
+ $this->tests_failed = 0;
}
public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) {
- $this->logger->write(
- 'Testsuite ' . $suite->getName() . ' ended. OK: ' .
- $this->tests_ok . ' Failed: ' . $this->tests_failed
- );
+ $this->logger->write('Testsuite ' . $suite->getName() . ' ended.' );
+ if ( $this->tests_ok > 0 || $this->tests_failed > 0 ) {
+ $this->logger->write( ' OK: ' . $this->tests_ok . ' Failed: ' . $this->tests_failed );
+ }
+ $this->tests_ok = 0;
+ $this->tests_failed = 0;
}
public function statusMessage( $message ) {
<?php
-class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
+abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
private $selenium;
private $isSetUp = false;
const RESULT_OK = 2;
const RESULT_ERROR = 3;
+ public abstract function addTests();
+
public function setUp() {
// Hack because because PHPUnit version 3.0.6 which is on prototype does not
// run setUp as part of TestSuite::run
$this->isSetUp = true;
$this->selenium = Selenium::getInstance();
$this->selenium->start();
+ //$this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() );
$this->login();
- // $this->loadPage( 'Testpage', 'edit' );
}
public function tearDown() {
+ //$this->selenium->open( $this->selenium->getUrl() . '/index.php?clearTestSuite=' . $this->getName() );
$this->selenium->stop();
}
class SimpleSeleniumTestCase extends SeleniumTestCase
{
- public function __construct( $name = 'Basic selenium test') {
- parent::__construct( $name );
- }
-
- public function runTest()
+ public function testBasic()
{
- $this->open( Selenium::getBaseUrl() .
+ $this->open( $this->getUrl() .
'/index.php?title=Selenium&action=edit' );
$this->type( "wpTextbox1", "This is a basic test" );
$this->click( "wpPreview" );
$this->assertEquals( $correct, true );
}
+
+ /*
+ * Needs the following in your LocalConfig or an alternative method of configuration (coming soon)
+ * require_once( "$IP/extensions/UsabilityInitiative/Vector/Vector.php" );
+ * $wgDefaultSkin='vector';
+ */
+ public function testGlobalVariable1()
+ {
+ $this->open( $this->getUrl() . '/index.php?&action=purge' );
+ $bodyClass = $this->getAttribute( "//body/@class" );
+ $this-> assertContains('skin-vector', $bodyClass, 'Vector skin not set');
+ }
}
<?php
-
-require_once(dirname( __FILE__ ) . '/SimpleSeleniumTestCase.php');
class SimpleSeleniumTestSuite extends SeleniumTestSuite
{
- public function __construct( $name = 'Basic selenium test suite') {
- parent::__construct( $name );
- }
-
public function addTests() {
- $test = new SimpleSeleniumTestCase();
- parent::addTest( $test );
+ $testFiles = array(
+ 'maintenance/tests/selenium/SimpleSeleniumTestCase.php'
+ );
+ parent::addTestFiles( $testFiles );
}
+
+
}
--- /dev/null
+[SeleniumSettings]
+
+browsers[firefox] = "*firefox"
+browsers[iexplorer] = "*iexploreproxy"
+browsers[chrome] = "*chrome"
+host = "localhost"
+port = "4444"
+wikiUrl = "http://localhost/deployment"
+username = "wikiuser"
+userPassword = "wikipass"
+testBrowser = "firefox"
+
+[SeleniumTests]
+
+testSuite[SimpleSeleniumTestSuite] = "maintenance/tests/selenium/SimpleSeleniumTestSuite.php"
+testSuite[PagedTiffHandlerSeleniumTestSuite] = "extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestSuite.php"
+