diff --git a/composer.lock b/composer.lock index 14a575f564e67cde1c07fdf200c838e6bf7ab83e..29d4ecbb45b90c9960abd9f6219efe1ae9eefb07 100644 --- a/composer.lock +++ b/composer.lock @@ -2896,6 +2896,67 @@ ], "time": "2016-03-05T09:04:22+00:00" }, + { + "name": "behat/mink-selenium2-driver", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", + "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/473a9f3ebe0c134ee1e623ce8a9c852832020288", + "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288", + "shasum": "" + }, + "require": { + "behat/mink": "~1.7@dev", + "instaclick/php-webdriver": "~1.1", + "php": ">=5.3.1" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "time": "2016-03-05T09:10:18+00:00" + }, { "name": "doctrine/instantiator", "version": "1.0.5", @@ -3036,6 +3097,65 @@ ], "time": "2017-01-03T13:21:43+00:00" }, + { + "name": "instaclick/php-webdriver", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/instaclick/php-webdriver.git", + "reference": "6fa959452e774dcaed543faad3a9d1a37d803327" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/6fa959452e774dcaed543faad3a9d1a37d803327", + "reference": "6fa959452e774dcaed543faad3a9d1a37d803327", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0||^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "WebDriver": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Justin Bishop", + "email": "jubishop@gmail.com", + "role": "Developer" + }, + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "role": "Fork Maintainer" + } + ], + "description": "PHP WebDriver for Selenium 2", + "homepage": "http://instaclick.com/", + "keywords": [ + "browser", + "selenium", + "webdriver", + "webtest" + ], + "time": "2017-06-30T04:02:48+00:00" + }, { "name": "ircmaxell/password-compat", "version": "v1.0.4", diff --git a/core/composer.json b/core/composer.json index 1f60805ffb11346a3c47f2eb1a050b9d880656c1..a6d52d1082cbf5c26747e644472bc639427ae7f8 100644 --- a/core/composer.json +++ b/core/composer.json @@ -48,7 +48,8 @@ "phpspec/prophecy": "^1.4", "symfony/css-selector": "^3.4.0", "symfony/phpunit-bridge": "^3.4.3", - "symfony/debug": "^3.4.0" + "symfony/debug": "^3.4.0", + "behat/mink-selenium2-driver": "^1.3" }, "replace": { "drupal/action": "self.version", diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist index 963d921a7e828d25c660f8fdc513f8a2b62a3669..2a55d680f3def84e0fb5e90e6ffec5802b748e8f 100644 --- a/core/phpunit.xml.dist +++ b/core/phpunit.xml.dist @@ -30,8 +30,10 @@ + + diff --git a/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php b/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php new file mode 100644 index 0000000000000000000000000000000000000000..5f243af67094f653f15eeb1e2658ae282e83c504 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php @@ -0,0 +1,35 @@ +getWebDriverSession()->deleteCookie($name); + return; + } + + $cookieArray = [ + 'name' => $name, + 'value' => urlencode($value), + 'secure' => FALSE, + // Unlike \Behat\Mink\Driver\Selenium2Driver::setCookie we set a domain + // and an expire date, as otherwise cookies leak from one test site into + // another. + 'domain' => parse_url($this->getWebDriverSession()->url(), PHP_URL_HOST), + 'expires' => time() + 80000, + ]; + + $this->getWebDriverSession()->setCookie($cookieArray); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php index d49d46ee6a6cf9d80bf845fe2ee88072468a7ea4..55b1284f708a4fd4858da419f5b20d1f18bde3ed 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php @@ -15,6 +15,9 @@ abstract class JavascriptTestBase extends BrowserTestBase { /** * {@inheritdoc} + * + * To use a webdriver based approach, please use DrupalSelenium2Driver::class. + * We will switch the default later. */ protected $minkDefaultDriverClass = PhantomJSDriver::class; @@ -22,14 +25,19 @@ abstract class JavascriptTestBase extends BrowserTestBase { * {@inheritdoc} */ protected function initMink() { - // Set up the template cache used by the PhantomJS mink driver. - $path = $this->tempFilesDirectory . DIRECTORY_SEPARATOR . 'browsertestbase-templatecache'; - $this->minkDefaultDriverArgs = [ - 'http://127.0.0.1:8510', - $path, - ]; - if (!file_exists($path)) { - mkdir($path); + if ($this->minkDefaultDriverClass === DrupalSelenium2Driver::class) { + $this->minkDefaultDriverArgs = ['chrome', NULL, 'http://localhost:4444/']; + } + elseif ($this->minkDefaultDriverClass === PhantomJSDriver::class) { + // Set up the template cache used by the PhantomJS mink driver. + $path = $this->tempFilesDirectory . DIRECTORY_SEPARATOR . 'browsertestbase-templatecache'; + $this->minkDefaultDriverArgs = [ + 'http://127.0.0.1:8510', + $path, + ]; + if (!file_exists($path)) { + mkdir($path); + } } try { @@ -67,7 +75,13 @@ protected function tearDown() { * {@inheritdoc} */ protected function getMinkDriverArgs() { - return getenv('MINK_DRIVER_ARGS_PHANTOMJS') ?: parent::getMinkDriverArgs(); + if ($this->minkDefaultDriverClass === DrupalSelenium2Driver::class) { + return getenv('MINK_DRIVER_ARGS_WEBDRIVER') ?: getenv('MINK_DRIVER_ARGS_PHANTOMJS') ?: parent::getMinkDriverArgs(); + } + elseif ($this->minkDefaultDriverClass === PhantomJSDriver::class) { + return getenv('MINK_DRIVER_ARGS_PHANTOMJS') ?: parent::getMinkDriverArgs(); + } + return parent::getMinkDriverArgs(); } /** @@ -176,4 +190,12 @@ protected function getDrupalSettings() { return $this->getSession()->evaluateScript($script) ?: []; } + /** + * {@inheritdoc} + */ + protected function getHtmlOutputHeaders() { + // The webdriver API does not support fetching headers. + return ''; + } + } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php index 7cef5b8c6c37436e8c66bf2d981765bd7779bc43..b3baf6e2d377b6793728bfb1dd70394215f7ee07 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\FunctionalJavascriptTests; +use Zumba\Mink\Driver\PhantomJSDriver; + /** * Runs a browser test using PhantomJS. * @@ -9,6 +11,11 @@ */ abstract class LegacyJavascriptTestBase extends JavascriptTestBase { + /** + * {@inheritdoc} + */ + protected $minkDefaultDriverClass = PhantomJSDriver::class; + /** * {@inheritdoc} */ diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebWithWebDriverAssertTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebWithWebDriverAssertTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d31a9a51c3fdbe8672dc87cdf65ba974d6addff7 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebWithWebDriverAssertTest.php @@ -0,0 +1,19 @@ +&1 >> /dev/null & - ``` * Run the functional tests: ``` export SIMPLETEST_DB='mysql://root@localhost/dev_d8' export SIMPLETEST_BASE_URL='http://d8.dev' ./vendor/bin/phpunit -c core --testsuite functional - ./vendor/bin/phpunit -c core --testsuite functional-javascript ``` Note: functional tests have to be invoked with a user in the same group as the @@ -37,6 +32,67 @@ User Group ``` +## Functional javascript tests + +Javascript tests use the Selenium2Driver which allows you to control a +big range of browsers. By default Drupal uses chromedriver to run tests. +For help installing and starting selenium, see http://mink.behat.org/en/latest/drivers/selenium2.html + +* Make sure you have a recent version of chrome installed + +* Install selenium-server-standalone and chromedriver + +Example for Mac: + +``` +brew install selenium-server-standalone +brew install chromedriver +``` + +* Before running tests make sure that selenium-server is running +``` +selenium-server -port 4444 +``` + +* Set the correct driver args and run the tests: +``` +export MINK_DRIVER_ARGS_WEBDRIVER='["chrome", null, "http://localhost:4444/wd/hub"]' +./vendor/bin/phpunit -c core --testsuite functional-javascript +``` + +* It is possible to use alternate browsers if the required dependencies are +installed. For example to use Firefox: + +``` +export MINK_DRIVER_ARGS_WEBDRIVER='["firefox", null, "http://localhost:4444/wd/hub"]' +./vendor/bin/phpunit -c core --testsuite functional-javascript +``` + +* To force all BrowserTestBase (including legacy JavascriptTestBase) tests to use +webdriver: + +``` +export MINK_DRIVER_CLASS='Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' +./vendor/bin/phpunit -c core --testsuite functional-javascript +``` + +## Running legacy javascript tests + +Older javascript test may use the PhantomJSDriver. To run these tests you will +have to install and start PhantomJS. + +* Start PhantomJS: + ``` + phantomjs --ssl-protocol=any --ignore-ssl-errors=true ./vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 >> /dev/null & + ``` + +* Then you can run the test: +``` +./vendor/bin/phpunit -c core --testsuite functional-javascript +``` + +## Running tests with a different user + If the default user is e.g. `www-data`, the above functional tests will have to be invoked with sudo instead: