diff --git a/.travis.yml b/.travis.yml index 84d53110a686..fb0e3a767c75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,8 @@ env: global: - TEST_DAV=$(tests/travis/changed_app.sh dav) - TC=litmus-v2 + - SRV_HOST_NAME=owncloud + - SRV_HOST_PORT=8888 matrix: - DB=sqlite @@ -21,20 +23,30 @@ branches: only: - master - /^stable\d+(\.\d+)?$/ + - /^.*selenium.*$/ addons: apt: packages: - realpath + hosts: + - owncloud + sauce_connect: + username: "individual-it" + jwt: + secure: "WaPqAVjcC6B4T5NWA1nffrywsnR9UZ5u3c2DrNLDR12cXJti0SbxGcE2Er8EGS1iCMxqMnpZfchbCelYmew5FOyeErqMTtni3lZ1gAu4KM35V5gUaRau8uEvTZk7AVHfDRSYlB/TJJV8sl8I33i3UvzUgsz4Il41X8qribycQOWoUCsiABIy/Fm05MhWugKjzBJ3Au/ZnNkYEjLW5z1cPymiuvNsUGvm9ushu2WwEc31hsS9lvpOcNVgdPJy2OaxNIZip8yH0c9gteo6rE7oElc81773K4QFf/0H0pD7Q4lUhqdHTn/aNyqWu8QaiS2BtygFKR15vxqbkloPQovM7S/Xr+PV7wQxItLE/E0QD8FkvIjoIVC4L448Mw+zBntpdGtmV4/UJJLl+VRFlLf5l2Do5fum1SeLI0kYaaN9rTXsFp/rmC7vT6dk3CiAm9owD69uWTVUecTqx2gRgNRdEXvL7t/6AZ8kspmWYdL9ekBSQ83rXlo7p8ZZm/Iu4k10JPCKxGfxVHFLVlPB6Z43+yBAtNjLkPdDP3+2FxU4LvvDKKXn2eESwkG2Mq5dEm4HAethygPJ48QmTYGPgg4b6PlcxWHoiC7qGZYWYj0Pmxt3kE6iZ4wxHG4cCU5p0/2MyGXzynjLz1qC6CZtXZbuyXDfrjvwcPXvvuANg0IX3hw=" before_install: - make - - sh -c "if [ '$TEST_DAV' = '1' ]; then bash tests/travis/before_install.sh $DB; fi" + - if [ ! -z "$SAUCE_USERNAME" ] && [ ! -z "$SAUCE_ACCESS_KEY" ]; then export TEST_SELENIUM=1 ; else export TEST_SELENIUM=0 ; fi + - sh -c "if [ '$TEST_DAV' = '1' ] || [ '$TEST_SELENIUM' = '1' ]; then bash tests/travis/before_install.sh $DB; fi" install: - - sh -c "if [ '$TEST_DAV' = '1' ]; then bash tests/travis/install.sh $DB; fi" + - sh -c "if [ '$TEST_DAV' = '1' ] || [ '$TEST_SELENIUM' = '1' ]; then bash tests/travis/install.sh $DB; fi" - sh -c "if [ '$TEST_DAV' = '1' ]; then bash apps/dav/tests/travis/$TC/install.sh; fi" +before_script: + - sh -c "if [ '$TEST_SELENIUM' = '1' ]; then bash tests/travis/start_php_dev_server.sh; fi" script: - sh -c "if [ '$TC' = 'syntax' ]; then make test-php-lint ; fi" @@ -42,6 +54,7 @@ script: - sh -c "if [ '$TEST_DAV' = '1' ]; then echo \"Testing DAV\"; fi" - sh -c "if [ '$TEST_DAV' = '1' ]; then bash apps/dav/tests/travis/$TC/script.sh; fi" + - sh -c "if [ '$TEST_SELENIUM' = '1' ]; then phpunit -c tests/phpunit-selenium-autotest.xml; fi" matrix: include: diff --git a/tests/Core/Frontend/LoginTest.php b/tests/Core/Frontend/LoginTest.php new file mode 100644 index 000000000000..d0f68cd31ec4 --- /dev/null +++ b/tests/Core/Frontend/LoginTest.php @@ -0,0 +1,44 @@ +. +* +*/ + +use Test\SeleniumTestCase; + +class LoginTest extends SeleniumTestCase { + + public function testNormalLogin() { + + $this->webDriver->get($this->rootURL); + $login = $this->webDriver->findElement ( WebDriverBy::id("user")); + $login->click(); + $login->sendKeys("admin"); + + $login = $this->webDriver->findElement ( WebDriverBy::id("password")); + $login->click(); + $login->sendKeys("admin"); + + $login = $this->webDriver->findElement ( WebDriverBy::id("submit")); + $login->click(); + sleep(5); + $fileElement = $this->webDriver->findElement(WebDriverBy::xpath("//span[@class='innernametext']")); + $this->assertEquals($fileElement->getText(), "welcome"); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2746405a387e..d6c750db9dad 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,6 +7,7 @@ } require_once __DIR__ . '/../lib/base.php'; +require_once __DIR__ . '/vendor/facebook/webdriver/lib/__init__.php'; // especially with code coverage it will require some more time set_time_limit(0); diff --git a/tests/lib/SeleniumTestCase.php b/tests/lib/SeleniumTestCase.php new file mode 100644 index 000000000000..8d1faa728af5 --- /dev/null +++ b/tests/lib/SeleniumTestCase.php @@ -0,0 +1,98 @@ +. +* +*/ + +namespace Test; + +use Test\TestCase; + +abstract class SeleniumTestCase extends TestCase { + protected $webDriver; + protected $rootURL; + + protected function setUp() { + parent::setUp(); + + $sauceUserName = getenv("SAUCE_USERNAME"); + $sauceAccessKey = getenv("SAUCE_ACCESS_KEY"); + $capabilities = array ( + \WebDriverCapabilityType::BROWSER_NAME => 'chrome', + 'tunnel-identifier' => getenv('TRAVIS_JOB_NUMBER') + ); + $this->rootURL="http://". getenv('SRV_HOST_NAME') .":" . getenv('SRV_HOST_PORT'). "/" . getenv('SRV_HOST_URL'); + + if ($sauceAccessKey != "") { + $this->webDriver = \RemoteWebDriver::create ( 'http://'.$sauceUserName.':'.$sauceAccessKey.'@localhost:4445/wd/hub', $capabilities ); + } else { + $this->webDriver = \RemoteWebDriver::create ( 'http://localhost:4444/wd/hub', $capabilities ); + } + + } + + public static function setUpBeforeClass() { + $dataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data-autotest'); + if (!file_exists($dataDir . "/admin")) { + mkdir($dataDir . "/admin"); + mkdir($dataDir . "/admin/files"); + copy(\OC::$SERVERROOT . '/core/skeleton/welcome.txt', $dataDir. "/admin/files/welcome.txt"); + } + } + + protected function tearDown() { + parent::tearDown(); + $this->webDriver->quit (); + } + + /** + * waits till an element is displayed on page + * @param WebDriverElement $element to wait for + * @param INT $timeout max. time to wait + */ + protected function waitTillElementIsDisplayed($element, $timeout = 30) { + for($counter = 0; $counter <= $timeout; $counter ++) { + try { + if ($element->isDisplayed () === false) { + break; + } + } catch ( Exception $e ) { + break; + } + + sleep (1); + } + } + + /** + * waits till an element is stale + * @param WebDriverElement $element to wait for + * @param INT $timeout max. time to wait + */ + protected function waitTillElementIsStale($element, $timeout = 30) { + for ($i=0; $i<=$timeout; $i++) { + try { + $element->findElements(\WebDriverBy::id("does-not-matter")); + } catch (StaleElementReferenceException $e) { + return true; + } + sleep(1); + } + } +} diff --git a/tests/phpunit-selenium-autotest.xml b/tests/phpunit-selenium-autotest.xml new file mode 100644 index 000000000000..a25f5a5513ff --- /dev/null +++ b/tests/phpunit-selenium-autotest.xml @@ -0,0 +1,21 @@ + + + + Core/Frontend + + + + + + .. + + + + + + diff --git a/tests/travis/install.sh b/tests/travis/install.sh index fe7907f798ca..b91f77147001 100755 --- a/tests/travis/install.sh +++ b/tests/travis/install.sh @@ -45,6 +45,11 @@ cat > ./tests/autoconfig-sqlite.php < false, + 'trusted_domains' => + array ( + 0 => 'localhost', + 1 => '$SRV_HOST_NAME', + ), 'dbtype' => 'sqlite', 'dbtableprefix' => 'oc_', 'adminlogin' => '$ADMINLOGIN', @@ -57,6 +62,11 @@ cat > ./tests/autoconfig-mysql.php < false, + 'trusted_domains' => + array ( + 0 => 'localhost', + 1 => '$SRV_HOST_NAME', + ), 'dbtype' => 'mysql', 'dbtableprefix' => 'oc_', 'adminlogin' => '$ADMINLOGIN', @@ -73,6 +83,11 @@ cat > ./tests/autoconfig-pgsql.php < false, + 'trusted_domains' => + array ( + 0 => 'localhost', + 1 => '$SRV_HOST_NAME', + ), 'dbtype' => 'pgsql', 'dbtableprefix' => 'oc_', 'adminlogin' => '$ADMINLOGIN', @@ -89,6 +104,11 @@ cat > ./tests/autoconfig-oracle.php < false, + 'trusted_domains' => + array ( + 0 => 'localhost', + 1 => '$SRV_HOST_NAME', + ), 'dbtype' => 'oci', 'dbtableprefix' => 'oc_', 'adminlogin' => '$ADMINLOGIN', diff --git a/tests/travis/start_php_dev_server.sh b/tests/travis/start_php_dev_server.sh new file mode 100644 index 000000000000..c7e644c0f7c0 --- /dev/null +++ b/tests/travis/start_php_dev_server.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# +# ownCloud +# +# @author Artur Neumann +# @copyright 2017 Artur Neumann info@individual-it.net +# + + +set -e + +php -S $SRV_HOST_NAME:$SRV_HOST_PORT > /dev/null 2>&1 & diff --git a/tests/vendor/facebook/webdriver/README.md b/tests/vendor/facebook/webdriver/README.md new file mode 100644 index 000000000000..d5272c4f4a49 --- /dev/null +++ b/tests/vendor/facebook/webdriver/README.md @@ -0,0 +1,105 @@ +php-webdriver -- WebDriver bindings for PHP +=========================================== + +## DESCRIPTION + +This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. + +Looking for documentation about php-webdriver? See http://facebook.github.io/php-webdriver/ + +The PHP client was rewritten from scratch. Using the old version? Check out Adam Goucher's fork of it at https://github.com/Element-34/php-webdriver + +Any complaint, question, idea? You can post it on the user group https://www.facebook.com/groups/phpwebdriver/. + +## GETTING THE CODE + +### Github + git clone git@github.com:facebook/php-webdriver.git + +### Packagist +Add the dependency. https://packagist.org/packages/facebook/webdriver + + { + "require": { + "facebook/webdriver": "dev-master" + } + } + +Download the composer.phar + + curl -sS https://getcomposer.org/installer | php + +Install the library. + + php composer.phar install + + + +## GETTING STARTED + +* All you need as the server for this client is the selenium-server-standalone-#.jar file provided here: http://selenium-release.storage.googleapis.com/index.html + +* Download and run that file, replacing # with the current server version. + + java -jar selenium-server-standalone-#.jar + +* Then when you create a session, be sure to pass the url to where your server is running. + + // This would be the url of the host running the server-standalone.jar + $host = 'http://localhost:4444/wd/hub'; // this is the default + +* Launch Firefox + + $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); + +* Launch Chrome + + $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); + +* You can also customize the desired capabilities. + + $desired_capabilities = DesiredCapabilities::firefox(); + $desired_capabilities->setJavascriptEnabled(false); + RemoteWebDriver::create($host, $desired_capabilities); + +* See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. + +## RUN UNIT TESTS + +To run unit tests simply run: + + ./vendor/bin/phpunit -c ./tests + +Note: For the functional test suite, a running selenium server is required. + +## MORE INFORMATION + +Check out the Selenium docs and wiki at http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki + +Learn how to integrate it with PHPUnit [Blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) | [Demo Project](https://github.com/DavertMik/php-webdriver-demo) + +## SUPPORT + +We have a great community willing to try and help you! + +Currently we offer support in two manners: + +### Via our Facebook Group + +If you have questions or are an active contributor consider joining our facebook group and contributing to the communal discussion and support + +https://www.facebook.com/groups/phpwebdriver/ + +### Via Github + +If you're reading this you've already found our Github repository. If you have a question, feel free to submit it as an issue and our staff will do their best to help you as soon as possible. + +## CONTRIBUTING + +We love to have your help to make php-webdriver better. Feel free to + +* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. + +When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. +FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) diff --git a/tests/vendor/facebook/webdriver/composer.json b/tests/vendor/facebook/webdriver/composer.json new file mode 100644 index 000000000000..00faaa7bf5e6 --- /dev/null +++ b/tests/vendor/facebook/webdriver/composer.json @@ -0,0 +1,23 @@ +{ + "name": "facebook/webdriver", + "description": "A php client for WebDriver", + "keywords": ["webdriver", "selenium", "php", "facebook"], + "homepage": "https://github.com/facebook/php-webdriver", + "type": "library", + "license": "Apache-2.0", + "support": { + "issues": "https://github.com/facebook/php-webdriver/issues", + "forum": "https://www.facebook.com/groups/phpwebdriver/", + "source": "https://github.com/facebook/php-webdriver" + }, + "require": { + "php": ">=5.3.19" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "phpdocumentor/phpdocumentor": "2.*" + }, + "autoload": { + "classmap": ["lib/"] + } +} diff --git a/tests/vendor/facebook/webdriver/example.php b/tests/vendor/facebook/webdriver/example.php new file mode 100644 index 000000000000..a1e133b912e9 --- /dev/null +++ b/tests/vendor/facebook/webdriver/example.php @@ -0,0 +1,49 @@ +get('http://docs.seleniumhq.org/'); + +// adding cookie +$driver->manage()->deleteAllCookies(); +$driver->manage()->addCookie(array( + 'name' => 'cookie_name', + 'value' => 'cookie_value', +)); +$cookies = $driver->manage()->getCookies(); +print_r($cookies); + +// click the link 'About' +$link = $driver->findElement( + WebDriverBy::id('menu_about') +); +$link->click(); + +// print the title of the current page +echo "The title is " . $driver->getTitle() . "'\n"; + +// print the title of the current page +echo "The current URI is " . $driver->getCurrentURL() . "'\n"; + +// Search 'php' in the search box +$input = $driver->findElement( + WebDriverBy::id('q') +); +$input->sendKeys('php')->submit(); + +// wait at most 10 seconds until at least one result is shown +$driver->wait(10)->until( + WebDriverExpectedCondition::presenceOfAllElementsLocatedBy( + WebDriverBy::className('gsc-result') + ) +); + +// close the Firefox +$driver->quit(); diff --git a/tests/vendor/facebook/webdriver/lib/JavaScriptExecutor.php b/tests/vendor/facebook/webdriver/lib/JavaScriptExecutor.php new file mode 100644 index 000000000000..131a7fef19d5 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/JavaScriptExecutor.php @@ -0,0 +1,47 @@ +wait(20, 1000)->until( + * WebDriverExpectedCondition::titleIs('WebDriver Page') + * ); + * + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * @return WebDriverWait + */ + public function wait( + $timeout_in_second = 30, + $interval_in_millisecond = 250); + + /** + * An abstraction for managing stuff you would do in a browser menu. For + * example, adding and deleting cookies. + * + * @return WebDriverOptions + */ + public function manage(); + + /** + * An abstraction allowing the driver to access the browser's history and to + * navigate to a given URL. + * + * @return WebDriverNavigation + * @see WebDriverNavigation + */ + public function navigate(); + + /** + * Switch to a different window or frame. + * + * @return WebDriverTargetLocator + * @see WebDriverTargetLocator + */ + public function switchTo(); + + /** + * @param string $name + * @param array $params + * @return mixed + */ + public function execute($name, $params); +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverAction.php b/tests/vendor/facebook/webdriver/lib/WebDriverAction.php new file mode 100644 index 000000000000..80a310a641a4 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverAction.php @@ -0,0 +1,25 @@ +executor = $executor; + } + + /** + * Accept alert + * + * @return WebDriverAlert The instance. + */ + public function accept() { + $this->executor->execute(DriverCommand::ACCEPT_ALERT); + return $this; + } + + /** + * Dismiss alert + * + * @return WebDriverAlert The instance. + */ + public function dismiss() { + $this->executor->execute(DriverCommand::DISMISS_ALERT); + return $this; + } + + /** + * Get alert text + * + * @return string + */ + public function getText() { + return $this->executor->execute(DriverCommand::GET_ALERT_TEXT); + } + + /** + * Send keystrokes to javascript prompt() dialog + * + * @param string $value + * @return WebDriverAlert + */ + public function sendKeys($value) { + $this->executor->execute( + DriverCommand::SET_ALERT_VALUE, + array('text' => $value) + ); + return $this; + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverBy.php b/tests/vendor/facebook/webdriver/lib/WebDriverBy.php new file mode 100644 index 000000000000..3409afd2588c --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverBy.php @@ -0,0 +1,128 @@ +mechanism = $mechanism; + $this->value = $value; + } + + /** + * @return string + */ + public function getMechanism() { + return $this->mechanism; + } + + /** + * @return string + */ + public function getValue() { + return $this->value; + } + + /** + * Locates elements whose class name contains the search value; compound class + * names are not permitted. + * + * @param string $class_name + * @return WebDriverBy + */ + public static function className($class_name) { + return new WebDriverBy('class name', $class_name); + } + + /** + * Locates elements matching a CSS selector. + * + * @param string $css_selector + * @return WebDriverBy + */ + public static function cssSelector($css_selector) { + return new WebDriverBy('css selector', $css_selector); + } + + /** + * Locates elements whose ID attribute matches the search value. + * + * @param string $id + * @return WebDriverBy + */ + public static function id($id) { + return new WebDriverBy('id', $id); + } + + /** + * Locates elements whose NAME attribute matches the search value. + * + * @param string $name + * @return WebDriverBy + */ + public static function name($name) { + return new WebDriverBy('name', $name); + } + + /** + * Locates anchor elements whose visible text matches the search value. + * + * @param string $link_text + * @return WebDriverBy + */ + public static function linkText($link_text) { + return new WebDriverBy('link text', $link_text); + } + + /** + * Locates anchor elements whose visible text partially matches the search + * value. + * + * @param string $partial_link_text + * @return WebDriverBy + */ + public static function partialLinkText($partial_link_text) { + return new WebDriverBy('partial link text', $partial_link_text); + } + + /** + * Locates elements whose tag name matches the search value. + * + * @param string $tag_name + * @return WebDriverBy + */ + public static function tagName($tag_name) { + return new WebDriverBy('tag name', $tag_name); + } + + /** + * Locates elements matching an XPath expression. + * + * @param string $xpath + * @return WebDriverBy + */ + public static function xpath($xpath) { + return new WebDriverBy('xpath', $xpath); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverCapabilities.php b/tests/vendor/facebook/webdriver/lib/WebDriverCapabilities.php new file mode 100644 index 000000000000..1e70efb2cf25 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverCapabilities.php @@ -0,0 +1,49 @@ +width = $width; + $this->height = $height; + } + + /** + * Get the height. + * + * @return int The height. + */ + public function getHeight() { + return $this->height; + } + + /** + * Get the width. + * + * @return int The width. + */ + public function getWidth() { + return $this->width; + } + + /** + * Check whether the given dimension is the same as the instance. + * + * @param WebDriverDimension $dimension The dimension to be compared with. + * @return bool Whether the height and the width are the same as the + * instance. + */ + public function equals(WebDriverDimension $dimension) { + return $this->height === $dimension->getHeight() && + $this->width === $dimension->getWidth(); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverDispatcher.php b/tests/vendor/facebook/webdriver/lib/WebDriverDispatcher.php new file mode 100644 index 000000000000..c5c4f191fbae --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverDispatcher.php @@ -0,0 +1,80 @@ +driver = $driver; + return $this; + } + + /** + * @return null|EventFiringWebDriver + */ + public function getDefaultDriver() { + return $this->driver; + } + + /** + * @param WebDriverEventListener $listener + * @return $this + */ + public function register(WebDriverEventListener $listener) { + $this->listeners[] = $listener; + return $this; + } + + /** + * @param WebDriverEventListener $listener + * @return $this + */ + public function unregister(WebDriverEventListener $listener) { + $key = array_search($listener, $this->listeners, true); + if ($key !== false) { + unset($this->listeners[$key]); + } + return $this; + } + + /** + * @param mixed $method + * @param mixed $arguments + * @return $this + */ + public function dispatch($method, $arguments) { + foreach ($this->listeners as $listener) { + call_user_func_array(array($listener, $method), $arguments); + } + return $this; + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverElement.php b/tests/vendor/facebook/webdriver/lib/WebDriverElement.php new file mode 100644 index 000000000000..62a0a1543916 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverElement.php @@ -0,0 +1,134 @@ +results = $results; + } + + /** + * @return mixed + */ + public function getResults() { + return $this->results; + } + + /** + * Throw WebDriverExceptions. + * For $status_code >= 0, they are errors defined in the json wired protocol. + * For $status_code < 0, they are errors defined in php-webdriver. + * + * @param int $status_code + * @param string $message + * @param mixed $results + */ + public static function throwException($status_code, $message, $results) { + switch ($status_code) { + case -1: + throw new WebDriverCurlException($message); + case 0: + // Success + break; + case 1: + throw new IndexOutOfBoundsException($message, $results); + case 2: + throw new NoCollectionException($message, $results); + case 3: + throw new NoStringException($message, $results); + case 4: + throw new NoStringLengthException($message, $results); + case 5: + throw new NoStringWrapperException($message, $results); + case 6: + throw new NoSuchDriverException($message, $results); + case 7: + throw new NoSuchElementException($message, $results); + case 8: + throw new NoSuchFrameException($message, $results); + case 9: + throw new UnknownCommandException($message, $results); + case 10: + throw new StaleElementReferenceException($message, $results); + case 11: + throw new ElementNotVisibleException($message, $results); + case 12: + throw new InvalidElementStateException($message, $results); + case 13: + throw new UnknownServerException($message, $results); + case 14: + throw new ExpectedException($message, $results); + case 15: + throw new ElementNotSelectableException($message, $results); + case 16: + throw new NoSuchDocumentException($message, $results); + case 17: + throw new UnexpectedJavascriptException($message, $results); + case 18: + throw new NoScriptResultException($message, $results); + case 19: + throw new XPathLookupException($message, $results); + case 20: + throw new NoSuchCollectionException($message, $results); + case 21: + throw new TimeOutException($message, $results); + case 22: + throw new NullPointerException($message, $results); + case 23: + throw new NoSuchWindowException($message, $results); + case 24: + throw new InvalidCookieDomainException($message, $results); + case 25: + throw new UnableToSetCookieException($message, $results); + case 26: + throw new UnexpectedAlertOpenException($message, $results); + case 27: + throw new NoAlertOpenException($message, $results); + case 28: + throw new ScriptTimeoutException($message, $results); + case 29: + throw new InvalidCoordinatesException($message, $results); + case 30: + throw new IMENotAvailableException($message, $results); + case 31: + throw new IMEEngineActivationFailedException($message, $results); + case 32: + throw new InvalidSelectorException($message, $results); + case 33: + throw new SessionNotCreatedException($message, $results); + case 34: + throw new MoveTargetOutOfBoundsException($message, $results); + default: + throw new UnrecognizedExceptionException($message, $results); + } + } +} + +class IndexOutOfBoundsException extends WebDriverException {} // 1 +class NoCollectionException extends WebDriverException {} // 2 +class NoStringException extends WebDriverException {} // 3 +class NoStringLengthException extends WebDriverException {} // 4 +class NoStringWrapperException extends WebDriverException {} // 5 +class NoSuchDriverException extends WebDriverException {} // 6 +class NoSuchElementException extends WebDriverException {} // 7 +class NoSuchFrameException extends WebDriverException {} // 8 +class UnknownCommandException extends WebDriverException {} // 9 +class StaleElementReferenceException extends WebDriverException {} // 10 +class ElementNotVisibleException extends WebDriverException {} // 11 +class InvalidElementStateException extends WebDriverException {} // 12 +class UnknownServerException extends WebDriverException {} // 13 +class ExpectedException extends WebDriverException {} // 14 +class ElementNotSelectableException extends WebDriverException {} // 15 +class NoSuchDocumentException extends WebDriverException {} // 16 +class UnexpectedJavascriptException extends WebDriverException {} // 17 +class NoScriptResultException extends WebDriverException {} // 18 +class XPathLookupException extends WebDriverException {} // 19 +class NoSuchCollectionException extends WebDriverException {} // 20 +class TimeOutException extends WebDriverException {} // 21 +class NullPointerException extends WebDriverException {} // 22 +class NoSuchWindowException extends WebDriverException {} // 23 +class InvalidCookieDomainException extends WebDriverException {} // 24 +class UnableToSetCookieException extends WebDriverException {} // 25 +class UnexpectedAlertOpenException extends WebDriverException {} // 26 +class NoAlertOpenException extends WebDriverException {} // 27 +class ScriptTimeoutException extends WebDriverException {} // 28 +class InvalidCoordinatesException extends WebDriverException {}// 29 +class IMENotAvailableException extends WebDriverException {} // 30 +class IMEEngineActivationFailedException extends WebDriverException {}// 31 +class InvalidSelectorException extends WebDriverException {} // 32 +class SessionNotCreatedException extends WebDriverException {} // 33 +class MoveTargetOutOfBoundsException extends WebDriverException {} // 34 + +// Fallback +class UnrecognizedExceptionException extends WebDriverException {} + +class UnexpectedTagNameException extends WebDriverException { + + /** + * @param string $expected_tag_name + * @param string $actual_tag_name + */ + public function __construct( + $expected_tag_name, + $actual_tag_name) { + parent::__construct( + sprintf( + "Element should have been \"%s\" but was \"%s\"", + $expected_tag_name, $actual_tag_name + ) + ); + } +} + +class UnsupportedOperationException extends WebDriverException {} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverExpectedCondition.php b/tests/vendor/facebook/webdriver/lib/WebDriverExpectedCondition.php new file mode 100644 index 000000000000..ca9f4df7cd60 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverExpectedCondition.php @@ -0,0 +1,409 @@ +apply; + } + + protected function __construct($apply) { + $this->apply = $apply; + } + + /** + * An expectation for checking the title of a page. + * + * @param string $title The expected title, which must be an exact match. + * @return bool WebDriverExpectedCondition True when the title matches, + * false otherwise. + */ + public static function titleIs($title) { + return new WebDriverExpectedCondition( + function ($driver) use ($title) { + return $title === $driver->getTitle(); + } + ); + } + + /** + * An expectation for checking substring of a page Title. + * + * @param string $title The expected substring of Title. + * @return bool WebDriverExpectedCondition True when in title, + * false otherwise. + */ + public static function titleContains($title) { + return new WebDriverExpectedCondition( + function ($driver) use ($title) { + return strpos($driver->getTitle(), $title) !== false; + } + ); + } + + /** + * An expectation for checking that an element is present on the DOM of a + * page. This does not necessarily mean that the element is visible. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition The element which + * is located. + */ + public static function presenceOfElementLocated(WebDriverBy $by) { + return new WebDriverExpectedCondition( + function ($driver) use ($by) { + return $driver->findElement($by); + } + ); + } + + /** + * An expectation for checking that an element is present on the DOM of a page + * and visible. Visibility means that the element is not only displayed but + * also has a height and width that is greater than 0. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition The element which is + * located and visible. + */ + public static function visibilityOfElementLocated(WebDriverBy $by) { + return new WebDriverExpectedCondition( + function ($driver) use ($by) { + try { + $element = $driver->findElement($by); + return $element->isDisplayed() ? $element : null; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking that an element, known to be present on the DOM + * of a page, is visible. Visibility means that the element is not only + * displayed but also has a height and width that is greater than 0. + * + * @param WebDriverElement $element The element to be checked. + * @return WebDriverExpectedCondition The same + * WebDriverElement once it is visible. + */ + public static function visibilityOf(WebDriverElement $element) { + return new WebDriverExpectedCondition( + function ($driver) use ($element) { + return $element->isDisplayed() ? $element : null; + } + ); + } + + /** + * An expectation for checking that there is at least one element present on a + * web page. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition An array of WebDriverElements + * once they are located. + */ + public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { + return new WebDriverExpectedCondition( + function ($driver) use ($by) { + $elements = $driver->findElements($by); + return count($elements) > 0 ? $elements : null; + } + ); + } + + /** + * An expectation for checking if the given text is present in the specified + * element. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element. + * @return bool WebDriverExpectedCondition Whether the text is presented. + */ + public static function textToBePresentInElement( + WebDriverBy $by, $text) { + return new WebDriverExpectedCondition( + function ($driver) use ($by, $text) { + try { + $element_text = $driver->findElement($by)->getText(); + return strpos($element_text, $text) !== false; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking if the given text is present in the specified + * elements value attribute. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element value. + * @return bool WebDriverExpectedCondition Whether the text is presented. + */ + public static function textToBePresentInElementValue( + WebDriverBy $by, $text) { + return new WebDriverExpectedCondition( + function ($driver) use ($by, $text) { + try { + $element_text = $driver->findElement($by)->getAttribute('value'); + return strpos($element_text, $text) !== false; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * Expectation for checking if iFrame exists. + * If iFrame exists switches driver's focus to the iFrame + * + * @param string $frame_locator The locator used to find the iFrame + * expected to be either the id or name value of the i/frame + * @return WebDriverExpectedCondition object focused on new frame + * when frame is found bool false otherwise + */ + public static function frameToBeAvailableAndSwitchToIt($frame_locator) { + return new WebDriverExpectedCondition( + function ($driver) use ($frame_locator) { + try { + return $driver->switchTo()->frame($frame_locator); + } catch (NoSuchFrameException $e) { + return false; + } + } + ); + } + + /** + * An expectation for checking that an element is either invisible or not + * present on the DOM. + * + * @param WebDriverBy $by The locator used to find the element. + * @return bool WebDriverExpectedCondition Whether there is no element + * located. + */ + public static function invisibilityOfElementLocated(WebDriverBy $by) { + return new WebDriverExpectedCondition( + function ($driver) use ($by) { + try { + return !($driver->findElement($by)->isDisplayed()); + } catch (NoSuchElementException $e) { + return true; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * An expectation for checking that an element with text is either invisible + * or not present on the DOM. + * + * @param WebdriverBy $by The locator used to find the element. + * @param string $text The text of the element. + * @return bool WebDriverExpectedCondition Whether the text is found in the + * element located. + */ + public static function invisibilityOfElementWithText( + WebDriverBy $by, $text) { + return new WebDriverExpectedCondition( + function ($driver) use ($by, $text) { + try { + return !($driver->findElement($by)->getText() === $text); + } catch (NoSuchElementException $e) { + return true; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * An expectation for checking an element is visible and enabled such that you + * can click it. + * + * @param WebDriverBy $by The locator used to find the element + * @return WebDriverExpectedCondition The WebDriverElement + * once it is located, visible and clickable + */ + public static function elementToBeClickable(WebDriverBy $by) { + $visibility_of_element_located = + WebDriverExpectedCondition::visibilityOfElementLocated($by); + return new WebDriverExpectedCondition( + function ($driver) use ($visibility_of_element_located) { + $element = call_user_func( + $visibility_of_element_located->getApply(), + $driver + ); + try { + if ($element !== null && $element->isEnabled()) { + return $element; + } else { + return null; + } + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * Wait until an element is no longer attached to the DOM. + * + * @param WebDriverElement $element The element to wait for. + * @return bool WebDriverExpectedCondition false if the element is still + * attached to the DOM, true otherwise. + */ + public static function stalenessOf(WebDriverElement $element) { + return new WebDriverExpectedCondition( + function ($driver) use ($element) { + try { + $element->isEnabled(); + return false; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * Wrapper for a condition, which allows for elements to update by redrawing. + * + * This works around the problem of conditions which have two parts: find an + * element and then check for some condition on it. For these conditions it is + * possible that an element is located and then subsequently it is redrawn on + * the client. When this happens a StaleElementReferenceException is thrown + * when the second part of the condition is checked. + * + * @param WebDriverExpectedCondition $condition The condition wrapped. + * @return WebDriverExpectedCondition The return value of the + * getApply() of the given condition. + */ + public static function refreshed(WebDriverExpectedCondition $condition) { + return new WebDriverExpectedCondition( + function ($driver) use ($condition) { + try { + return call_user_func($condition->getApply(), $driver); + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking if the given element is selected. + * + * @param mixed $element_or_by Either the element or the locator. + * @return bool WebDriverExpectedCondition whether the element is selected. + */ + public static function elementToBeSelected($element_or_by) { + return WebDriverExpectedCondition::elementSelectionStateToBe( + $element_or_by, + true + ); + } + + /** + * An expectation for checking if the given element is selected. + * + * @param mixed $element_or_by Either the element or the locator. + * @param bool $selected The required state. + * @return bool WebDriverExpectedCondition Whether the element is selected. + */ + public static function elementSelectionStateToBe( + $element_or_by, + $selected + ) { + if ($element_or_by instanceof WebDriverElement) { + return new WebDriverExpectedCondition( + function ($driver) use ($element_or_by, $selected) { + return $element_or_by->isSelected() === $selected; + } + ); + } else if ($element_or_by instanceof WebDriverBy) { + return new WebDriverExpectedCondition( + function ($driver) use ($element_or_by, $selected) { + try { + $element = $driver->findElement($element_or_by); + return $element->isSelected() === $selected; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + } + + /** + * An expectation for whether an alert() box is present. + * + * @return WebDriverExpectedCondition if alert() is present, + * null otherwise. + */ + public static function alertIsPresent() { + return new WebDriverExpectedCondition( + function ($driver) { + try { + // Unlike the Java code, we get a WebDriverAlert object regardless + // of whether there is an alert. Calling getText() will throw + // an exception if it is not really there. + $alert = $driver->switchTo()->alert(); + $alert->getText(); + return $alert; + } catch (NoAlertOpenException $e) { + return null; + } + } + ); + } + + /** + * An expectation with the logical opposite condition of the given condition. + * + * @param WebDriverExpectedCondition $condition The condition to be negated. + * @return mixed The negation of the result of the given condition. + */ + public static function not(WebDriverExpectedCondition $condition) { + return new WebDriverExpectedCondition( + function ($driver) use ($condition) { + $result = call_user_func($condition->getApply(), $driver); + return !$result; + } + ); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverHasInputDevices.php b/tests/vendor/facebook/webdriver/lib/WebDriverHasInputDevices.php new file mode 100644 index 000000000000..949c26dc8db6 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverHasInputDevices.php @@ -0,0 +1,30 @@ +executor = $executor; + } + + /** + * Move back a single entry in the browser's history, if possible. + * + * @return WebDriverNavigation The instance. + */ + public function back() { + $this->executor->execute(DriverCommand::GO_BACK); + return $this; + } + + /** + * Move forward a single entry in the browser's history, if possible. + * + * @return WebDriverNavigation The instance. + */ + public function forward() { + $this->executor->execute(DriverCommand::GO_FORWARD); + return $this; + } + + /** + * Refresh the current page. + * + * @return WebDriverNavigation The instance. + */ + public function refresh() { + $this->executor->execute(DriverCommand::REFRESH); + return $this; + } + + /** + * Navigate to the given URL. + * + * @param string $url + * @return WebDriverNavigation The instance. + */ + public function to($url) { + $params = array('url' => (string)$url); + $this->executor->execute(DriverCommand::GET, $params); + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverOptions.php b/tests/vendor/facebook/webdriver/lib/WebDriverOptions.php new file mode 100644 index 000000000000..61b5eb16f68d --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverOptions.php @@ -0,0 +1,167 @@ +executor = $executor; + } + + /** + * Add a specific cookie. + * + * Here are the valid attributes of a cookie array. + * 'name' : string The name of the cookie; may not be null or an empty + * string. + * 'value' : string The cookie value; may not be null. + * 'path' : string The path the cookie is visible to. If left blank or set + * to null, will be set to "/". + * 'domain': string The domain the cookie is visible to. It should be null or + * the same as the domain of the current URL. + * 'secure': bool Whether this cookie requires a secure connection(https?). + * It should be null or equal to the security of the current + * URL. + * 'expiry': int The cookie's expiration date; may be null. + * + * @param array $cookie An array with key as the attributes mentioned above. + * @return WebDriverOptions The current instance. + */ + public function addCookie(array $cookie) { + $this->validate($cookie); + $this->executor->execute( + DriverCommand::ADD_COOKIE, + array('cookie' => $cookie) + ); + return $this; + } + + /** + * Delete all the cookies that are currently visible. + * + * @return WebDriverOptions The current instance. + */ + public function deleteAllCookies() { + $this->executor->execute(DriverCommand::DELETE_ALL_COOKIES); + return $this; + } + + /** + * Delete the cookie with the give name. + * + * @param string $name + * @return WebDriverOptions The current instance. + */ + public function deleteCookieNamed($name) { + $this->executor->execute( + DriverCommand::DELETE_COOKIE, + array(':name' => $name) + ); + return $this; + } + + /** + * Get the cookie with a given name. + * + * @param string $name + * @return array The cookie, or null if no cookie with the given name is + * presented. + */ + public function getCookieNamed($name) { + $cookies = $this->getCookies(); + foreach ($cookies as $cookie) { + if ($cookie['name'] === $name) { + return $cookie; + } + } + return null; + } + + /** + * Get all the cookies for the current domain. + * + * @return array The array of cookies presented. + */ + public function getCookies() { + return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); + } + + private function validate(array $cookie) { + if (!isset($cookie['name']) || + $cookie['name'] === '' || + strpos($cookie['name'], ';') !== false) { + throw new InvalidArgumentException( + '"name" should be non-empty and does not contain a ";"'); + } + + if (!isset($cookie['value'])) { + throw new InvalidArgumentException( + '"value" is required when setting a cookie.'); + } + + if (isset($cookie['domain']) && strpos($cookie['domain'], ':') !== false) { + throw new InvalidArgumentException( + '"domain" should not contain a port:'.(string)$cookie['domain']); + } + } + + /** + * Return the interface for managing driver timeouts. + * + * @return WebDriverTimeouts + */ + public function timeouts() { + return new WebDriverTimeouts($this->executor); + } + + /** + * An abstraction allowing the driver to manipulate the browser's window + * + * @return WebDriverWindow + * @see WebDriverWindow + */ + public function window() { + return new WebDriverWindow($this->executor); + } + + /** + * Get the log for a given log type. Log buffer is reset after each request. + * + * @param string $log_type The log type. + * @return array The list of log entries. + * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + */ + public function getLog($log_type) { + return $this->executor->execute( + DriverCommand::GET_LOG, + array('type' => $log_type) + ); + } + + /** + * Get available log types. + * + * @return array The list of available log types. + * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + */ + public function getAvailableLogTypes() { + return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverPlatform.php b/tests/vendor/facebook/webdriver/lib/WebDriverPlatform.php new file mode 100644 index 000000000000..9d0e413fc7d6 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverPlatform.php @@ -0,0 +1,29 @@ +x = $x; + $this->y = $y; + } + + /** + * Get the x-coordinate. + * + * @return int The x-coordinate of the point. + */ + public function getX() { + return $this->x; + } + + /** + * Get the y-coordinate. + * + * @return int The y-coordinate of the point. + */ + public function getY() { + return $this->y; + } + + /** + * Set the point to a new position. + * + * @param int $new_x + * @param int $new_y + * @return WebDriverPoint The same instance with updated coordinates. + */ + public function move($new_x, $new_y) { + $this->x = $new_x; + $this->y = $new_y; + return $this; + } + + /** + * Move the current by offsets. + * + * @param int $x_offset + * @param int $y_offset + * @return WebDriverPoint The same instance with updated coordinates. + */ + public function moveBy($x_offset, $y_offset) { + $this->x += $x_offset; + $this->y += $y_offset; + return $this; + } + + /** + * Check whether the given point is the same as the instance. + * + * @param WebDriverPoint $point The point to be compared with. + * @return bool Whether the x and y coordinates are the same as the instance. + */ + public function equals(WebDriverPoint $point) { + return $this->x === $point->getX() && + $this->y === $point->getY(); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverSearchContext.php b/tests/vendor/facebook/webdriver/lib/WebDriverSearchContext.php new file mode 100644 index 000000000000..dacea3f333ea --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverSearchContext.php @@ -0,0 +1,42 @@ +getTagName(); + + if ($tag_name !== 'select') { + throw new UnexpectedTagNameException('select', $tag_name); + } + $this->element = $element; + $value = $element->getAttribute('multiple'); + $this->isMulti = ($value === 'true'); + } + + /** + * @return bool Whether this select element support selecting multiple + * options. This is done by checking the value of the 'multiple' + * attribute. + */ + public function isMultiple() { + return $this->isMulti; + } + + /** + * @return array All options belonging to this select tag. + */ + public function getOptions() { + return $this->element->findElements(WebDriverBy::tagName('option')); + } + + /** + * @return array All selected options belonging to this select tag. + */ + public function getAllSelectedOptions() { + $selected_options = array(); + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + $selected_options[] = $option; + } + } + return $selected_options; + } + + /** + * @return WebDriverElement The first selected option in this select tag (or + * the currently selected option in a normal select) + */ + public function getFirstSelectedOption() { + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + return $option; + } + } + + throw new NoSuchElementException('No options are selected'); + } + + /** + * Deselect all options in multiple select tag. + * + * @return void + */ + public function deselectAll() { + if (!$this->isMultiple()) { + throw new UnsupportedOperationException( + 'You may only deselect all options of a multi-select' + ); + } + + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + $option->click(); + } + } + } + + /** + * Select the option at the given index. + * + * @param int $index The index of the option. (0-based) + * @return void + */ + public function selectByIndex($index) { + $matched = false; + foreach ($this->getOptions() as $option) { + if ($option->getAttribute('index') === (string)$index) { + if (!$option->isSelected()) { + $option->click(); + if (!$this->isMultiple()) { + return; + } + } + $matched = true; + } + } + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with index: %d', $index) + ); + } + } + + /** + * Select all options that have value attribute matching the argument. That + * is, when given "foo" this would select an option like: + * + * ; + * + * @param string $value The value to match against. + * @return void + */ + public function selectByValue($value) { + $matched = false; + $xpath = './/option[@value = '.$this->escapeQuotes($value).']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + + foreach ($options as $option) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } + + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with value: %s', $value) + ); + } + } + + /** + * Select all options that display text matching the argument. That is, when + * given "Bar" this would select an option like: + * + * ; + * + * @param string $text The visible text to match against. + * @return void + */ + public function selectByVisibleText($text) { + $matched = false; + $xpath = './/option[normalize-space(.) = '.$this->escapeQuotes($text).']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + + foreach ($options as $option) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } + + // Since the mechanism of getting the text in xpath is not the same as + // webdriver, use the expensive getText() to check if nothing is matched. + if (!$matched) { + foreach ($this->getOptions() as $option) { + if ($option->getText() === $text) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } + } + } + + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with text: %s', $text) + ); + } + } + + /** + * Deselect the option at the given index. + * + * @param int $index The index of the option. (0-based) + * @return void + */ + public function deselectByIndex($index) { + foreach ($this->getOptions() as $option) { + if ($option->getAttribute('index') === (string)$index && + $option->isSelected()) { + $option->click(); + } + } + } + + /** + * Deselect all options that have value attribute matching the argument. That + * is, when given "foo" this would select an option like: + * + * ; + * + * @param string $value The value to match against. + * @return void + */ + public function deselectByValue($value) { + $xpath = './/option[@value = '.$this->escapeQuotes($value).']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + foreach ($options as $option) { + if ($option->isSelected()) { + $option->click(); + } + } + } + + /** + * Deselect all options that display text matching the argument. That is, when + * given "Bar" this would select an option like: + * + * ; + * + * @param string $text The visible text to match against. + * @return void + */ + public function deselectByVisibleText($text) { + $xpath = './/option[normalize-space(.) = '.$this->escapeQuotes($text).']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + foreach ($options as $option) { + if ($option->isSelected()) { + $option->click(); + } + } + } + + /** + * Convert strings with both quotes and ticks into: + * foo'"bar -> concat("foo'", '"', "bar") + * + * @param string $to_escape The string to be converted. + * @return string The escaped string. + */ + protected function escapeQuotes($to_escape) { + if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) { + $substrings = explode('"', $to_escape); + + $escaped = "concat("; + $first = true; + foreach ($substrings as $string) { + if (!$first) { + $escaped .= ", '\"',"; + $first = false; + } + $escaped .= '"' . $string . '"'; + } + return $escaped; + } + + if (strpos($to_escape, '"') !== false) { + return sprintf("'%s'", $to_escape); + } + + return sprintf('"%s"', $to_escape); + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverTargetLocator.php b/tests/vendor/facebook/webdriver/lib/WebDriverTargetLocator.php new file mode 100644 index 000000000000..d2c0a65f258d --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverTargetLocator.php @@ -0,0 +1,62 @@ +executor = $executor; + } + + /** + * Specify the amount of time the driver should wait when searching for an + * element if it is not immediately present. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function implicitlyWait($seconds) { + $this->executor->execute( + DriverCommand::IMPLICITLY_WAIT, + array('ms' => $seconds * 1000) + ); + return $this; + } + + /** + * Set the amount of time to wait for an asynchronous script to finish + * execution before throwing an error. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function setScriptTimeout($seconds) { + $this->executor->execute( + DriverCommand::SET_SCRIPT_TIMEOUT, + array('ms' => $seconds * 1000) + ); + return $this; + } + + /** + * Set the amount of time to wait for a page load to complete before throwing + * an error. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function pageLoadTimeout($seconds) { + $this->executor->execute(DriverCommand::SET_TIMEOUT, array( + 'type' => 'page load', + 'ms' => $seconds * 1000, + )); + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverWait.php b/tests/vendor/facebook/webdriver/lib/WebDriverWait.php new file mode 100644 index 000000000000..55ace62af750 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverWait.php @@ -0,0 +1,70 @@ +driver = $driver; + $this->timeout = $timeout_in_second ?: 30; + $this->interval = $interval_in_millisecond ?: 250; + } + + /** + * Calls the function provided with the driver as an argument until the return + * value is not falsey. + * + * @param (closure|WebDriverExpectedCondition) + * @param string $message + * @return mixed The return value of $func_or_ec + */ + public function until($func_or_ec, $message = "") { + $end = microtime(true) + $this->timeout; + $last_exception = null; + + while ($end > microtime(true)) { + try { + if ($func_or_ec instanceof WebDriverExpectedCondition) { + $ret_val = call_user_func($func_or_ec->getApply(), $this->driver); + } else { + $ret_val = call_user_func($func_or_ec, $this->driver); + } + if ($ret_val) { + return $ret_val; + } + } catch (NoSuchElementException $e) { + $last_exception = $e; + } + usleep($this->interval * 1000); + } + + if ($last_exception) { + throw $last_exception; + } + throw new TimeOutException($message); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/WebDriverWindow.php b/tests/vendor/facebook/webdriver/lib/WebDriverWindow.php new file mode 100644 index 000000000000..0bf86388b5f6 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/WebDriverWindow.php @@ -0,0 +1,143 @@ +executor = $executor; + } + + /** + * Get the position of the current window, relative to the upper left corner + * of the screen. + * + * @return array The current window position. + */ + public function getPosition() { + $position = $this->executor->execute( + DriverCommand::GET_WINDOW_POSITION, + array(':windowHandle' => 'current') + ); + return new WebDriverPoint( + $position['x'], + $position['y'] + ); + } + + /** + * Get the size of the current window. This will return the outer window + * dimension, not just the view port. + * + * @return array The current window size. + */ + public function getSize() { + $size = $this->executor->execute( + DriverCommand::GET_WINDOW_SIZE, + array(':windowHandle' => 'current') + ); + return new WebDriverDimension( + $size['width'], + $size['height'] + ); + } + + /** + * Maximizes the current window if it is not already maximized + * + * @return WebDriverWindow The instance. + */ + public function maximize() { + $this->executor->execute( + DriverCommand::MAXIMIZE_WINDOW, + array(':windowHandle' => 'current') + ); + return $this; + } + + /** + * Set the size of the current window. This will change the outer window + * dimension, not just the view port. + * + * @param WebDriverDimension $size + * @return WebDriverWindow The instance. + */ + public function setSize(WebDriverDimension $size) { + $params = array( + 'width' => $size->getWidth(), + 'height' => $size->getHeight(), + ':windowHandle' => 'current', + ); + $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params); + return $this; + } + + /** + * Set the position of the current window. This is relative to the upper left + * corner of the screen. + * + * @param WebDriverPoint $position + * @return WebDriverWindow The instance. + */ + public function setPosition(WebDriverPoint $position) { + $params = array( + 'x' => $position->getX(), + 'y' => $position->getY(), + ':windowHandle' => 'current', + ); + $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params); + return $this; + } + + /** + * Get the current browser orientation. + * + * @return string Either LANDSCAPE|PORTRAIT + */ + public function getScreenOrientation() { + return $this->executor->execute(DriverCommand::GET_SCREEN_ORIENTATION); + } + + + /** + * Set the browser orientation. The orientation should either + * LANDSCAPE|PORTRAIT + * + * @param string $orientation + * @return WebDriverWindow The instance. + * @throws IndexOutOfBoundsException + */ + public function setScreenOrientation($orientation) { + $orientation = strtoupper($orientation); + if (!in_array($orientation, array('PORTRAIT', 'LANDSCAPE'))) { + throw new IndexOutOfBoundsException( + "Orientation must be either PORTRAIT, or LANDSCAPE" + ); + } + + $this->executor->execute( + DriverCommand::SET_SCREEN_ORIENTATION, + array('orientation' => $orientation) + ); + + return $this; + + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/__init__.php b/tests/vendor/facebook/webdriver/lib/__init__.php new file mode 100755 index 000000000000..55219b4918ab --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/__init__.php @@ -0,0 +1,116 @@ +setCommandExecutor($executor) + ->startSession($desired_capabilities); + return $driver; + } + + public function startSession($desired_capabilities) { + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array( + 'desiredCapabilities' => $desired_capabilities->toArray(), + ) + ); + $response = $this->executor->execute($command); + $this->setSessionID($response->getSessionID()); + } + + /** + * @param string $url The url of the remote server + * @param DesiredCapabilities $desired_capabilities The desired capabilities + * @param int|null $connection_timeout_in_ms + * @param int|null $request_timeout_in_ms + */ + public static function create( + $url = 'http://localhost:4444/wd/hub', + $desired_capabilities = null, + $timeout_in_ms = null, + $request_timeout_in_ms = null + ) { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } + + public static function createBySessionID( + $session_id, + $url = 'http://localhost:4444/wd/hub' + ) { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/chrome/ChromeDriverService.php b/tests/vendor/facebook/webdriver/lib/chrome/ChromeDriverService.php new file mode 100644 index 000000000000..c4de774e7f62 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/chrome/ChromeDriverService.php @@ -0,0 +1,29 @@ +binary = $path; + return $this; + } + + /** + * @param array $arguments + * @return ChromeOptions + */ + public function addArguments(array $arguments) { + $this->arguments = array_merge($this->arguments, $arguments); + return $this; + } + + /** + * Add a Chrome extension to install on browser startup. Each path should be + * a packed Chrome extension. + * + * @param array $paths + * @return ChromeOptions + */ + public function addExtensions(array $paths) { + foreach ($paths as $path) { + $this->addExtension($path); + } + return $this; + } + + /** + * @param array $encoded_extensions An array of base64 encoded of the + * extensions. + * @return ChromeOptions + */ + public function addEncodedExtensions(array $encoded_extensions) { + foreach ($encoded_extensions as $encoded_extension) { + $this->addEncodedExtension($encoded_extension); + } + return $this; + } + + /** + * Sets an experimental option which has not exposed officially. + * + * @param string $name + * @param mixed $value + * @return ChromeOptions + */ + public function setExperimentalOption($name, $value) { + $this->experimentalOptions[$name] = $value; + return $this; + } + + /** + * @return DesiredCapabilities The DesiredCapabilities for Chrome with this + * options. + */ + public function toCapabilities() { + $capabilities = DesiredCapabilities::chrome(); + $capabilities->setCapability(self::CAPABILITY, $this); + return $capabilities; + } + + /** + * @return array + */ + public function toArray() { + $options = $this->experimentalOptions; + + // The selenium server expects a 'dictionary' instead of a 'list' when + // reading the chrome option. However, an empty array in PHP will be + // converted to a 'list' instead of a 'dictionary'. To fix it, we always + // set the 'binary' to avoid returning an empty array. + $options['binary'] = $this->binary; + + if ($this->arguments) { + $options['args'] = $this->arguments; + } + + if ($this->extensions) { + $options['extensions'] = $this->extensions; + } + + return $options; + } + + /** + * Add a Chrome extension to install on browser startup. Each path should be a + * packed Chrome extension. + * + * @param string $path + * @return ChromeOptions + */ + private function addExtension($path) { + $this->addEncodedExtension(base64_encode(file_get_contents($path))); + return $this; + } + + /** + * @param string $encoded_extension Base64 encoded of the extension. + * @return ChromeOptions + */ + private function addEncodedExtension($encoded_extension) { + $this->extensions[] = $encoded_extension; + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/firefox/FirefoxDriver.php b/tests/vendor/facebook/webdriver/lib/firefox/FirefoxDriver.php new file mode 100644 index 000000000000..b1580baa66c1 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/firefox/FirefoxDriver.php @@ -0,0 +1,19 @@ +extensions[] = $extension; + return $this; + } + + /** + * @param string $key + * @param string|bool|int $value + * @return FirefoxProfile + */ + public function setPreference($key, $value) { + if (is_string($value)) { + $value = sprintf('"%s"', $value); + } else if (is_int($value)) { + $value = sprintf('%d', $value); + } else if (is_bool($value)) { + $value = $value ? 'true' : 'false'; + } else { + throw new WebDriverException( + 'The value of the preference should be either a string, int or bool.'); + } + $this->preferences[$key] = $value; + return $this; + } + + /** + * @return string + */ + public function encode() { + $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); + + foreach ($this->extensions as $extension) { + $this->installExtension($extension, $temp_dir); + } + + $content = ""; + foreach ($this->preferences as $key => $value) { + $content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value); + } + file_put_contents($temp_dir.'/user.js', $content); + + $zip = new ZipArchive(); + $temp_zip = tempnam('', 'WebDriverFirefoxProfileZip'); + $zip->open($temp_zip, ZipArchive::CREATE); + + $dir = new RecursiveDirectoryIterator($temp_dir); + $files = new RecursiveIteratorIterator($dir); + foreach ($files as $name => $object) { + if (is_dir($name)) { + continue; + } + $dir_prefix = preg_replace( + '#\\\\#', + '\\\\\\\\', + $temp_dir.DIRECTORY_SEPARATOR + ); + $path = preg_replace("#^{$dir_prefix}#", "", $name); + $zip->addFile($name, $path); + } + $zip->close(); + + $profile = base64_encode(file_get_contents($temp_zip)); + return $profile; + } + + /** + * @param string $extension The path to the extension. + * @param string $profile_dir The path to the profile directory. + * @return string The path to the directory of this extension. + */ + private function installExtension($extension, $profile_dir) { + $temp_dir = $this->createTempDirectory(); + + $this->extractTo($extension, $temp_dir); + + $install_rdf_path = $temp_dir.'/install.rdf'; + // This is a hacky way to parse the id since there is no offical + // RDF parser library. + $matches = array(); + $xml = file_get_contents($install_rdf_path); + preg_match('#([^<]+)#', $xml, $matches); + $ext_dir = $profile_dir.'/extensions/'.$matches[1]; + + mkdir($ext_dir, 0777, true); + + $this->extractTo($extension, $ext_dir); + return $ext_dir; + } + + /** + * @param string $prefix Prefix of the temp directory. + * @return string The path to the temp directory created. + */ + private function createTempDirectory($prefix = '') { + $temp_dir = tempnam('', $prefix); + if (file_exists($temp_dir)) { + unlink($temp_dir); + mkdir($temp_dir); + if (!is_dir($temp_dir)) { + throw new WebDriverException('Cannot create firefox profile.'); + } + } + return $temp_dir; + } + + /** + * @param string $xpi The path to the .xpi extension. + * @param string $target_dir The path to the unzip directory. + * @return FirefoxProfile + */ + private function extractTo($xpi, $target_dir) { + $zip = new ZipArchive(); + if ($zip->open($xpi)) { + $zip->extractTo($target_dir); + $zip->close(); + } else { + throw new Exception("Failed to open the firefox extension. '$xpi'"); + } + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/WebDriverActions.php b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverActions.php new file mode 100644 index 000000000000..e560db92b76e --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverActions.php @@ -0,0 +1,236 @@ +driver = $driver; + $this->keyboard = $driver->getKeyboard(); + $this->mouse = $driver->getMouse(); + $this->action = new WebDriverCompositeAction(); + } + + /** + * A convenience method for performing the actions without calling build(). + * @return void + */ + public function perform() { + $this->action->perform(); + } + + /** + * Mouse click. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function click(WebDriverElement $element = null) { + $this->action->addAction( + new WebDriverClickAction($this->mouse, $element) + ); + return $this; + } + + /** + * Mouse click and hold. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function clickAndHold(WebDriverElement $element = null) { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $element) + ); + return $this; + } + + /** + * Context-click (right click). + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function contextClick(WebDriverElement $element = null) { + $this->action->addAction( + new WebDriverContextClickAction($this->mouse, $element) + ); + return $this; + } + + /** + * Double click. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function doubleClick(WebDriverElement $element = null) { + $this->action->addAction( + new WebDriverDoubleClickAction($this->mouse, $element) + ); + return $this; + } + + /** + * Drag and drop from $source to $target. + * + * @param WebDriverElement $source + * @param WebDriverElement $target + * @return WebDriverActions + */ + public function dragAndDrop(WebDriverElement $source, + WebDriverElement $target) { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $source) + ); + $this->action->addAction( + new WebDriverMouseMoveAction($this->mouse, $target) + ); + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, $target) + ); + return $this; + } + + /** + * Drag $source and drop by offset ($x_offset, $y_offset). + * + * @param WebDriverElement $source + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function dragAndDropBy(WebDriverElement $source, + $x_offset, + $y_offset) { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $source) + ); + $this->action->addAction( + new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) + ); + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, null) + ); + return $this; + } + + /** + * Mouse move by offset. + * + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function moveByOffset($x_offset, $y_offset) { + $this->action->addAction( + new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) + ); + return $this; + } + + /** + * Move to the middle of the given WebDriverElement. If offset are provided, + * move the an offset from the top-left cornerof that element. + * + * @param WebDriverElement $element + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function moveToElement(WebDriverElement $element, + $x_offset = null, + $y_offset = null) { + $this->action->addAction(new WebDriverMoveToOffsetAction( + $this->mouse, $element, $x_offset, $y_offset + )); + return $this; + } + + /** + * Release the mouse button. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function release(WebDriverElement $element = null) { + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, $element) + ); + return $this; + } + + /** + * Press a key on keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key + * @return WebDriverActions + */ + public function keyDown(WebDriverElement $element = null, $key = null) { + $this->action->addAction( + new WebDriverKeyDownAction($this->keyboard, $this->mouse, $element, $key) + ); + return $this; + } + + /** + * Release a key on keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key + * @return WebDriverActions + */ + public function keyUp(WebDriverElement $element = null, $key = null) { + $this->action->addAction( + new WebDriverKeyUpAction($this->keyboard, $this->mouse, $element, $key) + ); + return $this; + } + + /** + * Send keys by keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $keys + * @return WebDriverActions + */ + public function sendKeys(WebDriverElement $element = null, $keys = null) { + $this->action->addAction( + new WebDriverSendKeysAction( + $this->keyboard, $this->mouse, $element, $keys + ) + ); + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/WebDriverCompositeAction.php b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverCompositeAction.php new file mode 100644 index 000000000000..8cb204b727b8 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverCompositeAction.php @@ -0,0 +1,51 @@ +actions[] = $action; + return $this; + } + + /** + * Get the number of actions in the sequence. + * + * @return int The number of actions. + */ + public function getNumberOfActions() { + return count($this->actions); + } + + /** + * Perform the seqeunce of actions. + */ + public function perform() { + foreach ($this->actions as $action) { + $action->perform(); + } + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchActions.php b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchActions.php new file mode 100644 index 000000000000..5be31d427a1b --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchActions.php @@ -0,0 +1,153 @@ +touchScreen = $driver->getTouch(); + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function tap(WebDriverElement $element) { + $this->action->addAction( + new WebDriverTapAction($this->touchScreen, $element) + ); + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function down($x, $y) { + $this->action->addAction( + new WebDriverDownAction($this->touchScreen, $x, $y) + ); + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function up($x, $y) { + $this->action->addAction( + new WebDriverUpAction($this->touchScreen, $x, $y) + ); + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function move($x, $y) { + $this->action->addAction( + new WebDriverMoveAction($this->touchScreen, $x, $y) + ); + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function scroll($x, $y) { + $this->action->addAction( + new WebDriverScrollAction($this->touchScreen, $x, $y) + ); + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function scrollFromElement(WebDriverElement $element, $x, $y) { + $this->action->addAction( + new WebDriverScrollFromElementAction($this->touchScreen, $element, $x, $y) + ); + return $this; + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function doubleTap(WebDriverElement $element) { + $this->action->addAction( + new WebDriverDoubleTapAction($this->touchScreen, $element) + ); + return $this; + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function longPress(WebDriverElement $element) { + $this->action->addAction( + new WebDriverLongPressAction($this->touchScreen, $element) + ); + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function flick($x, $y) { + $this->action->addAction( + new WebDriverFlickAction($this->touchScreen, $x, $y) + ); + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @param int $speed + * @return WebDriverTouchActions + */ + public function flickFromElement(WebDriverElement $element, $x, $y, $speed) { + $this->action->addAction( + new WebDriverFlickFromElementAction( + $this->touchScreen, $element, $x, $y, $speed + ) + ); + return $this; + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchScreen.php b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchScreen.php new file mode 100644 index 000000000000..d38a8bccf2d4 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/WebDriverTouchScreen.php @@ -0,0 +1,118 @@ +mouse->mouseUp($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAction.php new file mode 100644 index 000000000000..0aba9dc16587 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAction.php @@ -0,0 +1,23 @@ +mouse->click($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAndHoldAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAndHoldAction.php new file mode 100644 index 000000000000..80622ed11ae2 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverClickAndHoldAction.php @@ -0,0 +1,26 @@ +mouse->mouseDown($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverContextClickAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverContextClickAction.php new file mode 100644 index 000000000000..4802fdc3a9ee --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverContextClickAction.php @@ -0,0 +1,26 @@ +mouse->contextClick($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverCoordinates.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverCoordinates.php new file mode 100644 index 000000000000..18cc42020d0b --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverCoordinates.php @@ -0,0 +1,68 @@ +onScreen = $on_screen; + $this->inViewPort = $in_view_port; + $this->onPage = $on_page; + $this->auxiliary = $auxiliary; + } + + /** + * @return WebDriverPoint + */ + public function onScreen() { + throw new UnsupportedOperationException( + 'onScreen is planned but not yet supported by Selenium' + ); + } + + /** + * @return WebDriverPoint + */ + public function inViewPort() { + return call_user_func($this->inViewPort); + } + + /** + * @return WebDriverPoint + */ + public function onPage() { + return call_user_func($this->onPage); + } + + /** + * @return Object The attached object. + */ + public function getAuxiliary() { + return $this->auxiliary; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverDoubleClickAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverDoubleClickAction.php new file mode 100644 index 000000000000..41fd4171662f --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverDoubleClickAction.php @@ -0,0 +1,23 @@ +mouse->doubleClick($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyDownAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyDownAction.php new file mode 100644 index 000000000000..1de8ae0ed7cb --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyDownAction.php @@ -0,0 +1,24 @@ +focusOnElement(); + $this->keyboard->pressKey($this->key); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyUpAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyUpAction.php new file mode 100644 index 000000000000..06e652700397 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeyUpAction.php @@ -0,0 +1,24 @@ +focusOnElement(); + $this->keyboard->releaseKey($this->key); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeysRelatedAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeysRelatedAction.php new file mode 100644 index 000000000000..c97069d87fd7 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverKeysRelatedAction.php @@ -0,0 +1,47 @@ +keyboard = $keyboard; + $this->mouse = $mouse; + $this->locationProvider = $location_provider; + } + + /** + * @return void + */ + protected function focusOnElement() { + if ($this->locationProvider) { + $this->mouse->click($this->locationProvider->getCoordinates()); + } + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseAction.php new file mode 100644 index 000000000000..4c16a7b3938d --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseAction.php @@ -0,0 +1,48 @@ +mouse = $mouse; + $this->locationProvider = $location_provider; + } + + /** + * @return null|WebDriverCoordinates + */ + protected function getActionLocation() { + if ($this->locationProvider !== null) { + return $this->locationProvider->getCoordinates(); + } + + return null; + } + + /** + * @return void + */ + protected function moveToLocation() { + $this->mouse->mouseMove($this->locationProvider); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseMoveAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseMoveAction.php new file mode 100644 index 000000000000..ca21d3511b6e --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMouseMoveAction.php @@ -0,0 +1,23 @@ +mouse->mouseMove($this->getActionLocation()); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMoveToOffsetAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMoveToOffsetAction.php new file mode 100644 index 000000000000..d82558b55ac7 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverMoveToOffsetAction.php @@ -0,0 +1,38 @@ +xOffset = $x_offset; + $this->yOffset = $y_offset; + } + + public function perform() { + $this->mouse->mouseMove( + $this->getActionLocation(), + $this->xOffset, + $this->yOffset + ); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSendKeysAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSendKeysAction.php new file mode 100644 index 000000000000..8dcc69183f84 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSendKeysAction.php @@ -0,0 +1,41 @@ +keys = $keys; + } + + public function perform() { + $this->focusOnElement(); + $this->keyboard->sendKeys($this->keys); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSingleKeyAction.php b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSingleKeyAction.php new file mode 100644 index 000000000000..7d06cd330de3 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/internal/WebDriverSingleKeyAction.php @@ -0,0 +1,30 @@ +key = $key; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDoubleTapAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDoubleTapAction.php new file mode 100644 index 000000000000..00b2c28a4ef3 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDoubleTapAction.php @@ -0,0 +1,23 @@ +touchScreen->doubleTap($this->locationProvider); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDownAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDownAction.php new file mode 100644 index 000000000000..43c4ed08d708 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverDownAction.php @@ -0,0 +1,37 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } + + public function perform() { + $this->touchScreen->down($this->x, $this->y); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickAction.php new file mode 100644 index 000000000000..76337c468d5c --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickAction.php @@ -0,0 +1,34 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } + + public function perform() { + $this->touchScreen->flick($this->x, $this->y); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickFromElementAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickFromElementAction.php new file mode 100644 index 000000000000..f361f1c29d93 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverFlickFromElementAction.php @@ -0,0 +1,49 @@ +x = $x; + $this->y = $y; + $this->speed = $speed; + parent::__construct($touch_screen, $element); + } + + public function perform() { + $this->touchScreen->flickFromElement( + $this->locationProvider, + $this->x, + $this->y, + $this->speed + ); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverLongPressAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverLongPressAction.php new file mode 100644 index 000000000000..556c1d47fb9a --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverLongPressAction.php @@ -0,0 +1,23 @@ +touchScreen->longPress($this->locationProvider); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverMoveAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverMoveAction.php new file mode 100644 index 000000000000..2c089a343cd3 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverMoveAction.php @@ -0,0 +1,37 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } + + public function perform() { + $this->touchScreen->move($this->x, $this->y); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollAction.php new file mode 100644 index 000000000000..082b1acaf693 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollAction.php @@ -0,0 +1,37 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } + + public function perform() { + $this->touchScreen->scroll($this->x, $this->y); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollFromElementAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollFromElementAction.php new file mode 100644 index 000000000000..3c985b6bdf75 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverScrollFromElementAction.php @@ -0,0 +1,44 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen, $element); + } + + public function perform() { + $this->touchScreen->scrollFromElement( + $this->locationProvider, + $this->x, + $this->y + ); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTapAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTapAction.php new file mode 100644 index 000000000000..fb1a710047ae --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTapAction.php @@ -0,0 +1,23 @@ +touchScreen->tap($this->locationProvider); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTouchAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTouchAction.php new file mode 100644 index 000000000000..99abced9c3d9 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverTouchAction.php @@ -0,0 +1,51 @@ +touchScreen = $touch_screen; + $this->locationProvider = $location_provider; + } + + /** + * @return null|WebDriverCoordinates + */ + protected function getActionLocation() { + return $this->locationProvider !== null + ? $this->locationProvider->getCoordinates() : null; + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverUpAction.php b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverUpAction.php new file mode 100644 index 000000000000..298302769e1f --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/interactions/touch/WebDriverUpAction.php @@ -0,0 +1,37 @@ +x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } + + public function perform() { + $this->touchScreen->up($this->x, $this->y); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/internal/WebDriverLocatable.php b/tests/vendor/facebook/webdriver/lib/internal/WebDriverLocatable.php new file mode 100644 index 000000000000..5250d13478de --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/internal/WebDriverLocatable.php @@ -0,0 +1,25 @@ + microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) === 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } + + throw new TimeOutException(sprintf( + "Timed out waiting for %s to become available after %d ms.", + $url, + $timeout_in_ms + )); + } + + public function waitUntilUnavailable($timeout_in_ms, $url) { + $end = microtime(true) + $timeout_in_ms / 1000; + + while ($end > microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) !== 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } + + throw new TimeOutException(sprintf( + "Timed out waiting for %s to become unavailable after %d ms.", + $url, + $timeout_in_ms + )); + } + + private function getHTTPResponseCode($timeout_in_ms, $url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt( + $ch, + 156, // CURLOPT_CONNECTTIMEOUT_MS + self::CONNECT_TIMEOUT_MS + ); + $code = null; + try { + curl_exec($ch); + $info = curl_getinfo($ch); + $code = $info['http_code']; + } catch (Exception $e) { + } + curl_close($ch); + return $code; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/DesiredCapabilities.php b/tests/vendor/facebook/webdriver/lib/remote/DesiredCapabilities.php new file mode 100644 index 000000000000..19183737193b --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/DesiredCapabilities.php @@ -0,0 +1,275 @@ +capabilities = $capabilities; + } + + /** + * @return string The name of the browser. + */ + public function getBrowserName() { + return $this->get(WebDriverCapabilityType::BROWSER_NAME, ''); + } + + /** + * @param string $browser_name + * @return DesiredCapabilities + */ + public function setBrowserName($browser_name) { + $this->set(WebDriverCapabilityType::BROWSER_NAME, $browser_name); + return $this; + } + + /** + * @return string The version of the browser. + */ + public function getVersion() { + return $this->get(WebDriverCapabilityType::VERSION, ''); + } + + /** + * @param string $version + * @return DesiredCapabilities + */ + public function setVersion($version) { + $this->set(WebDriverCapabilityType::VERSION, $version); + return $this; + } + + /** + * @param string $name + * @return mixed The value of a capability. + */ + public function getCapability($name) { + return $this->get($name); + } + + /** + * @param string $name + * @param mixed $value + * @return DesiredCapabilities + */ + public function setCapability($name, $value) { + $this->set($name, $value); + return $this; + } + + /** + * @return string The name of the platform. + */ + public function getPlatform() { + return $this->get(WebDriverCapabilityType::PLATFORM, ''); + } + + /** + * @param string $platform + * @return DesiredCapabilities + */ + public function setPlatform($platform) { + $this->set(WebDriverCapabilityType::PLATFORM, $platform); + return $this; + } + + /** + * @param string $capability_name + * @return bool Whether the value is not null and not false. + */ + public function is($capability_name) { + return (bool) $this->get($capability_name); + } + + /** + * @return bool Whether javascript is enabled. + */ + public function isJavascriptEnabled() { + return $this->get(WebDriverCapabilityType::JAVASCRIPT_ENABLED, false); + } + + /** + * This is a htmlUnit-only option. + * + * @param bool $enabled + * @return DesiredCapabilities + * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities + */ + public function setJavascriptEnabled($enabled) { + $browser = $this->getBrowserName(); + if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { + throw new Exception( + 'isJavascriptEnable() is a htmlunit-only option. '. + 'See https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities.' + ); + } + + $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); + return $this; + } + + /** + * @return array + */ + public function toArray() { + if (isset($this->capabilities[ChromeOptions::CAPABILITY]) && + $this->capabilities[ChromeOptions::CAPABILITY] instanceof ChromeOptions) { + $this->capabilities[ChromeOptions::CAPABILITY] = + $this->capabilities[ChromeOptions::CAPABILITY]->toArray(); + } + + if (isset($this->capabilities[FirefoxDriver::PROFILE]) && + $this->capabilities[FirefoxDriver::PROFILE] instanceof FirefoxProfile) { + $this->capabilities[FirefoxDriver::PROFILE] = + $this->capabilities[FirefoxDriver::PROFILE]->encode(); + } + + return $this->capabilities; + } + + /** + * @param string $key + * @param mixed $value + * @return DesiredCapabilities + */ + private function set($key, $value) { + $this->capabilities[$key] = $value; + return $this; + } + + /** + * @param string $key + * @param mixed $default + * @return mixed + */ + private function get($key, $default = null) { + return isset($this->capabilities[$key]) + ? $this->capabilities[$key] + : $default; + } + + /** + * @return DesiredCapabilities + */ + public static function android() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function chrome() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function firefox() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function htmlUnit() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function htmlUnitWithJS() { + $caps = new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + return $caps->setJavascriptEnabled(true); + } + + /** + * @return DesiredCapabilities + */ + public static function internetExplorer() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function iphone() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function ipad() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function opera() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function safari() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function phantomjs() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/DriverCommand.php b/tests/vendor/facebook/webdriver/lib/remote/DriverCommand.php new file mode 100644 index 000000000000..837e5e9de791 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/DriverCommand.php @@ -0,0 +1,169 @@ + array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/equals/:other'), + DriverCommand::FIND_CHILD_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'), + DriverCommand::FIND_CHILD_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'), + DriverCommand::EXECUTE_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window'), + DriverCommand::GET => array('method' => 'POST', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), + DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('method' => 'GET', 'url' => '/session/:sessionId/window_handle'), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/attribute/:name'), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/css/:propertyName'), + DriverCommand::GET_ELEMENT_LOCATION => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location'), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location_in_view'), + DriverCommand::GET_ELEMENT_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/name'), + DriverCommand::GET_ELEMENT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('method' => 'POST', 'url' => '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('method' => 'GET', 'url' => '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('method' => 'GET', 'url' => '/session/:sessionId'), + DriverCommand::GET_TITLE => array('method' => 'GET', 'url' => '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::GET_WINDOW_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::GO_BACK => array('method' => 'POST', 'url' => '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/displayed'), + DriverCommand::IS_ELEMENT_ENABLED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/enabled'), + DriverCommand::IS_ELEMENT_SELECTED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/selected'), + DriverCommand::MAXIMIZE_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/maximize'), + DriverCommand::MOUSE_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('method' => 'POST', 'url' => '/session'), + DriverCommand::QUIT => array('method' => 'DELETE', 'url' => '/session/:sessionId'), + DriverCommand::REFRESH => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/value'), + DriverCommand::IMPLICITLY_WAIT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/implicit_wait'), + DriverCommand::SET_SCREEN_ORIENTATION => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/async_script'), + DriverCommand::SET_WINDOW_POSITION => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::SET_WINDOW_SIZE => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::SUBMIT_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), + ); + + /** + * @var string + */ + protected $url; + /** + * @var resource + */ + protected $curl; + + /** + * @param string $url + */ + public function __construct($url) { + $this->url = $url; + $this->curl = curl_init(); + + // Get credentials from $url (if any) + $matches = null; + if (preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches)) { + $this->url = $matches[1].$matches[4]; + $auth_creds = $matches[2].":".$matches[3]; + curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); + } + + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + array( + 'Content-Type: application/json;charset=UTF-8', + 'Accept: application/json', + ) + ); + $this->setRequestTimeout(30000); + $this->setConnectionTimeout(30000); + } + + /** + * Set timeout for the connect phase + * + * @param int $timeout_in_ms Timeout in milliseconds + * @return HttpCommandExecutor + */ + public function setConnectionTimeout($timeout_in_ms) { + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt( + $this->curl, + /* CURLOPT_CONNECTTIMEOUT_MS */ 156, + $timeout_in_ms + ); + return $this; + } + + /** + * Set the maximum time of a request + * + * @param int $timeout_in_ms Timeout in milliseconds + * @return HttpCommandExecutor + */ + public function setRequestTimeout($timeout_in_ms) { + // There is a PHP bug in some versions (at least for PHP 5.3.3) which + // didn't define the constant. + curl_setopt( + $this->curl, + /* CURLOPT_TIMEOUT_MS */ 155, + $timeout_in_ms + ); + return $this; + } + + /** + * @param WebDriverCommand $command + * @return mixed + */ + public function execute(WebDriverCommand $command) { + if (!isset(self::$commands[$command->getName()])) { + throw new InvalidArgumentException( + $command->getName()." is not a valid command." + ); + } + $raw = self::$commands[$command->getName()]; + $http_method = $raw['method']; + $url = $raw['url']; + $url = str_replace(':sessionId', $command->getSessionID(), $url); + $params = $command->getParameters(); + foreach ($params as $name => $value) { + if ($name[0] === ':') { + $url = str_replace($name, $value, $url); + if ($http_method != 'POST') { + unset($params[$name]); + } + } + } + + if ($params && is_array($params) && $http_method !== 'POST') { + throw new BadMethodCallException(sprintf( + 'The http method called for %s is %s but it has to be POST' . + ' if you want to pass the JSON params %s', + $url, + $http_method, + json_encode($params) + )); + } + + curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); + + // https://github.com/facebook/php-webdriver/issues/173 + if ($command->getName() === DriverCommand::NEW_SESSION) { + curl_setopt($this->curl, CURLOPT_POST, 1); + } else { + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); + } + + $encoded_params = null; + + if ($http_method === 'POST' && $params && is_array($params)) { + $encoded_params = json_encode($params); + } + + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); + + $raw_results = trim(curl_exec($this->curl)); + + if ($error = curl_error($this->curl)) { + $msg = sprintf( + 'Curl error thrown for http %s to %s', + $http_method, + $url); + if ($params && is_array($params)) { + $msg .= sprintf(' with params: %s', json_encode($params)); + } + WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); + } + + $results = json_decode($raw_results, true); + + if ($results === null && json_last_error() !== JSON_ERROR_NONE) { + throw new WebDriverException( + sprintf( + "JSON decoding of remote response failed.\n". + "Error code: %d\n". + "The response: '%s'\n", + json_last_error(), + $raw_results + ) + ); + } + + $value = null; + if (is_array($results) && array_key_exists('value', $results)) { + $value = $results['value']; + } + + $message = null; + if (is_array($value) && array_key_exists('message', $value)) { + $message = $value['message']; + } + + $sessionId = null; + if (is_array($results) && array_key_exists('sessionId', $results)) { + $sessionId = $results['sessionId']; + } + + $status = isset($results['status']) ? $results['status'] : 0; + WebDriverException::throwException($status, $message, $results); + + $response = new WebDriverResponse($sessionId); + return $response + ->setStatus($status) + ->setValue($value); + } + + /** + * @return string + */ + public function getAddressOfRemoteServer() { + return $this->url; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/LocalFileDetector.php b/tests/vendor/facebook/webdriver/lib/remote/LocalFileDetector.php new file mode 100644 index 000000000000..f0107b0bac8a --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/LocalFileDetector.php @@ -0,0 +1,28 @@ +driver = $driver; + } + + /** + * @param string $command_name + * @param array $parameters + * @return mixed + */ + public function execute( + $command_name, + array $parameters = array() + ) { + return $this->driver->execute($command_name, $parameters); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteKeyboard.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteKeyboard.php new file mode 100644 index 000000000000..2a3cc54777ec --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteKeyboard.php @@ -0,0 +1,72 @@ +executor = $executor; + } + + /** + * Send keys to active element + * @param string|array $keys + * @return $this + */ + public function sendKeys($keys) { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => WebDriverKeys::encode($keys), + )); + return $this; + } + + /** + * Press a modifier key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function pressKey($key) { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => array((string)$key), + )); + return $this; + } + + /** + * Release a modifier key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function releaseKey($key) { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => array((string)$key), + )); + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteMouse.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteMouse.php new file mode 100644 index 000000000000..66d010252dda --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteMouse.php @@ -0,0 +1,125 @@ +executor = $executor; + } + + /** + * @param null|WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function click(WebDriverCoordinates $where = null) { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::CLICK, array( + 'button' => 0, + )); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function contextClick(WebDriverCoordinates $where = null) { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::CLICK, array( + 'button' => 2, + )); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function doubleClick(WebDriverCoordinates $where = null) { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::DOUBLE_CLICK); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function mouseDown(WebDriverCoordinates $where = null) { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::MOUSE_DOWN); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * @param int|null $x_offset + * @param int|null $y_offset + * + * @return RemoteMouse + */ + public function mouseMove(WebDriverCoordinates $where = null, + $x_offset = null, + $y_offset = null) { + $params = array(); + if ($where !== null) { + $params['element'] = $where->getAuxiliary(); + } + if ($x_offset !== null) { + $params['xoffset'] = $x_offset; + } + if ($y_offset !== null) { + $params['yoffset'] = $y_offset; + } + $this->executor->execute(DriverCommand::MOVE_TO, $params); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function mouseUp(WebDriverCoordinates $where = null) { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::MOUSE_UP); + return $this; + } + + /** + * @param WebDriverCoordinates $where + * @return void + */ + protected function moveIfNeeded(WebDriverCoordinates $where = null) { + if ($where) { + $this->mouseMove($where); + } + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteTargetLocator.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteTargetLocator.php new file mode 100644 index 000000000000..949836675d9e --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteTargetLocator.php @@ -0,0 +1,97 @@ +executor = $executor; + $this->driver = $driver; + } + + /** + * Switch to the main document if the page contains iframes. Otherwise, switch + * to the first frame on the page. + * + * @return WebDriver The driver focused on the top window or the first frame. + */ + public function defaultContent() { + $params = array('id' => null); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); + + return $this->driver; + } + + /** + * Switch to the iframe by its id or name. + * + * @param WebDriverElement|string $frame The WebDriverElement, + the id or the name of the frame. + * @return WebDriver The driver focused on the given frame. + */ + public function frame($frame) { + if ($frame instanceof WebDriverElement) { + $id = array('ELEMENT' => $frame->getID()); + } else { + $id = (string)$frame; + } + + $params = array('id' => $id); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); + + return $this->driver; + } + + /** + * Switch the focus to another window by its handle. + * + * @param string $handle The handle of the window to be focused on. + * @return WebDriver Tge driver focused on the given window. + * @see WebDriver::getWindowHandles + */ + public function window($handle) { + $params = array('name' => (string)$handle); + $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); + + return $this->driver; + } + + /** + * Switch to the currently active modal dialog for this particular driver + * instance. + * + * @return WebDriverAlert + */ + public function alert() { + return new WebDriverAlert($this->executor); + } + + /** + * Switches to the element that currently has focus within the document + * currently "switched to", or the body element if this cannot be detected. + * + * @return RemoteWebElement + */ + public function activeElement() { + $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT); + $method = new RemoteExecuteMethod($this->driver); + return new RemoteWebElement($method, $response['ELEMENT']); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteTouchScreen.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteTouchScreen.php new file mode 100644 index 000000000000..652020dea3c7 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteTouchScreen.php @@ -0,0 +1,192 @@ +executor = $executor; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function tap(WebDriverElement $element) { + $this->executor->execute( + DriverCommand::TOUCH_SINGLE_TAP, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function doubleTap(WebDriverElement $element) { + $this->executor->execute( + DriverCommand::TOUCH_DOUBLE_TAP, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function down($x, $y) { + $this->executor->execute(DriverCommand::TOUCH_DOWN, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } + + + /** + * @param int $xspeed + * @param int $yspeed + * + * @return RemoteTouchScreen The instance. + */ + public function flick($xspeed, $yspeed) { + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + 'xspeed' => $xspeed, + 'yspeed' => $yspeed, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * @param int $speed + * + * @return RemoteTouchScreen The instance. + */ + public function flickFromElement( + WebDriverElement $element, $xoffset, $yoffset, $speed + ) { + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + 'element' => $element->getID(), + 'speed' => $speed, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function longPress(WebDriverElement $element) { + $this->executor->execute( + DriverCommand::TOUCH_LONG_PRESS, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function move($x, $y) { + $this->executor->execute(DriverCommand::TOUCH_MOVE, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } + + /** + * @param int $xoffset + * @param int $yoffset + * + * @return RemoteTouchScreen The instance. + */ + public function scroll($xoffset, $yoffset) { + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * + * @return RemoteTouchScreen The instance. + */ + public function scrollFromElement( + WebDriverElement $element, $xoffset, $yoffset + ) { + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + 'element' => $element->getID(), + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + )); + + return $this; + } + + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function up($x, $y) { + $this->executor->execute(DriverCommand::TOUCH_UP, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteWebDriver.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteWebDriver.php new file mode 100644 index 000000000000..2b0969f07a1e --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteWebDriver.php @@ -0,0 +1,494 @@ +toArray(); + } + + $executor = new HttpCommandExecutor($url); + if ($connection_timeout_in_ms !== null) { + $executor->setConnectionTimeout($connection_timeout_in_ms); + } + if ($request_timeout_in_ms !== null) { + $executor->setRequestTimeout($request_timeout_in_ms); + } + + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array('desiredCapabilities' => $desired_capabilities) + ); + + $response = $executor->execute($command); + + $driver = new static(); + $driver->setSessionID($response->getSessionID()) + ->setCommandExecutor($executor); + return $driver; + } + + /** + * [Experimental] Construct the RemoteWebDriver by an existing session. + * + * This constructor can boost the performance a lot by reusing the same + * browser for the whole test suite. You do not have to pass the desired + * capabilities because the session was created before. + * + * @param string $url The url of the remote server + * @param string $session_id The existing session id + * @return RemoteWebDriver + */ + public static function createBySessionID( + $session_id, + $url = 'http://localhost:4444/wd/hub' + ) { + $driver = new static(); + $driver->setSessionID($session_id) + ->setCommandExecutor(new HttpCommandExecutor($url)); + return $driver; + } + + /** + * Close the current window. + * + * @return RemoteWebDriver The current instance. + */ + public function close() { + $this->execute(DriverCommand::CLOSE, array()); + + return $this; + } + + /** + * Find the first WebDriverElement using the given mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement NoSuchElementException is thrown in + * HttpCommandExecutor if no element is found. + * @see WebDriverBy + */ + public function findElement(WebDriverBy $by) { + $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $raw_element = $this->execute( + DriverCommand::FIND_ELEMENT, + $params + ); + + return $this->newElement($raw_element['ELEMENT']); + } + + /** + * Find all WebDriverElements within the current page using the given + * mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty + * array if nothing matches + * @see WebDriverBy + */ + public function findElements(WebDriverBy $by) { + $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $raw_elements = $this->execute( + DriverCommand::FIND_ELEMENTS, + $params + ); + + $elements = array(); + foreach ($raw_elements as $raw_element) { + $elements[] = $this->newElement($raw_element['ELEMENT']); + } + return $elements; + } + + /** + * Load a new web page in the current browser window. + * + * @param string $url + * + * @return RemoteWebDriver The current instance. + */ + public function get($url) { + $params = array('url' => (string)$url); + $this->execute(DriverCommand::GET, $params); + + return $this; + } + + /** + * Get a string representing the current URL that the browser is looking at. + * + * @return string The current URL. + */ + public function getCurrentURL() { + return $this->execute(DriverCommand::GET_CURRENT_URL); + } + + /** + * Get the source of the last loaded page. + * + * @return string The current page source. + */ + public function getPageSource() { + return $this->execute(DriverCommand::GET_PAGE_SOURCE); + } + + /** + * Get the title of the current page. + * + * @return string The title of the current page. + */ + public function getTitle() { + return $this->execute(DriverCommand::GET_TITLE); + } + + /** + * Return an opaque handle to this window that uniquely identifies it within + * this driver instance. + * + * @return string The current window handle. + */ + public function getWindowHandle() { + return $this->execute( + DriverCommand::GET_CURRENT_WINDOW_HANDLE, + array() + ); + } + + /** + * Get all window handles available to the current session. + * + * @return array An array of string containing all available window handles. + */ + public function getWindowHandles() { + return $this->execute(DriverCommand::GET_WINDOW_HANDLES, array()); + } + + /** + * Quits this driver, closing every associated window. + * + * @return void + */ + public function quit() { + $this->execute(DriverCommand::QUIT); + $this->executor = null; + } + + /** + * Prepare arguments for JavaScript injection + * + * @param array $arguments + * @return array + */ + private function prepareScriptArguments(array $arguments) { + $args = array(); + foreach ($arguments as $key => $value) { + if ($value instanceof WebDriverElement) { + $args[$key] = array('ELEMENT'=>$value->getID()); + } else { + if (is_array($value)) { + $value = $this->prepareScriptArguments($value); + } + $args[$key] = $value; + } + } + return $args; + } + + /** + * Inject a snippet of JavaScript into the page for execution in the context + * of the currently selected frame. The executed script is assumed to be + * synchronous and the result of evaluating the script will be returned. + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The return value of the script. + */ + public function executeScript($script, array $arguments = array()) { + $params = array( + 'script' => $script, + 'args' => $this->prepareScriptArguments($arguments), + ); + return $this->execute(DriverCommand::EXECUTE_SCRIPT, $params); + } + + /** + * Inject a snippet of JavaScript into the page for asynchronous execution in + * the context of the currently selected frame. + * + * The driver will pass a callback as the last argument to the snippet, and + * block until the callback is invoked. + * + * @see WebDriverExecuteAsyncScriptTestCase + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The value passed by the script to the callback. + */ + public function executeAsyncScript($script, array $arguments = array()) { + $params = array( + 'script' => $script, + 'args' => $this->prepareScriptArguments($arguments), + ); + return $this->execute( + DriverCommand::EXECUTE_ASYNC_SCRIPT, + $params + ); + } + + /** + * Take a screenshot of the current page. + * + * @param string $save_as The path of the screenshot to be saved. + * @return string The screenshot in PNG format. + */ + public function takeScreenshot($save_as = null) { + $screenshot = base64_decode( + $this->execute(DriverCommand::SCREENSHOT) + ); + if ($save_as) { + file_put_contents($save_as, $screenshot); + } + return $screenshot; + } + + /** + * Construct a new WebDriverWait by the current WebDriver instance. + * Sample usage: + * + * $driver->wait(20, 1000)->until( + * WebDriverExpectedCondition::titleIs('WebDriver Page') + * ); + * + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * + * @return WebDriverWait + */ + public function wait( + $timeout_in_second = 30, + $interval_in_millisecond = 250) { + return new WebDriverWait( + $this, $timeout_in_second, $interval_in_millisecond + ); + } + + /** + * An abstraction for managing stuff you would do in a browser menu. For + * example, adding and deleting cookies. + * + * @return WebDriverOptions + */ + public function manage() { + return new WebDriverOptions($this->getExecuteMethod()); + } + + /** + * An abstraction allowing the driver to access the browser's history and to + * navigate to a given URL. + * + * @return WebDriverNavigation + * @see WebDriverNavigation + */ + public function navigate() { + return new WebDriverNavigation($this->getExecuteMethod()); + } + + /** + * Switch to a different window or frame. + * + * @return RemoteTargetLocator + * @see RemoteTargetLocator + */ + public function switchTo() { + return new RemoteTargetLocator($this->getExecuteMethod(), $this); + } + + /** + * @return RemoteMouse + */ + public function getMouse() { + if (!$this->mouse) { + $this->mouse = new RemoteMouse($this->getExecuteMethod()); + } + return $this->mouse; + } + + /** + * @return RemoteKeyboard + */ + public function getKeyboard() { + if (!$this->keyboard) { + $this->keyboard = new RemoteKeyboard($this->getExecuteMethod()); + } + return $this->keyboard; + } + + /** + * @return RemoteTouchScreen + */ + public function getTouch() { + if (!$this->touch) { + $this->touch = new RemoteTouchScreen($this->getExecuteMethod()); + } + return $this->touch; + } + + protected function getExecuteMethod() { + if (!$this->executeMethod) { + $this->executeMethod = new RemoteExecuteMethod($this); + } + return $this->executeMethod; + } + + /** + * Construct a new action builder. + * + * @return WebDriverActions + */ + public function action() { + return new WebDriverActions($this); + } + + /** + * Return the WebDriverElement with the given id. + * + * @param string $id The id of the element to be created. + * @return RemoteWebElement + */ + private function newElement($id) { + return new RemoteWebElement($this->getExecuteMethod(), $id); + } + + /** + * Set the command executor of this RemoteWebdriver + * + * @param WebDriverCommandExecutor $executor + * @return RemoteWebDriver + */ + public function setCommandExecutor(WebDriverCommandExecutor $executor) { + $this->executor = $executor; + return $this; + } + + /** + * Set the command executor of this RemoteWebdriver + * + * @return HttpCommandExecutor + */ + public function getCommandExecutor() { + return $this->executor; + } + + /** + * Set the session id of the RemoteWebDriver. + * + * @param string $session_id + * @return RemoteWebDriver + */ + public function setSessionID($session_id) { + $this->sessionID = $session_id; + return $this; + } + + /** + * Get current selenium sessionID + * + * @return string sessionID + */ + public function getSessionID() { + return $this->sessionID; + } + + /** + * Get all selenium sessions. + * + * @param string $url The url of the remote server + * @param int $timeout_in_ms + * @return array + */ + public static function getAllSessions( + $url = 'http://localhost:4444/wd/hub', + $timeout_in_ms = 30000 + ) { + $executor = new HttpCommandExecutor($url); + $executor->setConnectionTimeout($timeout_in_ms); + + $command = new WebDriverCommand( + null, + DriverCommand::GET_ALL_SESSIONS, + array() + ); + + return $executor->execute($command)->getValue(); + } + + public function execute($command_name, $params = array()) { + $command = new WebDriverCommand( + $this->sessionID, + $command_name, + $params + ); + + $response = $this->executor->execute($command); + return $response->getValue(); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/RemoteWebElement.php b/tests/vendor/facebook/webdriver/lib/remote/RemoteWebElement.php new file mode 100644 index 000000000000..ea4d1b992936 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/RemoteWebElement.php @@ -0,0 +1,410 @@ +executor = $executor; + $this->id = $id; + $this->fileDetector = new UselessFileDetector(); + } + + /** + * If this element is a TEXTAREA or text INPUT element, this will clear the + * value. + * + * @return RemoteWebElement The current instance. + */ + public function clear() { + $this->executor->execute( + DriverCommand::CLEAR_ELEMENT, + array(':id' => $this->id) + ); + return $this; + } + + /** + * Click this element. + * + * @return RemoteWebElement The current instance. + */ + public function click() { + $this->executor->execute( + DriverCommand::CLICK_ELEMENT, + array(':id' => $this->id) + ); + return $this; + } + + /** + * Find the first WebDriverElement within this element using the given + * mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement NoSuchElementException is thrown in + * HttpCommandExecutor if no element is found. + * @see WebDriverBy + */ + public function findElement(WebDriverBy $by) { + $params = array( + 'using' => $by->getMechanism(), + 'value' => $by->getValue(), + ':id' => $this->id, + ); + $raw_element = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENT, + $params + ); + + return $this->newElement($raw_element['ELEMENT']); + } + + /** + * Find all WebDriverElements within this element using the given mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty + * array if nothing matches + * @see WebDriverBy + */ + public function findElements(WebDriverBy $by) { + $params = array( + 'using' => $by->getMechanism(), + 'value' => $by->getValue(), + ':id' => $this->id, + ); + $raw_elements = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENTS, + $params + ); + + $elements = array(); + foreach ($raw_elements as $raw_element) { + $elements[] = $this->newElement($raw_element['ELEMENT']); + } + return $elements; + } + + /** + * Get the value of a the given attribute of the element. + * + * @param string $attribute_name The name of the attribute. + * @return string|null The value of the attribute. + */ + public function getAttribute($attribute_name) { + $params = array( + ':name' => $attribute_name, + ':id' => $this->id, + ); + return $this->executor->execute( + DriverCommand::GET_ELEMENT_ATTRIBUTE, + $params + ); + } + + /** + * Get the value of a given CSS property. + * + * @param string $css_property_name The name of the CSS property. + * @return string The value of the CSS property. + */ + public function getCSSValue($css_property_name) { + $params = array( + ':propertyName' => $css_property_name, + ':id' => $this->id, + ); + return $this->executor->execute( + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY, + $params + ); + } + + /** + * Get the location of element relative to the top-left corner of the page. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocation() { + $location = $this->executor->execute( + DriverCommand::GET_ELEMENT_LOCATION, + array(':id' => $this->id) + ); + return new WebDriverPoint($location['x'], $location['y']); + } + + /** + * Try scrolling the element into the view port and return the location of + * element relative to the top-left corner of the page afterwards. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocationOnScreenOnceScrolledIntoView() { + $location = $this->executor->execute( + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, + array(':id' => $this->id) + ); + return new WebDriverPoint($location['x'], $location['y']); + } + + /** + * @return WebDriverCoordinates + */ + public function getCoordinates() { + $element = $this; + + $on_screen = null; // planned but not yet implemented + $in_view_port = function () use ($element) { + return $element->getLocationOnScreenOnceScrolledIntoView(); + }; + $on_page = function () use ($element) { + return $element->getLocation(); + }; + $auxiliary = $this->getID(); + + return new WebDriverCoordinates( + $on_screen, + $in_view_port, + $on_page, + $auxiliary + ); + } + + /** + * Get the size of element. + * + * @return WebDriverDimension The dimension of the element. + */ + public function getSize() { + $size = $this->executor->execute( + DriverCommand::GET_ELEMENT_SIZE, + array(':id' => $this->id) + ); + return new WebDriverDimension($size['width'], $size['height']); + } + + /** + * Get the tag name of this element. + * + * @return string The tag name. + */ + public function getTagName() { + // Force tag name to be lowercase as expected by protocol for Opera driver + // until this issue is not resolved : + // https://github.com/operasoftware/operadriver/issues/102 + // Remove it when fixed to be consistent with the protocol. + return strtolower($this->executor->execute( + DriverCommand::GET_ELEMENT_TAG_NAME, + array(':id' => $this->id) + )); + } + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, + * including sub-elements, without any leading or trailing whitespace. + * + * @return string The visible innerText of this element. + */ + public function getText() { + return $this->executor->execute( + DriverCommand::GET_ELEMENT_TEXT, + array(':id' => $this->id) + ); + } + + /** + * Is this element displayed or not? This method avoids the problem of having + * to parse an element's "style" attribute. + * + * @return bool + */ + public function isDisplayed() { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_DISPLAYED, + array(':id' => $this->id) + ); + } + + /** + * Is the element currently enabled or not? This will generally return true + * for everything but disabled input elements. + * + * @return bool + */ + public function isEnabled() { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_ENABLED, + array(':id' => $this->id) + ); + } + + /** + * Determine whether or not this element is selected or not. + * + * @return bool + */ + public function isSelected() { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_SELECTED, + array(':id' => $this->id) + ); + } + + /** + * Simulate typing into an element, which may set its value. + * + * @param mixed $value The data to be typed. + * @return RemoteWebElement The current instance. + */ + public function sendKeys($value) { + $local_file = $this->fileDetector->getLocalFile($value); + if ($local_file === null) { + $params = array( + 'value' => WebDriverKeys::encode($value), + ':id' => $this->id, + ); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + } else { + $remote_path = $this->upload($local_file); + $params = array( + 'value' => WebDriverKeys::encode($remote_path), + ':id' => $this->id, + ); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + } + return $this; + } + + /** + * Upload a local file to the server + * + * @param string $local_file + * + * @throws WebDriverException + * @return string The remote path of the file. + */ + private function upload($local_file) { + if (!is_file($local_file)) { + throw new WebDriverException("You may only upload files: " . $local_file); + } + + // Create a temporary file in the system temp directory. + $temp_zip = tempnam('', 'WebDriverZip'); + $zip = new ZipArchive(); + if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { + return false; + } + $info = pathinfo($local_file); + $file_name = $info['basename']; + $zip->addFile($local_file, $file_name); + $zip->close(); + $params = array( + 'file' => base64_encode(file_get_contents($temp_zip)), + ); + $remote_path = $this->executor->execute( + DriverCommand::UPLOAD_FILE, + $params + ); + unlink($temp_zip); + return $remote_path; + } + + /** + * Set the fileDetector in order to let the RemoteWebElement to know that + * you are going to upload a file. + * + * Basically, if you want WebDriver trying to send a file, set the fileDetector + * to be LocalFileDetector. Otherwise, keep it UselessFileDetector. + * + * eg. $element->setFileDetector(new LocalFileDetector); + * + * @param FileDetector $detector + * @return RemoteWebElement + * @see FileDetector + * @see LocalFileDetector + * @see UselessFileDetector + */ + public function setFileDetector(FileDetector $detector) { + $this->fileDetector = $detector; + return $this; + } + + /** + * If this current element is a form, or an element within a form, then this + * will be submitted to the remote server. + * + * @return RemoteWebElement The current instance. + */ + public function submit() { + $this->executor->execute( + DriverCommand::SUBMIT_ELEMENT, + array(':id' => $this->id) + ); + + return $this; + } + + /** + * Get the opaque ID of the element. + * + * @return string The opaque ID. + */ + public function getID() { + return $this->id; + } + + /** + * Test if two element IDs refer to the same DOM element. + * + * @param WebDriverElement $other + * @return bool + */ + public function equals(WebDriverElement $other) { + return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, array( + ':id' => $this->id, + ':other' => $other->getID(), + )); + } + + /** + * Return the WebDriverElement with $id + * + * @param string $id + * + * @return RemoteWebElement + */ + private function newElement($id) { + return new RemoteWebElement($this->executor, $id); + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/UselessFileDetector.php b/tests/vendor/facebook/webdriver/lib/remote/UselessFileDetector.php new file mode 100644 index 000000000000..db4c3f2cdd55 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/UselessFileDetector.php @@ -0,0 +1,25 @@ +sessionID = $session_id; + $this->name = $name; + $this->parameters = $parameters; + } + + public function getName() { + return $this->name; + } + + public function getSessionID() { + return $this->sessionID; + } + + public function getParameters() { + return $this->parameters; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/WebDriverResponse.php b/tests/vendor/facebook/webdriver/lib/remote/WebDriverResponse.php new file mode 100644 index 000000000000..a42e3067cac2 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/WebDriverResponse.php @@ -0,0 +1,87 @@ +sessionID = $session_id; + } + + /** + * @return null|int + */ + public function getStatus() { + return $this->status; + } + + /** + * @param int $status + * @return WebDriverResponse + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + + /** + * @return mixed + */ + public function getValue() { + return $this->value; + } + + /** + * @param mixed $value + * @return WebDriverResponse + */ + public function setValue($value) { + $this->value = $value; + return $this; + } + + /** + * @return null|string + */ + public function getSessionID() { + return $this->sessionID; + } + + /** + * @param mixed $session_id + * @return WebDriverResponse + */ + public function setSessionID($session_id) { + $this->sessionID = $session_id; + return $this; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/service/DriverCommandExecutor.php b/tests/vendor/facebook/webdriver/lib/remote/service/DriverCommandExecutor.php new file mode 100644 index 000000000000..51cdda466d11 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/service/DriverCommandExecutor.php @@ -0,0 +1,57 @@ +getURL()); + $this->service = $service; + } + + /** + * @param WebDriverCommand $command + * @param array $curl_opts + * + * @return mixed + */ + public function execute(WebDriverCommand $command, $curl_opts = array()) { + if ($command->getName() === DriverCommand::NEW_SESSION) { + $this->service->start(); + } + + try { + $value = parent::execute($command, $curl_opts); + if ($command->getName() === DriverCommand::QUIT) { + $this->service->stop(); + } + return $value; + } catch (Exception $e) { + if (!$this->service->isRunning()) { + throw new WebDriverException('The driver server has died.'); + } + throw $e; + } + } + +} diff --git a/tests/vendor/facebook/webdriver/lib/remote/service/DriverService.php b/tests/vendor/facebook/webdriver/lib/remote/service/DriverService.php new file mode 100644 index 000000000000..607bf8fb8ef0 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/remote/service/DriverService.php @@ -0,0 +1,142 @@ +executable = self::checkExecutable($executable); + $this->url = sprintf('http://localhost:%d', $port); + $this->args = $args; + $this->environment = $environment ?: $_ENV; + } + + /** + * @return string + */ + public function getURL() { + return $this->url; + } + + /** + * @return DriverService + */ + public function start() { + if ($this->process !== null) { + return $this; + } + + $pipes = array(); + $this->process = proc_open( + sprintf("%s %s", $this->executable, implode(' ', $this->args)), + $descriptorspec = array( + 0 => array('pipe', 'r'), // stdin + 1 => array('pipe', 'w'), // stdout + 2 => array('pipe', 'a'), // stderr + ), + $pipes, + null, + $this->environment + ); + + $checker = new URLChecker(); + $checker->waitUntilAvailable(20 * 1000, $this->url.'/status'); + + return $this; + } + + /** + * @return DriverService + */ + public function stop() { + if ($this->process === null) { + return $this; + } + + proc_terminate($this->process); + $this->process = null; + + $checker = new URLChecker(); + $checker->waitUntilUnAvailable(3 * 1000, $this->url.'/shutdown'); + + return $this; + } + + /** + * @return bool + */ + public function isRunning() { + if ($this->process === null) { + return false; + } + + $status = proc_get_status($this->process); + return $status['running']; + } + + /** + * Check if the executable is executable. + * + * @param string $executable + * @return string + * @throws Exception + */ + protected static function checkExecutable($executable) { + if (!is_file($executable)) { + throw new Exception("'$executable' is not a file."); + } + + if (!is_executable($executable)) { + throw new Exception("'$executable' is not executable."); + } + + return $executable; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriver.php b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriver.php new file mode 100644 index 000000000000..5f09493eb99c --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriver.php @@ -0,0 +1,351 @@ +dispatcher = $dispatcher ?: new WebDriverDispatcher(); + if (!$this->dispatcher->getDefaultDriver()) { + $this->dispatcher->setDefaultDriver($this); + } + $this->driver = $driver; + return $this; + } + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() { + return $this->dispatcher; + } + + /** + * @param mixed $method + * @return void + */ + protected function dispatch($method) { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + + /** + * @return WebDriver + */ + public function getWebDriver() { + return $this->driver; + } + + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + private function newElement(WebDriverElement $element) { + return new EventFiringWebElement($element, $this->getDispatcher()); + } + + /** + * @param mixed $url + * @return $this + * @throws WebDriverException + */ + public function get($url) { + $this->dispatch('beforeNavigateTo', $url, $this); + try { + $this->driver->get($url); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterNavigateTo', $url, $this); + return $this; + } + + /** + * @param WebDriverBy $by + * @return array + * @throws WebDriverException + */ + public function findElements(WebDriverBy $by) { + $this->dispatch('beforeFindBy', $by, null, $this); + try { + $elements = array(); + foreach ($this->driver->findElements($by) as $element) { + $elements[] = $this->newElement($element); + } + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterFindBy', $by, null, $this); + return $elements; + + } + + /** + * @param WebDriverBy $by + * @return EventFiringWebElement + * @throws WebDriverException + */ + public function findElement(WebDriverBy $by) { + $this->dispatch('beforeFindBy', $by, null, $this); + try { + $element = $this->newElement($this->driver->findElement($by)); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterFindBy', $by, null, $this); + return $element; + } + + /** + * @param $script + * @param array $arguments + * @return mixed + * @throws WebDriverException + */ + public function executeScript($script, array $arguments = array()) { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor' + ); + } + + $this->dispatch('beforeScript', $script, $this); + try { + $result = $this->driver->executeScript($script, $arguments); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterScript', $script, $this); + return $result; + } + + /** + * @param $script + * @param array $arguments + * @return mixed + * @throws WebDriverException + */ + public function executeAsyncScript($script, array $arguments = array()) { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor' + ); + } + + $this->dispatch('beforeScript', $script, $this); + try { + $result = $this->driver->executeAsyncScript($script, $arguments); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterScript', $script, $this); + return $result; + } + + /** + * @return $this + * @throws WebDriverException + */ + public function close() { + try { + $this->driver->close(); + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getCurrentURL() { + try { + return $this->driver->getCurrentURL(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getPageSource() { + try { + return $this->driver->getPageSource(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getTitle() { + try { + return $this->driver->getTitle(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getWindowHandle() { + try { + return $this->driver->getWindowHandle(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return array + * @throws WebDriverException + */ + public function getWindowHandles() { + try { + return $this->driver->getWindowHandles(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @throws WebDriverException + */ + public function quit() { + try { + $this->driver->quit(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param null|string $save_as + * @return string + * @throws WebDriverException + */ + public function takeScreenshot($save_as = null) { + try { + return $this->driver->takeScreenshot($save_as); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * @return WebDriverWait + * @throws WebDriverException + */ + public function wait($timeout_in_second = 30, + $interval_in_millisecond = 250) { + try { + return $this->driver->wait($timeout_in_second, $interval_in_millisecond); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverOptions + * @throws WebDriverException + */ + public function manage() { + try { + return $this->driver->manage(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return EventFiringWebDriverNavigation + * @throws WebDriverException + */ + public function navigate() { + try { + return new EventFiringWebDriverNavigation( + $this->driver->navigate(), + $this->getDispatcher() + ); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverTargetLocator + * @throws WebDriverException + */ + public function switchTo() { + try { + return $this->driver->switchTo(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverTouchScreen + * @throws WebDriverException + */ + public function getTouch() { + try { + return $this->driver->getTouch(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + private function dispatchOnException($exception) { + $this->dispatch('onException', $exception, $this); + throw $exception; + } + + public function execute($name, $params) { + try { + return $this->driver->execute($name, $params); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } +} diff --git a/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriverNavigation.php b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriverNavigation.php new file mode 100644 index 000000000000..5fb96f929df1 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebDriverNavigation.php @@ -0,0 +1,150 @@ +navigator = $navigator; + $this->dispatcher = $dispatcher; + return $this; + } + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() { + return $this->dispatcher; + } + + /** + * @param mixed $method + * @return void + */ + protected function dispatch($method) { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + + /** + * @return WebDriverNavigation + */ + public function getNavigator() { + return $this->navigator; + } + + /** + * @return $this + * @throws WebDriverException + */ + public function back() { + $this->dispatch( + 'beforeNavigateBack', + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->back(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateBack', + $this->getDispatcher()->getDefaultDriver() + ); + return $this; + } + + /** + * @return $this + * @throws WebDriverException + */ + public function forward() { + $this->dispatch( + 'beforeNavigateForward', + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->forward(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateForward', + $this->getDispatcher()->getDefaultDriver() + ); + return $this; + } + + /** + * @return $this + * @throws WebDriverException + */ + public function refresh() { + try { + $this->navigator->refresh(); + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param mixed $url + * @return $this + * @throws WebDriverException + */ + public function to($url) { + $this->dispatch( + 'beforeNavigateTo', + $url, + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->to($url); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateTo', + $url, + $this->getDispatcher()->getDefaultDriver() + ); + return $this; + } + + private function dispatchOnException($exception) { + $this->dispatch('onException', $exception); + throw $exception; + } +} diff --git a/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebElement.php b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebElement.php new file mode 100644 index 000000000000..1e0e499af175 --- /dev/null +++ b/tests/vendor/facebook/webdriver/lib/support/events/EventFiringWebElement.php @@ -0,0 +1,358 @@ +element = $element; + $this->dispatcher = $dispatcher; + return $this; + } + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() { + return $this->dispatcher; + } + + /** + * @param mixed $method + * @return void + */ + protected function dispatch($method) { + if (!$this->dispatcher) { + return; + } + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + + /** + * @return WebDriverElement + */ + public function getElement() { + return $this->element; + } + + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + private function newElement(WebDriverElement $element) { + return new EventFiringWebElement($element, $this->getDispatcher()); + } + + /** + * @param mixed $value + * @return $this + * @throws WebDriverException + */ + public function sendKeys($value) { + + $this->dispatch('beforeChangeValueOf', $this); + try { + $this->element->sendKeys($value); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterChangeValueOf', $this); + return $this; + + } + + /** + * @return $this + * @throws WebDriverException + */ + public function click() { + $this->dispatch('beforeClickOn', $this); + try { + $this->element->click(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterClickOn', $this); + return $this; + } + + /** + * @param WebDriverBy $by + * @return EventFiringWebElement + * @throws WebDriverException + */ + public function findElement(WebDriverBy $by) { + $this->dispatch( + 'beforeFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver()); + try { + $element = $this->newElement($this->element->findElement($by)); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + return $element; + } + + /** + * @param WebDriverBy $by + * @return array + * @throws WebDriverException + */ + public function findElements(WebDriverBy $by) { + $this->dispatch( + 'beforeFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + try { + $elements = array(); + foreach ($this->element->findElements($by) as $element) { + $elements[] = $this->newElement($element); + } + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + return $elements; + } + + /** + * @return $this + * @throws WebDriverException + */ + public function clear() { + try { + $this->element->clear(); + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param string $attribute_name + * @return string + * @throws WebDriverException + */ + public function getAttribute($attribute_name) { + try { + return $this->element->getAttribute($attribute_name); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param string $css_property_name + * @return string + * @throws WebDriverException + */ + public function getCSSValue($css_property_name) { + try { + return $this->element->getCSSValue($css_property_name); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverPoint + * @throws WebDriverException + */ + public function getLocation() { + try { + return $this->element->getLocation(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverPoint + * @throws WebDriverException + */ + public function getLocationOnScreenOnceScrolledIntoView() { + try { + return $this->element->getLocationOnScreenOnceScrolledIntoView(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return WebDriverCoordinates + */ + public function getCoordinates() { + try { + return $this->element->getCoordinates(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + + /** + * @return WebDriverDimension + * @throws WebDriverException + */ + public function getSize() { + try { + return $this->element->getSize(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getTagName() { + try { + return $this->element->getTagName(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getText() { + try { + return $this->element->getText(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return bool + * @throws WebDriverException + */ + public function isDisplayed() { + try { + return $this->element->isDisplayed(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return bool + * @throws WebDriverException + */ + public function isEnabled() { + try { + return $this->element->isEnabled(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return bool + * @throws WebDriverException + */ + public function isSelected() { + try { + return $this->element->isSelected(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return $this + * @throws WebDriverException + */ + public function submit() { + try { + $this->element->submit(); + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @return string + * @throws WebDriverException + */ + public function getID() { + try { + return $this->element->getID(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + + /** + * Test if two element IDs refer to the same DOM element. + * + * @param WebDriverElement $other + * @return bool + */ + public function equals(WebDriverElement $other) { + try { + return $this->element->equals($other); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + private function dispatchOnException($exception) { + $this->dispatch( + 'onException', + $exception, + $this->dispatcher->getDefaultDriver() + ); + throw $exception; + } + + +} diff --git a/tests/vendor/facebook/webdriver/tests/bootstrap.php b/tests/vendor/facebook/webdriver/tests/bootstrap.php new file mode 100644 index 000000000000..46df8183ea22 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/bootstrap.php @@ -0,0 +1,4 @@ +driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'php-webdriver test page', + $this->driver->getTitle() + ); + } + + public function testGetText() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Welcome to the facebook/php-webdriver testing page.', + $this->driver->findElement(WebDriverBy::id('welcome'))->getText() + ); + } + + public function testGetById() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by ID', + $this->driver->findElement(WebDriverBy::id('id_test'))->getText() + ); + } + + public function testGetByClassName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::className('test_class'))->getText() + ); + } + + public function testGetByCssSelector() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() + ); + } + + public function testGetByLinkText() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() + ); + } + + public function testGetByName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') + ); + } + + public function testGetByXpath() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') + ); + } + + public function testGetByPartialLinkText() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() + ); + } + + public function testGetByTagName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') + ); + } +} \ No newline at end of file diff --git a/tests/vendor/facebook/webdriver/tests/functional/FileUploadTest.php b/tests/vendor/facebook/webdriver/tests/functional/FileUploadTest.php new file mode 100644 index 000000000000..84ec454e8654 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/functional/FileUploadTest.php @@ -0,0 +1,42 @@ +driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->setFileDetector(new LocalFileDetector()) + ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); + self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + } + + public function testUselessFileDetectorSendKeys() { + $this->driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->sendKeys($this->getFilePath()); + self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + } + + private function getFilePath() { + return __DIR__ . '/files/FileUploadTestCaseFile.txt'; + } +} diff --git a/tests/vendor/facebook/webdriver/tests/functional/WebDriverTestCase.php b/tests/vendor/facebook/webdriver/tests/functional/WebDriverTestCase.php new file mode 100644 index 000000000000..4a5b77f6c067 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/functional/WebDriverTestCase.php @@ -0,0 +1,48 @@ +driver = RemoteWebDriver::create( + 'http://localhost:4444/wd/hub', + array( + WebDriverCapabilityType::BROWSER_NAME + //=> WebDriverBrowserType::FIREFOX, + => WebDriverBrowserType::HTMLUNIT, + ) + ); + } + + protected function tearDown() { + $this->driver->quit(); + } + + /** + * Get the URL of the test html. + * + * @param $path + * @return string + */ + protected function getTestPath($path) { + return 'file:///'.dirname(__FILE__).'/html/'.$path; + } +} diff --git a/tests/vendor/facebook/webdriver/tests/functional/files/FileUploadTestCaseFile.txt b/tests/vendor/facebook/webdriver/tests/functional/files/FileUploadTestCaseFile.txt new file mode 100644 index 000000000000..0ca232e37120 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/functional/files/FileUploadTestCaseFile.txt @@ -0,0 +1 @@ +text file diff --git a/tests/vendor/facebook/webdriver/tests/functional/html/index.html b/tests/vendor/facebook/webdriver/tests/functional/html/index.html new file mode 100644 index 000000000000..6bafefdc9f69 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/functional/html/index.html @@ -0,0 +1,12 @@ + + + php-webdriver test page + + +

Welcome to the facebook/php-webdriver testing page.

+

Test by ID

+

Test by Class

+ Click here + + + \ No newline at end of file diff --git a/tests/vendor/facebook/webdriver/tests/functional/html/upload.html b/tests/vendor/facebook/webdriver/tests/functional/html/upload.html new file mode 100644 index 000000000000..d542ad04f7c1 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/functional/html/upload.html @@ -0,0 +1,10 @@ + + + Upload a file + + +
+ +
+ + diff --git a/tests/vendor/facebook/webdriver/tests/phpunit.xml b/tests/vendor/facebook/webdriver/tests/phpunit.xml new file mode 100644 index 000000000000..88bf4dbdefd2 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/phpunit.xml @@ -0,0 +1,25 @@ + + + + + + + + ./unit + + + ./functional + + + + diff --git a/tests/vendor/facebook/webdriver/tests/unit/bootstrap.php b/tests/vendor/facebook/webdriver/tests/unit/bootstrap.php new file mode 100644 index 000000000000..562467964031 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/bootstrap.php @@ -0,0 +1,3 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsMouseUpCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverButtonReleaseAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickActionTest.php new file mode 100644 index 000000000000..98fd39197406 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -0,0 +1,40 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAction = new WebDriverClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php new file mode 100644 index 000000000000..fe1826ee078e --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -0,0 +1,40 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsMouseDownCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAndHoldAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverContextClickActionTest.php new file mode 100644 index 000000000000..7ac3162cc95b --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -0,0 +1,40 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverContextClickAction = new WebDriverContextClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsContextClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverContextClickAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverCoordinatesTest.php new file mode 100644 index 000000000000..cf4cc0d12fc9 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -0,0 +1,38 @@ +getAuxiliary()); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php new file mode 100644 index 000000000000..a0c85ac0d3a4 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -0,0 +1,40 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsDoubleClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverDoubleClickAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php new file mode 100644 index 000000000000..f82b25cb1c36 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -0,0 +1,44 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyDownAction = new WebDriverKeyDownAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('pressKey'); + $this->webDriverKeyDownAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php new file mode 100644 index 000000000000..e35277bd7583 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -0,0 +1,45 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyUpAction = new WebDriverKeyUpAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + 'a' + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); + $this->webDriverKeyUpAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php new file mode 100644 index 000000000000..aec3444d3883 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -0,0 +1,40 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMouseMoveAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php new file mode 100644 index 000000000000..2cd2bc75d162 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -0,0 +1,42 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( + $this->webDriverMouse, + $this->locationProvider, + 150, + 200 + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMoveToOffsetAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php new file mode 100644 index 000000000000..9f9cad84b160 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -0,0 +1,47 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->keys = array('t', 'e', 's', 't'); + $this->webDriverSendKeysAction = new WebDriverSendKeysAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + $this->keys + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverSendKeysAction->perform(); + } +} diff --git a/tests/vendor/facebook/webdriver/tests/unit/phpunit.xml b/tests/vendor/facebook/webdriver/tests/unit/phpunit.xml new file mode 100644 index 000000000000..0338c9327827 --- /dev/null +++ b/tests/vendor/facebook/webdriver/tests/unit/phpunit.xml @@ -0,0 +1,22 @@ + + + + + + + + ../unit + + + +