. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @category Testing * @package PHPUnit * @author Sebastian Bergmann * @copyright 2002-2008 Sebastian Bergmann * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version SVN: $Id: SeleniumTestCase.php 2111 2008-01-15 09:55:15Z sb $ * @link http://www.phpunit.de/ * @since File available since Release 3.0.0 */ require_once 'PHPUnit/Framework.php'; require_once 'PHPUnit/Util/Log/Database.php'; require_once 'PHPUnit/Util/Filter.php'; require_once 'PHPUnit/Util/Test.php'; require_once 'PHPUnit/Util/XML.php'; PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); /** * TestCase class that uses Selenium to provide * the functionality required for web testing. * * @category Testing * @package PHPUnit * @author Sebastian Bergmann * @copyright 2002-2008 Sebastian Bergmann * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: 3.2.9 * @link http://www.phpunit.de/ * @since Class available since Release 3.0.0 */ abstract class PHPUnit_Extensions_SeleniumTestCase extends PHPUnit_Framework_TestCase { /** * @var array * @access public * @static */ public static $browsers = array(); /** * @var string * @access protected */ protected $browser; /** * @var string * @access protected */ protected $browserName; /** * @var string * @access protected */ protected $browserUrl; /** * @var string * @access protected */ protected $host = 'localhost'; /** * @var integer * @access protected */ protected $port = 4444; /** * @var integer * @access protected */ protected $timeout = 30000; /** * @var array * @access protected */ protected static $sessionId = array(); /** * @var integer * @access protected */ protected $sleep = 0; /** * @var boolean * @access protected */ protected $autoStop = TRUE; /** * @var boolean * @access protected */ protected $collectCodeCoverageInformation = FALSE; /** * @var string * @access protected */ protected $coverageScriptUrl = ''; /** * @var string * @access protected */ protected $testId; /** * @var boolean * @access protected */ protected $inDefaultAssertions = FALSE; /** * @param string $name * @param array $browser * @throws InvalidArgumentException * @access public */ public function __construct($name = NULL, array $data = array(), array $browser = array()) { parent::__construct($name, $data); if (isset($browser['name'])) { if (! is_string($browser['name'])) { throw new InvalidArgumentException(); } } else { $browser['name'] = ''; } if (isset($browser['browser'])) { if (! is_string($browser['browser'])) { throw new InvalidArgumentException(); } } else { $browser['browser'] = ''; } if (isset($browser['host'])) { if (! is_string($browser['host'])) { throw new InvalidArgumentException(); } } else { $browser['host'] = 'localhost'; } if (isset($browser['port'])) { if (! is_int($browser['port'])) { throw new InvalidArgumentException(); } } else { $browser['port'] = 4444; } if (isset($browser['timeout'])) { if (! is_int($browser['timeout'])) { throw new InvalidArgumentException(); } } else { $browser['timeout'] = 30000; } $this->browserName = $browser['name']; $this->browser = $browser['browser']; $this->host = $browser['host']; $this->port = $browser['port']; $this->timeout = $browser['timeout']; } /** * @param string $className * @return PHPUnit_Framework_TestSuite * @access public */ public static function suite($className) { $suite = new PHPUnit_Framework_TestSuite(); $suite->setName($className); $class = new ReflectionClass($className); $classGroups = PHPUnit_Util_Test::getGroups($class); $staticProperties = $class->getStaticProperties(); // Create tests from Selenese/HTML files. if (isset($staticProperties['seleneseDirectory']) && is_dir($staticProperties['seleneseDirectory'])) { $files = new PHPUnit_Util_FilterIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($staticProperties['seleneseDirectory'])), '.htm'); // Create tests from Selenese/HTML files for multiple browsers. if (! empty($staticProperties['browsers'])) { foreach ($staticProperties['browsers'] as $browser) { $browserSuite = new PHPUnit_Framework_TestSuite(); $browserSuite->setName($className . ': ' . $browser['name']); foreach ($files as $file) { $browserSuite->addTest(new $className((string)$file, array(), $browser)); } $suite->addTest($browserSuite, $classGroups); } } // Create tests from Selenese/HTML files for single browser. else { foreach ($files as $file) { $suite->addTest(new $className((string)$file), $classGroups); } } } // Create tests from test methods for multiple browsers. if (! empty($staticProperties['browsers'])) { foreach ($staticProperties['browsers'] as $browser) { $browserSuite = new PHPUnit_Framework_TestSuite(); $browserSuite->setName($className . ': ' . $browser['name']); foreach ($class->getMethods() as $method) { if (PHPUnit_Framework_TestSuite::isPublicTestMethod($method)) { $name = $method->getName(); $data = PHPUnit_Util_Test::getProvidedData($className, $name); $groups = PHPUnit_Util_Test::getGroups($method, $classGroups); // Test method with @dataProvider. if (is_array($data) || $data instanceof Iterator) { $dataSuite = new PHPUnit_Framework_TestSuite($className . '::' . $name); foreach ($data as $_data) { $dataSuite->addTest(new $className($name, $_data, $browser), $groups); } $browserSuite->addTest($dataSuite); } // Test method without @dataProvider. else { $browserSuite->addTest(new $className($name, array(), $browser), $groups); } } } $suite->addTest($browserSuite); } } // Create tests from test methods for single browser. else { foreach ($class->getMethods() as $method) { if (PHPUnit_Framework_TestSuite::isPublicTestMethod($method)) { $name = $method->getName(); $data = PHPUnit_Util_Test::getProvidedData($className, $name); $groups = PHPUnit_Util_Test::getGroups($method, $classGroups); // Test method with @dataProvider. if (is_array($data) || $data instanceof Iterator) { $dataSuite = new PHPUnit_Framework_TestSuite($className . '::' . $name); foreach ($data as $_data) { $dataSuite->addTest(new $className($name, $_data), $groups); } $suite->addTest($dataSuite); } // Test method without @dataProvider. else { $suite->addTest(new $className($name), $groups); } } } } return $suite; } /** * Runs the test case and collects the results in a TestResult object. * If no TestResult object is passed a new one will be created. * * @param PHPUnit_Framework_TestResult $result * @return PHPUnit_Framework_TestResult * @throws InvalidArgumentException * @access public */ public function run(PHPUnit_Framework_TestResult $result = NULL) { if ($result === NULL) { $result = $this->createResult(); } $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation(); $result->run($this); if ($this->collectCodeCoverageInformation) { $result->appendCodeCoverageInformation($this, $this->getCodeCoverage()); } return $result; } /** * @access protected */ protected function runTest() { $this->start(); if (! is_file($this->name)) { parent::runTest(); } else { $this->runSelenese($this->name); } if ($this->autoStop) { try { $this->stop(); } catch (RuntimeException $e) {} } } /** * If you want to override tearDown() make sure to either call stop() or * parent::tearDown(). Otherwise the Selenium RC session will not be * closed upon test failure. * * @access protected */ protected function tearDown() { if ($this->autoStop) { try { $this->stop(); } catch (RuntimeException $e) {} } } /** * Returns a string representation of the test case. * * @return string * @access public */ public function toString() { $buffer = parent::toString(); if (! empty($this->browserName)) { $buffer .= ' with browser ' . $this->browserName; } return $buffer; } /** * @return string * @access public */ public function start() { if (! isset(self::$sessionId[$this->host][$this->port][$this->browser])) { self::$sessionId[$this->host][$this->port][$this->browser] = $this->getString('getNewBrowserSession', array( $this->browser, $this->browserUrl)); $this->doCommand('setTimeout', array($this->timeout)); } $this->testId = md5(uniqid(rand(), TRUE)); return self::$sessionId[$this->host][$this->port][$this->browser]; } /** * @access public */ public function stop() { if (! isset(self::$sessionId[$this->host][$this->port][$this->browser])) { return; } $this->doCommand('testComplete'); unset(self::$sessionId[$this->host][$this->port][$this->browser]); } /** * @param boolean $autoStop * @throws InvalidArgumentException * @access public */ public function setAutoStop($autoStop) { if (! is_bool($autoStop)) { throw new InvalidArgumentException(); } $this->autoStop = $autoStop; } /** * @param string $browser * @throws InvalidArgumentException * @access public */ public function setBrowser($browser) { if (! is_string($browser)) { throw new InvalidArgumentException(); } $this->browser = $browser; } /** * @param string $browserUrl * @throws InvalidArgumentException * @access public */ public function setBrowserUrl($browserUrl) { if (! is_string($browserUrl)) { throw new InvalidArgumentException(); } $this->browserUrl = $browserUrl; } /** * @param string $host * @throws InvalidArgumentException * @access public */ public function setHost($host) { if (! is_string($host)) { throw new InvalidArgumentException(); } $this->host = $host; } /** * @param integer $port * @throws InvalidArgumentException * @access public */ public function setPort($port) { if (! is_int($port)) { throw new InvalidArgumentException(); } $this->port = $port; } /** * @param integer $timeout * @throws InvalidArgumentException * @access public */ public function setTimeout($timeout) { if (! is_int($timeout)) { throw new InvalidArgumentException(); } $this->timeout = $timeout; } /** * @param integer $seconds * @throws InvalidArgumentException * @access public */ public function setSleep($seconds) { if (! is_int($seconds)) { throw new InvalidArgumentException(); } $this->sleep = $seconds; } /** * Runs a test from a Selenese (HTML) specification. * * @param string $filename * @access public */ public function runSelenese($filename) { $document = PHPUnit_Util_XML::load($filename, TRUE); $xpath = new DOMXPath($document); $rows = $xpath->query('body/table/tbody/tr'); foreach ($rows as $row) { $action = NULL; $arguments = array(); $columns = $xpath->query('td', $row); foreach ($columns as $column) { if ($action === NULL) { $action = $column->nodeValue; } else { $arguments[] = $column->nodeValue; } } $this->__call($action, $arguments); } } /** * This method implements the Selenium RC protocol. * * @param string $command * @param array $arguments * @return mixed * @access public * @method unknown addLocationStrategy() * @method unknown addSelection() * @method unknown allowNativeXpath() * @method unknown altKeyDown() * @method unknown altKeyUp() * @method unknown answerOnNextPrompt() * @method unknown assignId() * @method unknown captureScreenshot() * @method unknown check() * @method unknown chooseCancelOnNextConfirmation() * @method unknown click() * @method unknown clickAndWait() * @method unknown clickAt() * @method unknown close() * @method unknown controlKeyDown() * @method unknown controlKeyUp() * @method unknown createCookie() * @method unknown deleteCookie() * @method unknown doubleClick() * @method unknown doubleClickAt() * @method unknown dragAndDrop() * @method unknown dragAndDropToObject() * @method unknown dragDrop() * @method unknown fireEvent() * @method string getAlert() * @method array getAllButtons() * @method array getAllFields() * @method array getAllLinks() * @method array getAllWindowIds() * @method array getAllWindowNames() * @method array getAllWindowTitles() * @method string getAttribute() * @method array getAttributeFromAllWindows() * @method string getBodyText() * @method string getConfirmation() * @method string getCookie() * @method integer getCursorPosition() * @method integer getElementHeight() * @method integer getElementIndex() * @method integer getElementPositionLeft() * @method integer getElementPositionTop() * @method integer getElementWidth() * @method string getEval() * @method string getExpression() * @method string getHtmlSource() * @method string getLocation() * @method string getLogMessages() * @method integer getMouseSpeed() * @method string getPrompt() * @method array getSelectOptions() * @method string getSelectedId() * @method array getSelectedIds() * @method string getSelectedIndex() * @method array getSelectedIndexes() * @method string getSelectedLabel() * @method array getSelectedLabels() * @method string getSelectedValue() * @method array getSelectedValues() * @method unknown getSpeed() * @method string getTable() * @method string getText() * @method string getTitle() * @method string getValue() * @method boolean getWhetherThisFrameMatchFrameExpression() * @method boolean getWhetherThisWindowMatchWindowExpression() * @method integer getXpathCount() * @method unknown goBack() * @method unknown highlight() * @method boolean isAlertPresent() * @method boolean isChecked() * @method boolean isConfirmationPresent() * @method boolean isEditable() * @method boolean isElementPresent() * @method boolean isOrdered() * @method boolean isPromptPresent() * @method boolean isSomethingSelected() * @method boolean isTextPresent() * @method boolean isVisible() * @method unknown keyDown() * @method unknown keyPress() * @method unknown keyUp() * @method unknown metaKeyDown() * @method unknown metaKeyUp() * @method unknown mouseDown() * @method unknown mouseDownAt() * @method unknown mouseMove() * @method unknown mouseMoveAt() * @method unknown mouseOut() * @method unknown mouseOver() * @method unknown mouseUp() * @method unknown mouseUpAt() * @method unknown open() * @method unknown openWindow() * @method unknown refresh() * @method unknown removeAllSelections() * @method unknown removeSelection() * @method unknown select() * @method unknown selectFrame() * @method unknown selectWindow() * @method unknown setContext() * @method unknown setCursorPosition() * @method unknown setMouseSpeed() * @method unknown setSpeed() * @method unknown shiftKeyDown() * @method unknown shiftKeyUp() * @method unknown submit() * @method unknown type() * @method unknown typeKeys() * @method unknown uncheck() * @method unknown waitForCondition() * @method unknown waitForPageToLoad() * @method unknown waitForPopUp() * @method unknown windowFocus() * @method unknown windowMaximize() */ public function __call($command, $arguments) { switch ($command) { case 'addLocationStrategy': case 'addSelection': case 'allowNativeXpath': case 'altKeyDown': case 'altKeyUp': case 'answerOnNextPrompt': case 'assignId': case 'captureScreenshot': case 'check': case 'chooseCancelOnNextConfirmation': case 'click': case 'clickAt': case 'close': case 'controlKeyDown': case 'controlKeyUp': case 'createCookie': case 'deleteCookie': case 'doubleClick': case 'doubleClickAt': case 'dragAndDrop': case 'dragAndDropToObject': case 'dragDrop': case 'fireEvent': case 'goBack': case 'highlight': case 'keyDown': case 'keyPress': case 'keyUp': case 'metaKeyDown': case 'metaKeyUp': case 'mouseDown': case 'mouseDownAt': case 'mouseMove': case 'mouseMoveAt': case 'mouseOut': case 'mouseOver': case 'mouseUp': case 'mouseUpAt': case 'open': case 'openWindow': case 'refresh': case 'removeAllSelections': case 'removeSelection': case 'select': case 'selectFrame': case 'selectWindow': case 'setContext': case 'setCursorPosition': case 'setMouseSpeed': case 'setSpeed': case 'shiftKeyDown': case 'shiftKeyUp': case 'submit': case 'type': case 'typeKeys': case 'uncheck': case 'windowFocus': case 'windowMaximize': { // Pre-Command Actions switch ($command) { case 'open': case 'openWindow': { if ($this->collectCodeCoverageInformation) { $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', '/'); $this->createCookie('PHPUNIT_SELENIUM_TEST_ID=' . $this->testId, 'path=/'); } } break; } $this->doCommand($command, $arguments); // Post-Command Actions switch ($command) { case 'addLocationStrategy': case 'allowNativeXpath': case 'assignId': case 'captureScreenshot': { // intentionally empty } break; default: { if ($this->sleep > 0) { sleep($this->sleep); } $this->runDefaultAssertions($command); } } } break; case 'getWhetherThisFrameMatchFrameExpression': case 'getWhetherThisWindowMatchWindowExpression': case 'isAlertPresent': case 'isChecked': case 'isConfirmationPresent': case 'isEditable': case 'isElementPresent': case 'isOrdered': case 'isPromptPresent': case 'isSomethingSelected': case 'isTextPresent': case 'isVisible': { return $this->getBoolean($command, $arguments); } break; case 'getCursorPosition': case 'getElementHeight': case 'getElementIndex': case 'getElementPositionLeft': case 'getElementPositionTop': case 'getElementWidth': case 'getMouseSpeed': case 'getSpeed': case 'getXpathCount': { return $this->getNumber($command, $arguments); } break; case 'getAlert': case 'getAttribute': case 'getBodyText': case 'getConfirmation': case 'getCookie': case 'getEval': case 'getExpression': case 'getHtmlSource': case 'getLocation': case 'getLogMessages': case 'getPrompt': case 'getSelectedId': case 'getSelectedIndex': case 'getSelectedLabel': case 'getSelectedValue': case 'getTable': case 'getText': case 'getTitle': case 'getValue': { return $this->getString($command, $arguments); } break; case 'getAllButtons': case 'getAllFields': case 'getAllLinks': case 'getAllWindowIds': case 'getAllWindowNames': case 'getAllWindowTitles': case 'getAttributeFromAllWindows': case 'getSelectedIds': case 'getSelectedIndexes': case 'getSelectedLabels': case 'getSelectedValues': case 'getSelectOptions': { return $this->getStringArray($command, $arguments); } break; case 'clickAndWait': { $this->doCommand('click', $arguments); $this->doCommand('waitForPageToLoad', array($this->timeout)); if ($this->sleep > 0) { sleep($this->sleep); } $this->runDefaultAssertions($command); } break; case 'waitForCondition': case 'waitForPopUp': { if (count($arguments) == 1) { $arguments[] = $this->timeout; } $this->doCommand($command, $arguments); $this->runDefaultAssertions($command); } break; case 'waitForPageToLoad': { if (empty($arguments)) { $arguments[] = $this->timeout; } $this->doCommand($command, $arguments); $this->runDefaultAssertions($command); } break; default: { $this->stop(); throw new BadMethodCallException("Method $command not defined."); } } } /** * Asserts that an alert is present. * * @param string $message * @access public */ public function assertAlertPresent($message = 'No alert present.') { $this->assertTrue($this->isAlertPresent(), $message); } /** * Asserts that no alert is present. * * @param string $message * @access public */ public function assertNoAlertPresent($message = 'Alert present.') { $this->assertFalse($this->isAlertPresent(), $message); } /** * Asserts that an option is checked. * * @param string $locator * @param string $message * @access public */ public function assertChecked($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" not checked.', $locator); } $this->assertTrue($this->isChecked($locator), $message); } /** * Asserts that an option is not checked. * * @param string $locator * @param string $message * @access public */ public function assertNotChecked($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" checked.', $locator); } $this->assertFalse($this->isChecked($locator), $message); } /** * Assert that a confirmation is present. * * @param string $message * @access public */ public function assertConfirmationPresent($message = 'No confirmation present.') { $this->assertTrue($this->isConfirmationPresent(), $message); } /** * Assert that no confirmation is present. * * @param string $message * @access public */ public function assertNoConfirmationPresent($message = 'Confirmation present.') { $this->assertFalse($this->isConfirmationPresent(), $message); } /** * Asserts that an input field is editable. * * @param string $locator * @param string $message * @access public */ public function assertEditable($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" not editable.', $locator); } $this->assertTrue($this->isEditable($locator), $message); } /** * Asserts that an input field is not editable. * * @param string $locator * @param string $message * @access public */ public function assertNotEditable($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" editable.', $locator); } $this->assertFalse($this->isEditable($locator), $message); } /** * Asserts that an element's value is equal to a given string. * * @param string $locator * @param string $text * @param string $message * @access public */ public function assertElementValueEquals($locator, $text, $message = '') { $this->assertEquals($text, $this->getValue($locator), $message); } /** * Asserts that an element's value is not equal to a given string. * * @param string $locator * @param string $text * @param string $message * @access public */ public function assertElementValueNotEquals($locator, $text, $message = '') { $this->assertNotEquals($text, $this->getValue($locator), $message); } /** * Asserts that an element contains a given string. * * @param string $locator * @param string $text * @param string $message * @access public */ public function assertElementContainsText($locator, $text, $message = '') { $this->assertContains($text, $this->getValue($locator), $message); } /** * Asserts that an element does not contain a given string. * * @param string $locator * @param string $text * @param string $message * @access public */ public function assertElementNotContainsText($locator, $text, $message = '') { $this->assertNotContains($text, $this->getValue($locator), $message); } /** * Asserts than an element is present. * * @param string $locator * @param string $message * @access public */ public function assertElementPresent($locator, $message = '') { if ($message == '') { $message = sprintf('Element "%s" not present.', $locator); } $this->assertTrue($this->isElementPresent($locator), $message); } /** * Asserts than an element is not present. * * @param string $locator * @param string $message * @access public */ public function assertElementNotPresent($locator, $message = '') { if ($message == '') { $message = sprintf('Element "%s" present.', $locator); } $this->assertFalse($this->isElementPresent($locator), $message); } /** * Asserts that the location is equal to a specified one. * * @param string $location * @param string $message * @access public */ public function assertLocationEquals($location, $message = '') { $this->assertEquals($location, $this->getLocation(), $message); } /** * Asserts that the location is not equal to a specified one. * * @param string $location * @param string $message * @access public */ public function assertLocationNotEquals($location, $message = '') { $this->assertNotEquals($location, $this->getLocation(), $message); } /** * Asserts than a prompt is present. * * @param string $message * @access public */ public function assertPromptPresent($message = 'No prompt present.') { $this->assertTrue($this->isPromptPresent(), $message); } /** * Asserts than no prompt is present. * * @param string $message * @access public */ public function assertNoPromptPresent($message = 'Prompt present.') { $this->assertFalse($this->isPromptPresent(), $message); } /** * Asserts that a select element has a specific option. * * @param string $selectLocator * @param string $option * @param string $message * @access public * @since Method available since Release 3.2.0 */ public function assertSelectHasOption($selectLocator, $option, $message = '') { $this->assertContains($option, $this->getSelectOptions($selectLocator), $message); } /** * Asserts that a select element does not have a specific option. * * @param string $selectLocator * @param string $option * @param string $message * @access public * @since Method available since Release 3.2.0 */ public function assertSelectNotHasOption($selectLocator, $option, $message = '') { $this->assertNotContains($option, $this->getSelectOptions($selectLocator), $message); } /** * Asserts that a specific label is selected. * * @param string $selectLocator * @param string $value * @param string $message * @access public * @since Method available since Release 3.2.0 */ public function assertSelected($selectLocator, $option, $message = '') { if ($message == '') { $message = sprintf('Label "%s" not selected in "%s".', $option, $selectLocator); } $this->assertEquals($option, $this->getSelectedLabel($selectLocator), $message); } /** * Asserts that a specific label is not selected. * * @param string $selectLocator * @param string $value * @param string $message * @access public * @since Method available since Release 3.2.0 */ public function assertNotSelected($selectLocator, $option, $message = '') { if ($message == '') { $message = sprintf('Label "%s" selected in "%s".', $option, $selectLocator); } $this->assertNotEquals($option, $this->getSelectedLabel($selectLocator), $message); } /** * Asserts that a specific value is selected. * * @param string $selectLocator * @param string $value * @param string $message * @access public */ public function assertIsSelected($selectLocator, $value, $message = '') { if ($message == '') { $message = sprintf('Value "%s" not selected in "%s".', $value, $selectLocator); } $this->assertEquals($value, $this->getSelectedValue($selectLocator), $message); } /** * Asserts that a specific value is not selected. * * @param string $selectLocator * @param string $value * @param string $message * @access public */ public function assertIsNotSelected($selectLocator, $value, $message = '') { if ($message == '') { $message = sprintf('Value "%s" selected in "%s".', $value, $selectLocator); } $this->assertNotEquals($value, $this->getSelectedValue($selectLocator), $message); } /** * Asserts that something is selected. * * @param string $selectLocator * @param string $message * @access public */ public function assertSomethingSelected($selectLocator, $message = '') { if ($message == '') { $message = sprintf('Nothing selected from "%s".', $selectLocator); } $this->assertTrue($this->isSomethingSelected($selectLocator), $message); } /** * Asserts that nothing is selected. * * @param string $selectLocator * @param string $message * @access public */ public function assertNothingSelected($selectLocator, $message = '') { if ($message == '') { $message = sprintf('Something selected from "%s".', $selectLocator); } $this->assertFalse($this->isSomethingSelected($selectLocator), $message); } /** * Asserts that a given text is present. * * @param string $pattern * @param string $message * @access public */ public function assertTextPresent($pattern, $message = '') { if ($message == '') { $message = sprintf('"%s" not present.', $pattern); } $this->assertTrue($this->isTextPresent($pattern), $message); } /** * Asserts that a given text is not present. * * @param string $pattern * @param string $message * @access public */ public function assertTextNotPresent($pattern, $message = '') { if ($message == '') { $message = sprintf('"%s" present.', $pattern); } $this->assertFalse($this->isTextPresent($pattern), $message); } /** * Asserts that the title is equal to a given string. * * @param string $title * @param string $message * @access public */ public function assertTitleEquals($title, $message = '') { $this->assertEquals($title, $this->getTitle(), $message); } /** * Asserts that the title is not equal to a given string. * * @param string $title * @param string $message * @access public */ public function assertTitleNotEquals($title, $message = '') { $this->assertNotEquals($title, $this->getTitle(), $message); } /** * Asserts that something is visible. * * @param string $locator * @param string $message * @access public */ public function assertVisible($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" not visible.', $locator); } $this->assertTrue($this->isVisible($locator), $message); } /** * Asserts that something is not visible. * * @param string $locator * @param string $message * @access public */ public function assertNotVisible($locator, $message = '') { if ($message == '') { $message = sprintf('"%s" visible.', $locator); } $this->assertFalse($this->isVisible($locator), $message); } /** * Template Method that is called after Selenium actions. * * @param string $action * @access protected * @since Method available since Release 3.1.0 */ protected function defaultAssertions($action) {} /** * Send a command to the Selenium RC server. * * @param string $command * @param array $arguments * @return string * @access protected * @author Shin Ohno * @author Bjoern Schotte * @since Method available since Release 3.1.0 */ protected function doCommand($command, array $arguments = array()) { $url = sprintf('http://%s:%s/selenium-server/driver/?cmd=%s', $this->host, $this->port, urlencode($command)); for ($i = 0; $i < count($arguments); $i ++) { $argNum = strval($i + 1); $url .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i]))); } if (isset(self::$sessionId[$this->host][$this->port][$this->browser])) { $url .= sprintf('&%s=%s', 'sessionId', self::$sessionId[$this->host][$this->port][$this->browser]); } if (! $handle = @fopen($url, 'r')) { throw new RuntimeException('Could not connect to the Selenium RC server.'); } stream_set_blocking($handle, 1); stream_set_timeout($handle, 0, $this->timeout); $info = stream_get_meta_data($handle); $response = ''; while ((! feof($handle)) && (! $info['timed_out'])) { $response .= fgets($handle, 4096); $info = stream_get_meta_data($handle); } fclose($handle); if (! preg_match('/^OK/', $response)) { $this->stop(); throw new RuntimeException('The response from the Selenium RC server is invalid: ' . $response); } return $response; } /** * Send a command to the Selenium RC server and treat the result * as a boolean. * * @param string $command * @param array $arguments * @return boolean * @access protected * @author Shin Ohno * @author Bjoern Schotte * @since Method available since Release 3.1.0 */ protected function getBoolean($command, array $arguments) { $result = $this->getString($command, $arguments); switch ($result) { case 'true': return TRUE; case 'false': return FALSE; default: { $this->stop(); throw new RuntimeException('Result is neither "true" nor "false": ' . PHPUnit_Util_Type::toString($result, TRUE)); } } } /** * Send a command to the Selenium RC server and treat the result * as a number. * * @param string $command * @param array $arguments * @return numeric * @access protected * @author Shin Ohno * @author Bjoern Schotte * @since Method available since Release 3.1.0 */ protected function getNumber($command, array $arguments) { $result = $this->getString($command, $arguments); if (! is_numeric($result)) { $this->stop(); throw new RuntimeException('Result is not numeric: ' . PHPUnit_Util_Type::toString($result, TRUE)); } return $result; } /** * Send a command to the Selenium RC server and treat the result * as a string. * * @param string $command * @param array $arguments * @return string * @access protected * @author Shin Ohno * @author Bjoern Schotte * @since Method available since Release 3.1.0 */ protected function getString($command, array $arguments) { try { $result = $this->doCommand($command, $arguments); } catch (RuntimeException $e) { $this->stop(); throw $e; } return (strlen($result) > 3) ? substr($result, 3) : ''; } /** * Send a command to the Selenium RC server and treat the result * as an array of strings. * * @param string $command * @param array $arguments * @return array * @access protected * @author Shin Ohno * @author Bjoern Schotte * @since Method available since Release 3.1.0 */ protected function getStringArray($command, array $arguments) { $csv = $this->getString($command, $arguments); $token = ''; $tokens = array(); $letters = preg_split('//', $csv, - 1, PREG_SPLIT_NO_EMPTY); $count = count($letters); for ($i = 0; $i < $count; $i ++) { $letter = $letters[$i]; switch ($letter) { case '\\': { $letter = $letters[++ $i]; $token .= $letter; } break; case ',': { $tokens[] = $token; $token = ''; } break; default: { $token .= $letter; } } } $tokens[] = $token; return $tokens; } /** * @return array * @access protected * @since Method available since Release 3.2.0 */ protected function getCodeCoverage() { if (! empty($this->coverageScriptUrl)) { $url = sprintf('%s?PHPUNIT_SELENIUM_TEST_ID=%s', $this->coverageScriptUrl, $this->testId); return $this->matchLocalAndRemotePaths(eval('return ' . file_get_contents($url) . ';')); } else { return array(); } } /** * @param array $coverage * @return array * @access protected * @author Mattis Stordalen Flister * @since Method available since Release 3.2.9 */ protected function matchLocalAndRemotePaths(array &$coverage) { $coverageWithLocalPaths = array(); foreach ($coverage as $originalRemotePath => $value) { $remotePath = $originalRemotePath; $separator = $this->findDirectorySeparator($remotePath); while (! ($localpath = PHPUnit_Util_Filesystem::fileExistsInIncludePath($remotePath)) && strpos($remotePath, $separator) !== FALSE) { $remotePath = substr($remotePath, strpos($remotePath, $separator) + 1); } if ($localpath && md5_file($localpath) == $value['md5']) { $coverageWithLocalPaths[$localpath] = $value; unset($coverageWithLocalPaths[$localpath]['md5']); } } return $coverageWithLocalPaths; } /** * @param string $path * @return string * @access protected * @author Mattis Stordalen Flister * @since Method available since Release 3.2.9 */ protected function findDirectorySeparator($path) { if (strpos($path, '/') !== FALSE) { return '/'; } return '\\'; } /** * @param string $path * @return array * @access protected * @author Mattis Stordalen Flister * @since Method available since Release 3.2.9 */ protected function explodeDirectories($path) { return explode($this->findDirectorySeparator($path), dirname($path)); } /** * @param string $action * @access private * @since Method available since Release 3.2.0 */ private function runDefaultAssertions($action) { if (! $this->inDefaultAssertions) { $this->inDefaultAssertions = TRUE; $this->defaultAssertions($action); $this->inDefaultAssertions = FALSE; } } } ?>