Index: trunk/phase3/maintenance/tests/RunSeleniumTests.php |
— | — | @@ -26,8 +26,13 @@ |
27 | 27 | define( 'SELENIUMTEST', true ); |
28 | 28 | |
29 | 29 | require_once( dirname( dirname( __FILE__ ) )."/Maintenance.php" ); |
| 30 | +require_once( 'PHPUnit/Framework.php' ); |
| 31 | +require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); |
30 | 32 | |
| 33 | + |
31 | 34 | class SeleniumTester extends Maintenance { |
| 35 | + protected $selenium; |
| 36 | + |
32 | 37 | public function __construct() { |
33 | 38 | parent::__construct(); |
34 | 39 | |
— | — | @@ -45,27 +50,25 @@ |
46 | 51 | } |
47 | 52 | |
48 | 53 | public function listBrowsers() { |
49 | | - global $wgSeleniumTestsBrowsers; |
| 54 | + $desc = "Available browsers:\n"; |
50 | 55 | |
51 | | - $desc = "Available browsers:\n"; |
52 | | - foreach ($wgSeleniumTestsBrowsers as $k => $v) { |
| 56 | + $sel = new Selenium; |
| 57 | + foreach ($sel->setupBrowsers() as $k => $v) { |
53 | 58 | $desc .= " $k => $v\n"; |
54 | 59 | } |
55 | 60 | |
56 | 61 | echo $desc; |
57 | 62 | } |
58 | 63 | |
59 | | - protected function runTests( $verbose = false ) { |
60 | | - global $wgSeleniumLogger, $wgSeleniumTestSuites; |
| 64 | + protected function getTestSuites() { |
| 65 | + return array( 'SimpleSeleniumTestSuite' ); |
| 66 | + } |
61 | 67 | |
62 | | - require_once( 'Testing/Selenium.php' ); |
63 | | - require_once( 'PHPUnit/Framework.php' ); |
64 | | - require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); |
| 68 | + protected function runTests( ) { |
65 | 69 | $result = new PHPUnit_Framework_TestResult; |
66 | | - $wgSeleniumLogger = new SeleniumTestConsoleLogger; |
67 | | - $result->addListener( new SeleniumTestListener( $wgSeleniumLogger ) ); |
| 70 | + $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) ); |
68 | 71 | |
69 | | - foreach ( $wgSeleniumTestSuites as $testSuiteName ) { |
| 72 | + foreach ( $this->getTestSuites() as $testSuiteName ) { |
70 | 73 | $suite = new $testSuiteName; |
71 | 74 | $suite->addTests(); |
72 | 75 | try { |
— | — | @@ -77,20 +80,29 @@ |
78 | 81 | } |
79 | 82 | |
80 | 83 | public function execute() { |
81 | | - global $wgSeleniumServerPort, $wgSeleniumTestsSeleniumHost, |
82 | | - $wgSeleniumTestsWikiUrl, $wgServer, $wgScriptPath; |
| 84 | + global $wgServer, $wgScriptPath; |
83 | 85 | |
| 86 | + /** |
| 87 | + * @todo Add an alternative where settings are read from an INI file. |
| 88 | + */ |
| 89 | + $this->selenium = new Selenium( ); |
| 90 | + $this->selenium->setUrl( $this->getOption( 'url', $wgServer . $wgScriptPath ) ); |
| 91 | + $this->selenium->setBrowser( $this->getOption( 'browser', 'firefox' ) ); |
| 92 | + $this->selenium->setPort( $this->getOption( 'port', 4444 ) ); |
| 93 | + $this->selenium->setHost( $this->getOption( 'host', 'localhost' ) ); |
| 94 | + $this->selenium->setUser( $this->getOption( 'user', 'WikiSysop' ) ); |
| 95 | + $this->selenium->setPass( $this->getOption( 'pass', 'Password' ) ); |
| 96 | + $this->selenium->setVerbose( $this->hasOption( 'verbose' ) ); |
| 97 | + |
84 | 98 | if( $this->hasOption( 'list-browsers' ) ) { |
85 | 99 | $this->listBrowsers(); |
86 | 100 | exit(0); |
87 | 101 | } |
88 | 102 | |
89 | | - $wgSeleniumServerPort = $this->getOption( 'port', 4444 ); |
90 | | - $wgSeleniumTestsSeleniumHost = $this->getOption( 'host', 'localhost' ); |
91 | | - $wgSeleniumTestsWikiUrl = $this->getOption( 'url', $wgServer . $wgScriptPath ); |
92 | | - $wgSeleniumTestsUseBrowser = $this->getOption( 'browser', 'firefox' ); |
| 103 | + $logger = new SeleniumTestConsoleLogger; |
| 104 | + $this->selenium->setLogger( $logger ); |
93 | 105 | |
94 | | - $this->runTests( $this->hasOption( 'verbose' ) ); |
| 106 | + $this->runTests( ); |
95 | 107 | } |
96 | 108 | } |
97 | 109 | |
Index: trunk/phase3/maintenance/tests/selenium/Selenium.php |
— | — | @@ -4,49 +4,76 @@ |
5 | 5 | * This is implemented as a singleton. |
6 | 6 | */ |
7 | 7 | |
8 | | -class Selenium extends Testing_Selenium { |
| 8 | +require( 'Testing/Selenium.php' ); |
| 9 | +class Selenium { |
9 | 10 | protected static $_instance = null; |
10 | 11 | public $isStarted = false; |
| 12 | + public $tester; |
11 | 13 | |
12 | | - public static function getInstance() { |
13 | | - global $wgSeleniumTestsBrowsers, $wgSeleniumTestsSeleniumHost, $wgSeleniumTestsUseBrowser; |
14 | | - global $wgSeleniumServerPort, $wgSeleniumLogger; |
| 14 | + protected $port; |
| 15 | + protected $host; |
| 16 | + protected $browser; |
| 17 | + protected $browsers; |
| 18 | + protected $logger; |
| 19 | + protected $user; |
| 20 | + protected $pass; |
| 21 | + protected $timeout = 30000; |
| 22 | + protected $verbose; |
15 | 23 | |
| 24 | + /** |
| 25 | + * @todo this shouldn't have to be static |
| 26 | + */ |
| 27 | + static protected $url; |
| 28 | + |
| 29 | + /** |
| 30 | + * Override parent |
| 31 | + */ |
| 32 | + public function __construct() { |
| 33 | + /** |
| 34 | + * @todo this is an ugly hack to make information available to |
| 35 | + * other tests. It should be fixed. |
| 36 | + */ |
16 | 37 | if ( null === self::$_instance ) { |
17 | | - $wgSeleniumLogger->write( "Browser: " . $wgSeleniumTestsBrowsers[$wgSeleniumTestsUseBrowser] ); |
18 | | - self::$_instance = new self( $wgSeleniumTestsBrowsers[$wgSeleniumTestsUseBrowser], |
19 | | - self::getBaseUrl(), |
20 | | - $wgSeleniumTestsSeleniumHost, |
21 | | - $wgSeleniumServerPort ); |
| 38 | + self::$_instance = $this; |
| 39 | + } else { |
| 40 | + throw new MWException("Already have one Selenium instance."); |
22 | 41 | } |
23 | | - return self::$_instance; |
24 | 42 | } |
25 | 43 | |
26 | 44 | public function start() { |
27 | | - parent::start(); |
| 45 | + $this->tester = new Testing_Selenium( $this->browser, self::$url, $this->host, |
| 46 | + $this->port, $this->timeout ); |
| 47 | + if ( method_exists( $this->tester, "setVerbose" ) ) $this->tester->setVerbose( $this->verbose ); |
| 48 | + |
| 49 | + $this->tester->start(); |
28 | 50 | $this->isStarted = true; |
29 | 51 | } |
30 | 52 | |
31 | 53 | public function stop() { |
32 | | - parent::stop(); |
| 54 | + $this->tester->stop(); |
| 55 | + $this->tester = null; |
33 | 56 | $this->isStarted = false; |
34 | 57 | } |
35 | 58 | |
36 | | - static function getBaseUrl() { |
37 | | - global $wgSeleniumTestsWikiUrl, $wgServer, $wgScriptPath; |
38 | | - if ( $wgSeleniumTestsWikiUrl ) { |
39 | | - return $wgSeleniumTestsWikiUrl; |
40 | | - } else { |
41 | | - return $wgServer . $wgScriptPath; |
| 59 | + protected function setupBrowsers() { |
| 60 | + /** |
| 61 | + * @todo This needs to be replaced with something not hard |
| 62 | + * coded. This would be entries in a .ini file or |
| 63 | + * screen-scraping |
| 64 | + * http://grid.tesla.usability.wikimedia.org:4444/console for |
| 65 | + * example. |
| 66 | + */ |
| 67 | + return array( |
| 68 | + 'firefox' => 'Firefox 3.5 on Linux', |
| 69 | + 'iexplorer' => '*iexploreproxy', |
| 70 | + 'chrome' => '*googlechrome', |
| 71 | + ); |
42 | 72 | } |
43 | | - } |
44 | 73 | |
45 | 74 | public function login() { |
46 | | - global $wgSeleniumTestsWikiUser, $wgSeleniumTestsWikiPassword; |
47 | | - |
48 | | - $this->open( self::getBaseUrl() . '/index.php?title=Special:Userlogin' ); |
49 | | - $this->type( 'wpName1', $wgSeleniumTestsWikiUser ); |
50 | | - $this->type( 'wpPassword1', $wgSeleniumTestsWikiPassword ); |
| 75 | + $this->open( self::$url . '/index.php?title=Special:Userlogin' ); |
| 76 | + $this->type( 'wpName1', $this->user ); |
| 77 | + $this->type( 'wpPassword1', $this->pass ); |
51 | 78 | $this->click( "//input[@id='wpLoginAttempt']" ); |
52 | 79 | $this->waitForPageToLoad(5000); |
53 | 80 | //after login we redirect to the main page. So check whether the "Prefernces" top menu item exists |
— | — | @@ -57,18 +84,71 @@ |
58 | 85 | |
59 | 86 | } |
60 | 87 | |
| 88 | + public static function getInstance() { |
| 89 | + if ( null === self::$_instance ) { |
| 90 | + throw new MWException( "No instance set yet" ); |
| 91 | + } |
| 92 | + |
| 93 | + return self::$_instance; |
| 94 | + } |
| 95 | + |
61 | 96 | public function loadPage( $title, $action ) { |
62 | | - $this->open( self::getBaseUrl() . '/index.php?title=' . $title . '&action=' . $action ); |
| 97 | + $this->open( self::$url . '/index.php?title=' . $title . '&action=' . $action ); |
63 | 98 | } |
64 | 99 | |
65 | | - /* |
66 | | - * Log to console or html depending on the value of $wgSeleniumTestsRunMode |
67 | | - */ |
| 100 | + public function setLogger( $logger ) { |
| 101 | + $this->logger = $logger; |
| 102 | + } |
| 103 | + |
| 104 | + public function getLogger( ) { |
| 105 | + return $this->logger; |
| 106 | + } |
| 107 | + |
68 | 108 | public function log( $message ) { |
69 | | - global $wgSeleniumLogger; |
70 | | - $wgSeleniumLogger->write( $message ); |
| 109 | + $this->logger->write( $message ); |
71 | 110 | } |
72 | 111 | |
| 112 | + public function setUrl( $url ) { |
| 113 | + self::$url = $url; |
| 114 | + } |
| 115 | + |
| 116 | + static public function getUrl() { |
| 117 | + return self::$url; |
| 118 | + } |
| 119 | + |
| 120 | + public function setPort( $port ) { |
| 121 | + $this->port = $port; |
| 122 | + } |
| 123 | + |
| 124 | + public function setUser( $user ) { |
| 125 | + $this->user = $user; |
| 126 | + } |
| 127 | + |
| 128 | + public function setPass( $pass ) { |
| 129 | + $this->pass = $pass; |
| 130 | + } |
| 131 | + |
| 132 | + public function setHost( $host ) { |
| 133 | + $this->host = $host; |
| 134 | + } |
| 135 | + |
| 136 | + public function setVerbose( $verbose ) { |
| 137 | + $this->verbose = $verbose; |
| 138 | + } |
| 139 | + |
| 140 | + public function setBrowser( $b ) { |
| 141 | + $browsers = $this->setupBrowsers(); |
| 142 | + if ( !isset( $browsers[$b] ) ) { |
| 143 | + throw new MWException( "Invalid Browser: $b.\n" ); |
| 144 | + } |
| 145 | + $this->browser = $browsers[$b]; |
| 146 | + } |
| 147 | + |
| 148 | + public function __call( $name, $args ) { |
| 149 | + $t = call_user_func_array( array( $this->tester, $name), $args ); |
| 150 | + return $t; |
| 151 | + } |
| 152 | + |
73 | 153 | // Prevent external cloning |
74 | 154 | protected function __clone() { } |
75 | 155 | // Prevent external construction |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3719,50 +3719,6 @@ |
3720 | 3720 | */ |
3721 | 3721 | $wgParserTestRemote = false; |
3722 | 3722 | |
3723 | | -/** |
3724 | | - * Enable Selenium test framework. |
3725 | | - * This enables maintenance/tests/RunSeleniumTests.php and [[Special:Selenium]]. |
3726 | | - */ |
3727 | | -$wgEnableSelenium = false; |
3728 | | - |
3729 | | -/** List of Selenium test suites. These must be registered with the autoloader. */ |
3730 | | -$wgSeleniumTestSuites = array( |
3731 | | - 'SimpleSeleniumTestSuite' |
3732 | | -); |
3733 | | - |
3734 | | - |
3735 | | -/** Hostname of selenium server */ |
3736 | | -$wgSeleniumTestsSeleniumHost = 'localhost'; |
3737 | | - |
3738 | | -/** URL of the wiki to be tested. By default, the local wiki is used. */ |
3739 | | -$wgSeleniumTestsWikiUrl = false; |
3740 | | - |
3741 | | -/** Port used by selenium server. */ |
3742 | | -$wgSeleniumServerPort = 4444; |
3743 | | - |
3744 | | -/** Wiki login username. Used by Selenium to log onto the wiki. */ |
3745 | | -$wgSeleniumTestsWikiUser = 'Wikiuser'; |
3746 | | - |
3747 | | -/** Wiki login password. Used by Selenium to log onto the wiki. */ |
3748 | | -$wgSeleniumTestsWikiPassword = ''; |
3749 | | - |
3750 | | -/** |
3751 | | - * Common browsers on Windows platform. Modify for other platforms or |
3752 | | - * other Windows browsers. |
3753 | | - * Use the *chrome handler in order to be able to test file uploads. |
3754 | | - * 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/ |
3755 | | - */ |
3756 | | -$wgSeleniumTestsBrowsers = array( |
3757 | | - 'firefox' => '*firefox /usr/bin/firefox', |
3758 | | - 'iexplorer' => '*iexploreproxy', |
3759 | | - 'opera' => '*chrome /usr/bin/opera', |
3760 | | -); |
3761 | | - |
3762 | | -/** Actually, use this browser */ |
3763 | | -$wgSeleniumTestsUseBrowser = 'firefox'; |
3764 | | - |
3765 | | - |
3766 | | - |
3767 | 3723 | /** @} */ # end of profiling, testing and debugging } |
3768 | 3724 | |
3769 | 3725 | /************************************************************************//** |
Index: trunk/phase3/includes/specials/SpecialSelenium.php |
— | — | @@ -1,72 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Implements Special:Selenium |
5 | | - * |
6 | | - * @file |
7 | | - * @ingroup SpecialPage |
8 | | - * @todo Remove this feature |
9 | | - */ |
10 | | - |
11 | | -/** |
12 | | - * @ingroup SpecialPage |
13 | | - */ |
14 | | -class SpecialSelenium extends SpecialPage { |
15 | | - function __construct() { |
16 | | - parent::__construct( 'Selenium', 'selenium', false ); |
17 | | - } |
18 | | - |
19 | | - function getDescription() { |
20 | | - return 'Selenium'; |
21 | | - } |
22 | | - |
23 | | - function execute( $par ) { |
24 | | - global $wgUser, $wgOut, $wgEnableSelenium, $wgRequest; |
25 | | - |
26 | | - if ( !$wgEnableSelenium ) { |
27 | | - throw new MWException( |
28 | | - 'Selenium special page invoked when it should not be registered!' ); |
29 | | - } |
30 | | - |
31 | | - $this->setHeaders(); |
32 | | - if ( !$this->userCanExecute( $wgUser ) ) { |
33 | | - $this->displayRestrictionError(); |
34 | | - return; |
35 | | - } |
36 | | - |
37 | | - if ( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) { |
38 | | - $this->runTests(); |
39 | | - } |
40 | | - $wgOut->addHTML( |
41 | | - Html::openElement( 'form', array( |
42 | | - 'method' => 'POST', |
43 | | - 'action' => $this->getTitle()->getLocalUrl(), |
44 | | - ) ) . |
45 | | - Html::input( 'submit', 'Run tests', 'submit' ) . |
46 | | - Html::hidden( 'token', $wgUser->editToken() ) . |
47 | | - '</form>' |
48 | | - ); |
49 | | - } |
50 | | - |
51 | | - function runTests() { |
52 | | - global $wgSeleniumTestSuites, $wgOut, $wgSeleniumLogger; |
53 | | - SeleniumLoader::load(); |
54 | | - |
55 | | - $result = new PHPUnit_Framework_TestResult; |
56 | | - $wgSeleniumLogger = new SeleniumTestHTMLLogger; |
57 | | - $result->addListener( new SeleniumTestListener( $wgSeleniumLogger ) ); |
58 | | - //$wgSeleniumLogger->setHeaders(); |
59 | | - |
60 | | - // run tests |
61 | | - $wgOut->addHTML( '<div class="selenium">' ); |
62 | | - |
63 | | - // for some really strange reason, foreach doesn't work here. It produces an infinite loop, |
64 | | - // executing only the first test suite. |
65 | | - for ( $i = 0; $i < count( $wgSeleniumTestSuites ); $i++ ) { |
66 | | - $suite = new $wgSeleniumTestSuites[$i]; |
67 | | - $suite->addTests(); |
68 | | - $suite->run( $result ); |
69 | | - } |
70 | | - $wgOut->addHTML( '</div>' ); |
71 | | - } |
72 | | -} |
73 | | - |
Index: trunk/phase3/includes/SpecialPage.php |
— | — | @@ -207,7 +207,6 @@ |
208 | 208 | static function initList() { |
209 | 209 | global $wgSpecialPages; |
210 | 210 | global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication; |
211 | | - global $wgEnableSelenium; |
212 | 211 | |
213 | 212 | if ( self::$mListInitialised ) { |
214 | 213 | return; |
— | — | @@ -230,10 +229,6 @@ |
231 | 230 | self::$mList['Invalidateemail'] = 'EmailInvalidation'; |
232 | 231 | } |
233 | 232 | |
234 | | - if ( $wgEnableSelenium ) { |
235 | | - self::$mList['Selenium'] = 'SpecialSelenium'; |
236 | | - } |
237 | | - |
238 | 233 | # Add extension special pages |
239 | 234 | self::$mList = array_merge( self::$mList, $wgSpecialPages ); |
240 | 235 | |