1350 lines
43 KiB
PHP
1350 lines
43 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* PHPUnit
|
||
|
|
*
|
||
|
|
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
|
||
|
|
* 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.
|
||
|
|
*
|
||
|
|
* @package PHPUnit_Selenium
|
||
|
|
* @author Sebastian Bergmann <sebastian@phpunit.de>
|
||
|
|
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
|
||
|
|
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
|
||
|
|
* @link http://www.phpunit.de/
|
||
|
|
* @since File available since Release 1.0.0
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Implementation of the Selenium RC client/server protocol.
|
||
|
|
*
|
||
|
|
* @package PHPUnit_Selenium
|
||
|
|
* @author Sebastian Bergmann <sebastian@phpunit.de>
|
||
|
|
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
|
||
|
|
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
|
||
|
|
* @version Release: @package_version@
|
||
|
|
* @link http://www.phpunit.de/
|
||
|
|
* @since Class available since Release 1.0.0
|
||
|
|
*/
|
||
|
|
class PHPUnit_Extensions_SeleniumTestCase_Driver
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* @var PHPUnit_Extensions_SeleniumTestCase
|
||
|
|
*/
|
||
|
|
protected $testCase;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $testId;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $name;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $browser;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $browserUrl;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var boolean
|
||
|
|
*/
|
||
|
|
protected $collectCodeCoverageInformation = FALSE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $host = 'localhost';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var integer
|
||
|
|
*/
|
||
|
|
protected $port = 4444;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var integer
|
||
|
|
*/
|
||
|
|
protected $httpTimeout = 45;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var integer
|
||
|
|
*/
|
||
|
|
protected $seleniumTimeout = 30;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $sessionId;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var integer
|
||
|
|
*/
|
||
|
|
protected $sleep = 0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var boolean
|
||
|
|
*/
|
||
|
|
protected $useWaitForPageToLoad = TRUE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var boolean
|
||
|
|
*/
|
||
|
|
protected $wait = 5;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected static $autoGeneratedCommands = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $commands = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var array $userCommands A numerical array which holds custom user commands.
|
||
|
|
*/
|
||
|
|
protected $userCommands = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $verificationErrors = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
private $webDriverCapabilities;
|
||
|
|
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
if (empty(self::$autoGeneratedCommands)) {
|
||
|
|
self::autoGenerateCommands();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Only browserName is supported.
|
||
|
|
*/
|
||
|
|
public function setWebDriverCapabilities(array $capabilities)
|
||
|
|
{
|
||
|
|
$this->webDriverCapabilities = $capabilities;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return string
|
||
|
|
*/
|
||
|
|
public function start()
|
||
|
|
{
|
||
|
|
if ($this->browserUrl == NULL) {
|
||
|
|
throw new PHPUnit_Framework_Exception(
|
||
|
|
'setBrowserUrl() needs to be called before start().'
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($this->webDriverCapabilities !== NULL) {
|
||
|
|
$seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($this->host, $this->port);
|
||
|
|
$driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl);
|
||
|
|
$session = $driver->startSession($this->webDriverCapabilities, new PHPUnit_Extensions_Selenium2TestCase_URL($this->browserUrl));
|
||
|
|
$webDriverSessionId = $session->id();
|
||
|
|
$this->sessionId = $this->getString(
|
||
|
|
'getNewBrowserSession',
|
||
|
|
array($this->browser, $this->browserUrl, '',
|
||
|
|
"webdriver.remote.sessionid=$webDriverSessionId")
|
||
|
|
);
|
||
|
|
|
||
|
|
$this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isset($this->sessionId)) {
|
||
|
|
$this->sessionId = $this->getString(
|
||
|
|
'getNewBrowserSession',
|
||
|
|
array($this->browser, $this->browserUrl)
|
||
|
|
);
|
||
|
|
|
||
|
|
$this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->sessionId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return string
|
||
|
|
* @since Method available since Release 1.1.0
|
||
|
|
*/
|
||
|
|
public function getSessionId()
|
||
|
|
{
|
||
|
|
return $this->sessionId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string
|
||
|
|
* @since Method available since Release 1.2.0
|
||
|
|
*/
|
||
|
|
public function setSessionId($sessionId)
|
||
|
|
{
|
||
|
|
$this->sessionId = $sessionId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public function stop()
|
||
|
|
{
|
||
|
|
if (!isset($this->sessionId)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->doCommand('testComplete');
|
||
|
|
|
||
|
|
$this->sessionId = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param boolean $flag
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setCollectCodeCoverageInformation($flag)
|
||
|
|
{
|
||
|
|
if (!is_bool($flag)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->collectCodeCoverageInformation = $flag;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param PHPUnit_Extensions_SeleniumTestCase $testCase
|
||
|
|
*/
|
||
|
|
public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase)
|
||
|
|
{
|
||
|
|
$this->testCase = $testCase;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param integer $testId
|
||
|
|
*/
|
||
|
|
public function setTestId($testId)
|
||
|
|
{
|
||
|
|
$this->testId = $testId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string $name
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setName($name)
|
||
|
|
{
|
||
|
|
if (!is_string($name)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->name = $name;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return string
|
||
|
|
*/
|
||
|
|
public function getName()
|
||
|
|
{
|
||
|
|
return $this->name;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string $browser
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setBrowser($browser)
|
||
|
|
{
|
||
|
|
if (!is_string($browser)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->browser = $browser;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return string
|
||
|
|
*/
|
||
|
|
public function getBrowser()
|
||
|
|
{
|
||
|
|
return $this->browser;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string $browserUrl
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setBrowserUrl($browserUrl)
|
||
|
|
{
|
||
|
|
if (!is_string($browserUrl)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->browserUrl = $browserUrl;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string $host
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setHost($host)
|
||
|
|
{
|
||
|
|
if (!is_string($host)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->host = $host;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return string
|
||
|
|
* @since Method available since Release 1.1.0
|
||
|
|
*/
|
||
|
|
public function getHost()
|
||
|
|
{
|
||
|
|
return $this->host;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param integer $port
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setPort($port)
|
||
|
|
{
|
||
|
|
if (!is_int($port)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->port = $port;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return integer
|
||
|
|
* @since Method available since Release 1.1.0
|
||
|
|
*/
|
||
|
|
public function getPort()
|
||
|
|
{
|
||
|
|
return $this->port;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param integer $timeout for Selenium RC in seconds
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setTimeout($timeout)
|
||
|
|
{
|
||
|
|
if (!is_int($timeout)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->seleniumTimeout = $timeout;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param integer $timeout for HTTP connection to Selenium RC in seconds
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setHttpTimeout($timeout)
|
||
|
|
{
|
||
|
|
if (!is_int($timeout)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->httpTimeout = $timeout;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param integer $seconds
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setSleep($seconds)
|
||
|
|
{
|
||
|
|
if (!is_int($seconds)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->sleep = $seconds;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the number of seconds to sleep() after *AndWait commands
|
||
|
|
* when setWaitForPageToLoad(FALSE) is used.
|
||
|
|
*
|
||
|
|
* @param integer $seconds
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setWait($seconds)
|
||
|
|
{
|
||
|
|
if (!is_int($seconds)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->wait = $seconds;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE)
|
||
|
|
* is used after *AndWait commands.
|
||
|
|
*
|
||
|
|
* @param boolean $flag
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public function setWaitForPageToLoad($flag)
|
||
|
|
{
|
||
|
|
if (!is_bool($flag)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->useWaitForPageToLoad = $flag;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds allowed user commands into {@link self::$userCommands}. See
|
||
|
|
* {@link self::__call()} (switch/case -> default) for usage.
|
||
|
|
*
|
||
|
|
* @param string $command A command.
|
||
|
|
*
|
||
|
|
* @return $this
|
||
|
|
* @see self::__call()
|
||
|
|
*/
|
||
|
|
public function addUserCommand($command)
|
||
|
|
{
|
||
|
|
if (!is_string($command)) {
|
||
|
|
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
|
||
|
|
}
|
||
|
|
$this->userCommands[] = $command;
|
||
|
|
return $this;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This method implements the Selenium RC protocol.
|
||
|
|
*
|
||
|
|
* @param string $command
|
||
|
|
* @param array $arguments
|
||
|
|
* @return mixed
|
||
|
|
* @method unknown addLocationStrategy()
|
||
|
|
* @method unknown addLocationStrategyAndWait()
|
||
|
|
* @method unknown addScript()
|
||
|
|
* @method unknown addScriptAndWait()
|
||
|
|
* @method unknown addSelection()
|
||
|
|
* @method unknown addSelectionAndWait()
|
||
|
|
* @method unknown allowNativeXpath()
|
||
|
|
* @method unknown allowNativeXpathAndWait()
|
||
|
|
* @method unknown altKeyDown()
|
||
|
|
* @method unknown altKeyDownAndWait()
|
||
|
|
* @method unknown altKeyUp()
|
||
|
|
* @method unknown altKeyUpAndWait()
|
||
|
|
* @method unknown answerOnNextPrompt()
|
||
|
|
* @method unknown assignId()
|
||
|
|
* @method unknown assignIdAndWait()
|
||
|
|
* @method unknown attachFile()
|
||
|
|
* @method unknown break()
|
||
|
|
* @method unknown captureEntirePageScreenshot()
|
||
|
|
* @method unknown captureEntirePageScreenshotAndWait()
|
||
|
|
* @method unknown captureEntirePageScreenshotToStringAndWait()
|
||
|
|
* @method unknown captureScreenshotAndWait()
|
||
|
|
* @method unknown captureScreenshotToStringAndWait()
|
||
|
|
* @method unknown check()
|
||
|
|
* @method unknown checkAndWait()
|
||
|
|
* @method unknown chooseCancelOnNextConfirmation()
|
||
|
|
* @method unknown chooseCancelOnNextConfirmationAndWait()
|
||
|
|
* @method unknown chooseOkOnNextConfirmation()
|
||
|
|
* @method unknown chooseOkOnNextConfirmationAndWait()
|
||
|
|
* @method unknown click()
|
||
|
|
* @method unknown clickAndWait()
|
||
|
|
* @method unknown clickAt()
|
||
|
|
* @method unknown clickAtAndWait()
|
||
|
|
* @method unknown close()
|
||
|
|
* @method unknown contextMenu()
|
||
|
|
* @method unknown contextMenuAndWait()
|
||
|
|
* @method unknown contextMenuAt()
|
||
|
|
* @method unknown contextMenuAtAndWait()
|
||
|
|
* @method unknown controlKeyDown()
|
||
|
|
* @method unknown controlKeyDownAndWait()
|
||
|
|
* @method unknown controlKeyUp()
|
||
|
|
* @method unknown controlKeyUpAndWait()
|
||
|
|
* @method unknown createCookie()
|
||
|
|
* @method unknown createCookieAndWait()
|
||
|
|
* @method unknown deleteAllVisibleCookies()
|
||
|
|
* @method unknown deleteAllVisibleCookiesAndWait()
|
||
|
|
* @method unknown deleteCookie()
|
||
|
|
* @method unknown deleteCookieAndWait()
|
||
|
|
* @method unknown deselectPopUp()
|
||
|
|
* @method unknown deselectPopUpAndWait()
|
||
|
|
* @method unknown doubleClick()
|
||
|
|
* @method unknown doubleClickAndWait()
|
||
|
|
* @method unknown doubleClickAt()
|
||
|
|
* @method unknown doubleClickAtAndWait()
|
||
|
|
* @method unknown dragAndDrop()
|
||
|
|
* @method unknown dragAndDropAndWait()
|
||
|
|
* @method unknown dragAndDropToObject()
|
||
|
|
* @method unknown dragAndDropToObjectAndWait()
|
||
|
|
* @method unknown dragDrop()
|
||
|
|
* @method unknown dragDropAndWait()
|
||
|
|
* @method unknown echo()
|
||
|
|
* @method unknown fireEvent()
|
||
|
|
* @method unknown fireEventAndWait()
|
||
|
|
* @method unknown focus()
|
||
|
|
* @method unknown focusAndWait()
|
||
|
|
* @method string getAlert()
|
||
|
|
* @method array getAllButtons()
|
||
|
|
* @method array getAllFields()
|
||
|
|
* @method array getAllLinks()
|
||
|
|
* @method array getAllWindowIds()
|
||
|
|
* @method array getAllWindowNames()
|
||
|
|
* @method array getAllWindowTitles()
|
||
|
|
* @method string getAttribute(string $attributeLocator)
|
||
|
|
* @method array getAttributeFromAllWindows(string $attributeName)
|
||
|
|
* @method string getBodyText()
|
||
|
|
* @method string getConfirmation()
|
||
|
|
* @method string getCookie()
|
||
|
|
* @method string getCookieByName(string $name)
|
||
|
|
* @method integer getCssCount(string $locator)
|
||
|
|
* @method integer getCursorPosition(string $locator)
|
||
|
|
* @method integer getElementHeight(string $locator)
|
||
|
|
* @method integer getElementIndex(string $locator)
|
||
|
|
* @method integer getElementPositionLeft(string $locator)
|
||
|
|
* @method integer getElementPositionTop(string $locator)
|
||
|
|
* @method integer getElementWidth(string $locator)
|
||
|
|
* @method string getEval(string $script)
|
||
|
|
* @method string getExpression(string $expression)
|
||
|
|
* @method string getHtmlSource()
|
||
|
|
* @method string getLocation()
|
||
|
|
* @method string getLogMessages()
|
||
|
|
* @method integer getMouseSpeed()
|
||
|
|
* @method string getPrompt()
|
||
|
|
* @method array getSelectOptions(string $selectLocator)
|
||
|
|
* @method string getSelectedId(string $selectLocator)
|
||
|
|
* @method array getSelectedIds(string $selectLocator)
|
||
|
|
* @method string getSelectedIndex(string $selectLocator)
|
||
|
|
* @method array getSelectedIndexes(string $selectLocator)
|
||
|
|
* @method string getSelectedLabel(string $selectLocator)
|
||
|
|
* @method array getSelectedLabels(string $selectLocator)
|
||
|
|
* @method string getSelectedValue(string $selectLocator)
|
||
|
|
* @method array getSelectedValues(string $selectLocator)
|
||
|
|
* @method unknown getSpeed()
|
||
|
|
* @method unknown getSpeedAndWait()
|
||
|
|
* @method string getTable(string $tableCellAddress)
|
||
|
|
* @method string getText(string $locator)
|
||
|
|
* @method string getTitle()
|
||
|
|
* @method string getValue(string $locator)
|
||
|
|
* @method boolean getWhetherThisFrameMatchFrameExpression(string $currentFrameString, string $target)
|
||
|
|
* @method boolean getWhetherThisWindowMatchWindowExpression(string $currentWindowString, string $target)
|
||
|
|
* @method integer getXpathCount(string $xpath)
|
||
|
|
* @method unknown goBack()
|
||
|
|
* @method unknown goBackAndWait()
|
||
|
|
* @method unknown highlight(string $locator)
|
||
|
|
* @method unknown highlightAndWait(string $locator)
|
||
|
|
* @method unknown ignoreAttributesWithoutValue(string $ignore)
|
||
|
|
* @method unknown ignoreAttributesWithoutValueAndWait(string $ignore)
|
||
|
|
* @method boolean isAlertPresent()
|
||
|
|
* @method boolean isChecked(locator)
|
||
|
|
* @method boolean isConfirmationPresent()
|
||
|
|
* @method boolean isCookiePresent(string $name)
|
||
|
|
* @method boolean isEditable(string $locator)
|
||
|
|
* @method boolean isElementPresent(string $locator)
|
||
|
|
* @method boolean isOrdered(string $locator1, string $locator2)
|
||
|
|
* @method boolean isPromptPresent()
|
||
|
|
* @method boolean isSomethingSelected(string $selectLocator)
|
||
|
|
* @method boolean isTextPresent(pattern)
|
||
|
|
* @method boolean isVisible(locator)
|
||
|
|
* @method unknown keyDown()
|
||
|
|
* @method unknown keyDownAndWait()
|
||
|
|
* @method unknown keyDownNative()
|
||
|
|
* @method unknown keyDownNativeAndWait()
|
||
|
|
* @method unknown keyPress()
|
||
|
|
* @method unknown keyPressAndWait()
|
||
|
|
* @method unknown keyPressNative()
|
||
|
|
* @method unknown keyPressNativeAndWait()
|
||
|
|
* @method unknown keyUp()
|
||
|
|
* @method unknown keyUpAndWait()
|
||
|
|
* @method unknown keyUpNative()
|
||
|
|
* @method unknown keyUpNativeAndWait()
|
||
|
|
* @method unknown metaKeyDown()
|
||
|
|
* @method unknown metaKeyDownAndWait()
|
||
|
|
* @method unknown metaKeyUp()
|
||
|
|
* @method unknown metaKeyUpAndWait()
|
||
|
|
* @method unknown mouseDown()
|
||
|
|
* @method unknown mouseDownAndWait()
|
||
|
|
* @method unknown mouseDownAt()
|
||
|
|
* @method unknown mouseDownAtAndWait()
|
||
|
|
* @method unknown mouseMove()
|
||
|
|
* @method unknown mouseMoveAndWait()
|
||
|
|
* @method unknown mouseMoveAt()
|
||
|
|
* @method unknown mouseMoveAtAndWait()
|
||
|
|
* @method unknown mouseOut()
|
||
|
|
* @method unknown mouseOutAndWait()
|
||
|
|
* @method unknown mouseOver()
|
||
|
|
* @method unknown mouseOverAndWait()
|
||
|
|
* @method unknown mouseUp()
|
||
|
|
* @method unknown mouseUpAndWait()
|
||
|
|
* @method unknown mouseUpAt()
|
||
|
|
* @method unknown mouseUpAtAndWait()
|
||
|
|
* @method unknown mouseUpRight()
|
||
|
|
* @method unknown mouseUpRightAndWait()
|
||
|
|
* @method unknown mouseUpRightAt()
|
||
|
|
* @method unknown mouseUpRightAtAndWait()
|
||
|
|
* @method unknown open()
|
||
|
|
* @method unknown openWindow()
|
||
|
|
* @method unknown openWindowAndWait()
|
||
|
|
* @method unknown pause()
|
||
|
|
* @method unknown refresh()
|
||
|
|
* @method unknown refreshAndWait()
|
||
|
|
* @method unknown removeAllSelections()
|
||
|
|
* @method unknown removeAllSelectionsAndWait()
|
||
|
|
* @method unknown removeScript()
|
||
|
|
* @method unknown removeScriptAndWait()
|
||
|
|
* @method unknown removeSelection()
|
||
|
|
* @method unknown removeSelectionAndWait()
|
||
|
|
* @method unknown retrieveLastRemoteControlLogs()
|
||
|
|
* @method unknown rollup()
|
||
|
|
* @method unknown rollupAndWait()
|
||
|
|
* @method unknown runScript()
|
||
|
|
* @method unknown runScriptAndWait()
|
||
|
|
* @method unknown select()
|
||
|
|
* @method unknown selectAndWait()
|
||
|
|
* @method unknown selectFrame()
|
||
|
|
* @method unknown selectPopUp()
|
||
|
|
* @method unknown selectPopUpAndWait()
|
||
|
|
* @method unknown selectWindow()
|
||
|
|
* @method unknown setBrowserLogLevel()
|
||
|
|
* @method unknown setBrowserLogLevelAndWait()
|
||
|
|
* @method unknown setContext()
|
||
|
|
* @method unknown setCursorPosition()
|
||
|
|
* @method unknown setCursorPositionAndWait()
|
||
|
|
* @method unknown setMouseSpeed()
|
||
|
|
* @method unknown setMouseSpeedAndWait()
|
||
|
|
* @method unknown setSpeed()
|
||
|
|
* @method unknown setSpeedAndWait()
|
||
|
|
* @method unknown shiftKeyDown()
|
||
|
|
* @method unknown shiftKeyDownAndWait()
|
||
|
|
* @method unknown shiftKeyUp()
|
||
|
|
* @method unknown shiftKeyUpAndWait()
|
||
|
|
* @method unknown shutDownSeleniumServer()
|
||
|
|
* @method unknown store()
|
||
|
|
* @method unknown submit()
|
||
|
|
* @method unknown submitAndWait()
|
||
|
|
* @method unknown type()
|
||
|
|
* @method unknown typeAndWait()
|
||
|
|
* @method unknown typeKeys()
|
||
|
|
* @method unknown typeKeysAndWait()
|
||
|
|
* @method unknown uncheck()
|
||
|
|
* @method unknown uncheckAndWait()
|
||
|
|
* @method unknown useXpathLibrary()
|
||
|
|
* @method unknown useXpathLibraryAndWait()
|
||
|
|
* @method unknown waitForCondition()
|
||
|
|
* @method unknown waitForElementPresent()
|
||
|
|
* @method unknown waitForElementNotPresent()
|
||
|
|
* @method unknown waitForPageToLoad()
|
||
|
|
* @method unknown waitForPopUp()
|
||
|
|
* @method unknown windowFocus()
|
||
|
|
* @method unknown windowMaximize()
|
||
|
|
*/
|
||
|
|
public function __call($command, $arguments)
|
||
|
|
{
|
||
|
|
$arguments = $this->preprocessParameters($arguments);
|
||
|
|
|
||
|
|
$wait = FALSE;
|
||
|
|
|
||
|
|
if (substr($command, -7, 7) == 'AndWait') {
|
||
|
|
$command = substr($command, 0, -7);
|
||
|
|
$wait = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch ($command) {
|
||
|
|
case 'addLocationStrategy':
|
||
|
|
case 'addScript':
|
||
|
|
case 'addSelection':
|
||
|
|
case 'allowNativeXpath':
|
||
|
|
case 'altKeyDown':
|
||
|
|
case 'altKeyUp':
|
||
|
|
case 'answerOnNextPrompt':
|
||
|
|
case 'assignId':
|
||
|
|
case 'attachFile':
|
||
|
|
case 'break':
|
||
|
|
case 'captureEntirePageScreenshot':
|
||
|
|
case 'captureScreenshot':
|
||
|
|
case 'check':
|
||
|
|
case 'chooseCancelOnNextConfirmation':
|
||
|
|
case 'chooseOkOnNextConfirmation':
|
||
|
|
case 'click':
|
||
|
|
case 'clickAt':
|
||
|
|
case 'close':
|
||
|
|
case 'contextMenu':
|
||
|
|
case 'contextMenuAt':
|
||
|
|
case 'controlKeyDown':
|
||
|
|
case 'controlKeyUp':
|
||
|
|
case 'createCookie':
|
||
|
|
case 'deleteAllVisibleCookies':
|
||
|
|
case 'deleteCookie':
|
||
|
|
case 'deselectPopUp':
|
||
|
|
case 'doubleClick':
|
||
|
|
case 'doubleClickAt':
|
||
|
|
case 'dragAndDrop':
|
||
|
|
case 'dragAndDropToObject':
|
||
|
|
case 'dragDrop':
|
||
|
|
case 'echo':
|
||
|
|
case 'fireEvent':
|
||
|
|
case 'focus':
|
||
|
|
case 'goBack':
|
||
|
|
case 'highlight':
|
||
|
|
case 'ignoreAttributesWithoutValue':
|
||
|
|
case 'keyDown':
|
||
|
|
case 'keyDownNative':
|
||
|
|
case 'keyPress':
|
||
|
|
case 'keyPressNative':
|
||
|
|
case 'keyUp':
|
||
|
|
case 'keyUpNative':
|
||
|
|
case 'metaKeyDown':
|
||
|
|
case 'metaKeyUp':
|
||
|
|
case 'mouseDown':
|
||
|
|
case 'mouseDownAt':
|
||
|
|
case 'mouseMove':
|
||
|
|
case 'mouseMoveAt':
|
||
|
|
case 'mouseOut':
|
||
|
|
case 'mouseOver':
|
||
|
|
case 'mouseUp':
|
||
|
|
case 'mouseUpAt':
|
||
|
|
case 'mouseUpRight':
|
||
|
|
case 'mouseUpRightAt':
|
||
|
|
case 'open':
|
||
|
|
case 'openWindow':
|
||
|
|
case 'pause':
|
||
|
|
case 'refresh':
|
||
|
|
case 'removeAllSelections':
|
||
|
|
case 'removeScript':
|
||
|
|
case 'removeSelection':
|
||
|
|
case 'retrieveLastRemoteControlLogs':
|
||
|
|
case 'rollup':
|
||
|
|
case 'runScript':
|
||
|
|
case 'select':
|
||
|
|
case 'selectFrame':
|
||
|
|
case 'selectPopUp':
|
||
|
|
case 'selectWindow':
|
||
|
|
case 'setBrowserLogLevel':
|
||
|
|
case 'setContext':
|
||
|
|
case 'setCursorPosition':
|
||
|
|
case 'setMouseSpeed':
|
||
|
|
case 'setSpeed':
|
||
|
|
case 'shiftKeyDown':
|
||
|
|
case 'shiftKeyUp':
|
||
|
|
case 'shutDownSeleniumServer':
|
||
|
|
case 'store':
|
||
|
|
case 'submit':
|
||
|
|
case 'type':
|
||
|
|
case 'typeKeys':
|
||
|
|
case 'uncheck':
|
||
|
|
case 'useXpathLibrary':
|
||
|
|
case 'windowFocus':
|
||
|
|
case 'windowMaximize':
|
||
|
|
case isset(self::$autoGeneratedCommands[$command]): {
|
||
|
|
// Pre-Command Actions
|
||
|
|
switch ($command) {
|
||
|
|
case 'open':
|
||
|
|
case 'openWindow': {
|
||
|
|
if ($this->collectCodeCoverageInformation) {
|
||
|
|
$this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/');
|
||
|
|
|
||
|
|
$this->createCookie(
|
||
|
|
'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId,
|
||
|
|
'path=/'
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 'store':
|
||
|
|
// store is a synonym of storeExpression
|
||
|
|
// and RC only understands storeExpression
|
||
|
|
$command = 'storeExpression';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) {
|
||
|
|
$helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]);
|
||
|
|
call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments);
|
||
|
|
} else {
|
||
|
|
$this->doCommand($command, $arguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Post-Command Actions
|
||
|
|
switch ($command) {
|
||
|
|
case 'addLocationStrategy':
|
||
|
|
case 'allowNativeXpath':
|
||
|
|
case 'assignId':
|
||
|
|
case 'captureEntirePageScreenshot':
|
||
|
|
case 'captureScreenshot': {
|
||
|
|
// intentionally empty
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default: {
|
||
|
|
if ($wait) {
|
||
|
|
if ($this->useWaitForPageToLoad) {
|
||
|
|
$this->waitForPageToLoad($this->seleniumTimeout * 1000);
|
||
|
|
} else {
|
||
|
|
sleep($this->wait);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($this->sleep > 0) {
|
||
|
|
sleep($this->sleep);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->testCase->runDefaultAssertions($command);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'getWhetherThisFrameMatchFrameExpression':
|
||
|
|
case 'getWhetherThisWindowMatchWindowExpression':
|
||
|
|
case 'isAlertPresent':
|
||
|
|
case 'isChecked':
|
||
|
|
case 'isConfirmationPresent':
|
||
|
|
case 'isCookiePresent':
|
||
|
|
case 'isEditable':
|
||
|
|
case 'isElementPresent':
|
||
|
|
case 'isOrdered':
|
||
|
|
case 'isPromptPresent':
|
||
|
|
case 'isSomethingSelected':
|
||
|
|
case 'isTextPresent':
|
||
|
|
case 'isVisible': {
|
||
|
|
return $this->getBoolean($command, $arguments);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'getCssCount':
|
||
|
|
case 'getCursorPosition':
|
||
|
|
case 'getElementHeight':
|
||
|
|
case 'getElementIndex':
|
||
|
|
case 'getElementPositionLeft':
|
||
|
|
case 'getElementPositionTop':
|
||
|
|
case 'getElementWidth':
|
||
|
|
case 'getMouseSpeed':
|
||
|
|
case 'getSpeed':
|
||
|
|
case 'getXpathCount': {
|
||
|
|
$result = $this->getNumber($command, $arguments);
|
||
|
|
|
||
|
|
if ($wait) {
|
||
|
|
$this->waitForPageToLoad($this->seleniumTimeout * 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'getAlert':
|
||
|
|
case 'getAttribute':
|
||
|
|
case 'getBodyText':
|
||
|
|
case 'getConfirmation':
|
||
|
|
case 'getCookie':
|
||
|
|
case 'getCookieByName':
|
||
|
|
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 'captureEntirePageScreenshotToString':
|
||
|
|
case 'captureScreenshotToString':
|
||
|
|
case 'getValue': {
|
||
|
|
$result = $this->getString($command, $arguments);
|
||
|
|
|
||
|
|
if ($wait) {
|
||
|
|
$this->waitForPageToLoad($this->seleniumTimeout * 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
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': {
|
||
|
|
$result = $this->getStringArray($command, $arguments);
|
||
|
|
|
||
|
|
if ($wait) {
|
||
|
|
$this->waitForPageToLoad($this->seleniumTimeout * 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'waitForCondition':
|
||
|
|
case 'waitForElementPresent':
|
||
|
|
case 'waitForElementNotPresent':
|
||
|
|
case 'waitForFrameToLoad':
|
||
|
|
case 'waitForPopUp': {
|
||
|
|
if (count($arguments) == 1) {
|
||
|
|
$arguments[] = $this->seleniumTimeout * 1000;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->doCommand($command, $arguments);
|
||
|
|
$this->testCase->runDefaultAssertions($command);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'waitForPageToLoad': {
|
||
|
|
if (empty($arguments)) {
|
||
|
|
$arguments[] = $this->seleniumTimeout * 1000;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->doCommand($command, $arguments);
|
||
|
|
$this->testCase->runDefaultAssertions($command);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default: {
|
||
|
|
if (!in_array($command, $this->userCommands)) {
|
||
|
|
throw new BadMethodCallException(
|
||
|
|
"Method $command not defined."
|
||
|
|
);
|
||
|
|
}
|
||
|
|
$this->doCommand($command, $arguments);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Send a command to the Selenium RC server.
|
||
|
|
*
|
||
|
|
* @param string $command
|
||
|
|
* @param array $arguments
|
||
|
|
* @param array $namedArguments
|
||
|
|
* @return string
|
||
|
|
* @author Seth Casana <totallymeat@gmail.org>
|
||
|
|
*/
|
||
|
|
protected function doCommand($command, array $arguments = array(), array $namedArguments = array())
|
||
|
|
{
|
||
|
|
$url = sprintf(
|
||
|
|
'http://%s:%s/selenium-server/driver/',
|
||
|
|
$this->host,
|
||
|
|
$this->port
|
||
|
|
);
|
||
|
|
|
||
|
|
$numArguments = count($arguments);
|
||
|
|
$postData = sprintf('cmd=%s', urlencode($command));
|
||
|
|
for ($i = 0; $i < $numArguments; $i++) {
|
||
|
|
$argNum = strval($i + 1);
|
||
|
|
|
||
|
|
if ($arguments[$i] == ' ') {
|
||
|
|
$postData .= sprintf('&%s=%s', $argNum, urlencode($arguments[$i]));
|
||
|
|
} else {
|
||
|
|
$postData .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
foreach ($namedArguments as $key => $value) {
|
||
|
|
$postData .= sprintf('&%s=%s', $key, urlencode($value));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isset($this->sessionId)) {
|
||
|
|
$postData .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
|
||
|
|
}
|
||
|
|
|
||
|
|
$curl = curl_init();
|
||
|
|
curl_setopt($curl, CURLOPT_URL, $url);
|
||
|
|
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||
|
|
curl_setopt($curl, CURLOPT_POST, TRUE);
|
||
|
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||
|
|
'Content-Type: application/x-www-form-urlencoded; charset=utf-8'
|
||
|
|
));
|
||
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||
|
|
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
|
||
|
|
|
||
|
|
$response = curl_exec($curl);
|
||
|
|
$info = curl_getinfo($curl);
|
||
|
|
|
||
|
|
if (!$response) {
|
||
|
|
throw new RuntimeException("CURL error while accessing the Selenium Server at '$url': " . curl_error($curl));
|
||
|
|
}
|
||
|
|
|
||
|
|
curl_close($curl);
|
||
|
|
|
||
|
|
if (!preg_match('/^OK/', $response)) {
|
||
|
|
throw new RuntimeException("Invalid response while accessing the Selenium Server at '$url': " . $response);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($info['http_code'] != 200) {
|
||
|
|
throw new RuntimeException(
|
||
|
|
'The response from the Selenium RC server is invalid: ' .
|
||
|
|
$response
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $response;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function preprocessParameters($params)
|
||
|
|
{
|
||
|
|
foreach ($params as $key => $param ) {
|
||
|
|
if (is_string($param) && (strlen($param) > 0)) {
|
||
|
|
$params[$key] = $this->getString('getExpression', array($param));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $params;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Send a command to the Selenium RC server and treat the result
|
||
|
|
* as a boolean.
|
||
|
|
*
|
||
|
|
* @param string $command
|
||
|
|
* @param array $arguments
|
||
|
|
* @return boolean
|
||
|
|
* @author Shin Ohno <ganchiku@gmail.com>
|
||
|
|
* @author Bjoern Schotte <schotte@mayflower.de>
|
||
|
|
*/
|
||
|
|
protected function getBoolean($command, array $arguments)
|
||
|
|
{
|
||
|
|
$result = $this->getString($command, $arguments);
|
||
|
|
|
||
|
|
switch ($result) {
|
||
|
|
case 'true': return TRUE;
|
||
|
|
|
||
|
|
case 'false': return FALSE;
|
||
|
|
|
||
|
|
default: {
|
||
|
|
throw new PHPUnit_Framework_Exception(
|
||
|
|
'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::export($result)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Send a command to the Selenium RC server and treat the result
|
||
|
|
* as a number.
|
||
|
|
*
|
||
|
|
* @param string $command
|
||
|
|
* @param array $arguments
|
||
|
|
* @return numeric
|
||
|
|
* @author Shin Ohno <ganchiku@gmail.com>
|
||
|
|
* @author Bjoern Schotte <schotte@mayflower.de>
|
||
|
|
*/
|
||
|
|
protected function getNumber($command, array $arguments)
|
||
|
|
{
|
||
|
|
$result = $this->getString($command, $arguments);
|
||
|
|
|
||
|
|
if (!is_numeric($result)) {
|
||
|
|
throw new PHPUnit_Framework_Exception(
|
||
|
|
'Result is not numeric: ' . PHPUnit_Util_Type::export($result)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
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
|
||
|
|
* @author Shin Ohno <ganchiku@gmail.com>
|
||
|
|
* @author Bjoern Schotte <schotte@mayflower.de>
|
||
|
|
*/
|
||
|
|
protected function getString($command, array $arguments)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$result = $this->doCommand($command, $arguments);
|
||
|
|
}
|
||
|
|
|
||
|
|
catch (RuntimeException $e) {
|
||
|
|
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
|
||
|
|
* @author Shin Ohno <ganchiku@gmail.com>
|
||
|
|
* @author Bjoern Schotte <schotte@mayflower.de>
|
||
|
|
*/
|
||
|
|
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;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function getVerificationErrors()
|
||
|
|
{
|
||
|
|
return $this->verificationErrors;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function clearVerificationErrors()
|
||
|
|
{
|
||
|
|
$this->verificationErrors = array();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function assertCommand($command, $arguments, $info)
|
||
|
|
{
|
||
|
|
$method = $info['originalMethod'];
|
||
|
|
$requiresTarget = $info['requiresTarget'];
|
||
|
|
$result = $this->__call($method, $arguments);
|
||
|
|
$message = "Failed command: " . $command . "('"
|
||
|
|
. (array_key_exists(0, $arguments) ? $arguments[0] . "'" : '')
|
||
|
|
. (array_key_exists(1, $arguments) ? ", '" . $arguments[1] . "'" : '')
|
||
|
|
. ")";
|
||
|
|
|
||
|
|
if ($info['isBoolean']) {
|
||
|
|
if (!isset($info['negative']) || !$info['negative']) {
|
||
|
|
PHPUnit_Framework_Assert::assertTrue($result, $message);
|
||
|
|
} else {
|
||
|
|
PHPUnit_Framework_Assert::assertFalse($result, $message);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if ($requiresTarget === TRUE) {
|
||
|
|
$expected = $arguments[1];
|
||
|
|
} else {
|
||
|
|
$expected = $arguments[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strpos($expected, 'exact:') === 0) {
|
||
|
|
$expected = substr($expected, strlen('exact:'));
|
||
|
|
|
||
|
|
if (!isset($info['negative']) || !$info['negative']) {
|
||
|
|
PHPUnit_Framework_Assert::assertEquals($expected, $result, $message);
|
||
|
|
} else {
|
||
|
|
PHPUnit_Framework_Assert::assertNotEquals($expected, $result, $message);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$caseInsensitive = FALSE;
|
||
|
|
|
||
|
|
if (strpos($expected, 'regexp:') === 0) {
|
||
|
|
$expected = substr($expected, strlen('regexp:'));
|
||
|
|
}
|
||
|
|
|
||
|
|
else if (strpos($expected, 'regexpi:') === 0) {
|
||
|
|
$expected = substr($expected, strlen('regexpi:'));
|
||
|
|
$caseInsensitive = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
else {
|
||
|
|
if (strpos($expected, 'glob:') === 0) {
|
||
|
|
$expected = substr($expected, strlen('glob:'));
|
||
|
|
}
|
||
|
|
|
||
|
|
$expected = '^' . str_replace(
|
||
|
|
array('*', '?'), array('.*', '.?'), $expected
|
||
|
|
) . '$';
|
||
|
|
}
|
||
|
|
|
||
|
|
$expected = '/' . str_replace('/', '\/', $expected) . '/';
|
||
|
|
|
||
|
|
if ($caseInsensitive) {
|
||
|
|
$expected .= 'i';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isset($info['negative']) || !$info['negative']) {
|
||
|
|
PHPUnit_Framework_Assert::assertRegExp(
|
||
|
|
$expected, $result, $message
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
PHPUnit_Framework_Assert::assertNotRegExp(
|
||
|
|
$expected, $result, $message
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function verifyCommand($command, $arguments, $info)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$this->assertCommand($command, $arguments, $info);
|
||
|
|
}
|
||
|
|
|
||
|
|
catch (PHPUnit_Framework_AssertionFailedError $e) {
|
||
|
|
array_push($this->verificationErrors, $e->toString());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function waitForCommand($command, $arguments, $info)
|
||
|
|
{
|
||
|
|
$lastExceptionMessage = '';
|
||
|
|
for ($second = 0; ; $second++) {
|
||
|
|
if ($second > $this->httpTimeout) {
|
||
|
|
PHPUnit_Framework_Assert::fail(
|
||
|
|
"WaitFor timeout. \n"
|
||
|
|
. "Last exception message: \n" . $lastExceptionMessage
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$this->assertCommand($command, $arguments, $info);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
catch (Exception $e) {
|
||
|
|
$lastExceptionMessage = $e->getMessage();
|
||
|
|
}
|
||
|
|
|
||
|
|
sleep(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call
|
||
|
|
* for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(),
|
||
|
|
* store*(), waitFor*(), and waitForNot*() methods.
|
||
|
|
*/
|
||
|
|
protected static function autoGenerateCommands()
|
||
|
|
{
|
||
|
|
$method = new ReflectionMethod(__CLASS__, '__call');
|
||
|
|
$docComment = $method->getDocComment();
|
||
|
|
|
||
|
|
if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\((.*)\))', $docComment, $matches)) {
|
||
|
|
foreach ($matches[2] as $methodKey => $method) {
|
||
|
|
if (preg_match('/^(get|is)([A-Z].+)$/', $method, $methodMatches)) {
|
||
|
|
$baseName = $methodMatches[2];
|
||
|
|
$isBoolean = $methodMatches[1] == 'is';
|
||
|
|
$requiresTarget = (strlen($matches[3][$methodKey]) > 0);
|
||
|
|
|
||
|
|
if (preg_match('/^(.*)Present$/', $baseName, $methodMatches)) {
|
||
|
|
$notBaseName = $methodMatches[1] . 'NotPresent';
|
||
|
|
} else {
|
||
|
|
$notBaseName = 'Not' . $baseName;
|
||
|
|
}
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['store' . $baseName] = array(
|
||
|
|
'functionHelper' => FALSE
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['assert' . $baseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'functionHelper' => 'assertCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['assert' . $notBaseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'negative' => TRUE,
|
||
|
|
'functionHelper' => 'assertCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['verify' . $baseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'functionHelper' => 'verifyCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['verify' . $notBaseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'negative' => TRUE,
|
||
|
|
'functionHelper' => 'verifyCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['waitFor' . $baseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'functionHelper' => 'waitForCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
|
||
|
|
self::$autoGeneratedCommands['waitFor' . $notBaseName] = array(
|
||
|
|
'originalMethod' => $method,
|
||
|
|
'isBoolean' => $isBoolean,
|
||
|
|
'negative' => TRUE,
|
||
|
|
'functionHelper' => 'waitForCommand',
|
||
|
|
'requiresTarget' => $requiresTarget
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|