diff --git a/.travis.yml b/.travis.yml index bfaf3219e..8b8ed821e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: php dist: trusty +before_install: + - sudo apt-get update + - sudo apt-get install chromium-chromedriver + cache: directories: - $HOME/.composer/cache/files @@ -67,6 +71,10 @@ matrix: - PHPUNIT_TEST=framework before_script: +# Extra $PATH + - export PATH=~/.composer/vendor/bin:$PATH + - export PATH=/usr/lib/chromium-browser/:$PATH + # Init PHP - pecl channel-update pecl.php.net - phpenv rehash @@ -74,11 +82,10 @@ before_script: - echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini # Install composer dependencies - - export PATH=~/.composer/vendor/bin:$PATH - composer validate - if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:2.0.x-dev --no-update; fi - if [[ $DB == SQLITE ]]; then composer require silverstripe/sqlite3:2.0.x-dev --no-update; fi - - composer require silverstripe/recipe-core:1.0.x-dev silverstripe/admin:1.0.x-dev silverstripe/versioned:1.0.x-dev --no-update + - composer require silverstripe/recipe-testing:^1 silverstripe/recipe-core:1.0.x-dev silverstripe/admin:1.0.x-dev silverstripe/versioned:1.0.x-dev --no-update - if [[ $PHPUNIT_TEST == cms ]] || [[ $BEHAT_TEST == cms ]]; then composer require silverstripe/recipe-cms:1.0.x-dev --no-update; fi - if [[ $PHPCS_TEST ]]; then composer global require squizlabs/php_codesniffer:^3 --prefer-dist --no-interaction --no-progress --no-suggest -o; fi - composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile @@ -90,7 +97,7 @@ before_script: - if [[ $BEHAT_TEST ]]; then mkdir artifacts; fi - if [[ $BEHAT_TEST ]]; then cp composer.lock artifacts/; fi - if [[ $BEHAT_TEST ]]; then sh -e /etc/init.d/xvfb start; sleep 3; fi - - if [[ $BEHAT_TEST ]]; then (vendor/bin/selenium-server-standalone > artifacts/selenium.log 2>&1 &); fi + - if [[ $BEHAT_TEST ]]; then (chromedriver > artifacts/chromedriver.log 2>&1 &); fi - if [[ $BEHAT_TEST == framework ]]; then (vendor/bin/serve --bootstrap-file tests/behat/serve-bootstrap.php &> artifacts/serve.log &); fi - if [[ $BEHAT_TEST == cms ]]; then (vendor/bin/serve --bootstrap-file vendor/silverstripe/cms/tests/behat/serve-bootstrap.php &> artifacts/serve.log &); fi diff --git a/behat.yml b/behat.yml index faf1eea89..f6d329195 100644 --- a/behat.yml +++ b/behat.yml @@ -23,10 +23,11 @@ default: extensions: SilverStripe\BehatExtension\MinkExtension: - default_session: selenium2 - javascript_session: selenium2 - selenium2: - browser: firefox + default_session: facebook_web_driver + javascript_session: facebook_web_driver + facebook_web_driver: + browser: chrome + wd_host: "http://127.0.0.1:9515" #chromedriver port SilverStripe\BehatExtension\Extension: screenshot_path: %paths.base%/artifacts/screenshots diff --git a/composer.json b/composer.json index 52309b90a..d4ffc904c 100644 --- a/composer.json +++ b/composer.json @@ -52,10 +52,7 @@ }, "require-dev": { "phpunit/phpunit": "^5.7", - "silverstripe/versioned": "^1.0", - "silverstripe/behat-extension": "^3", - "silverstripe/serve": "^2", - "se/selenium-server-standalone": "2.41.0" + "silverstripe/versioned": "^1.0" }, "provide": { "psr/container-implementation": "1.0.0" diff --git a/tests/behat/features/reauthenticate.feature b/tests/behat/features/reauthenticate.feature index 15b648e9e..236c2d851 100644 --- a/tests/behat/features/reauthenticate.feature +++ b/tests/behat/features/reauthenticate.feature @@ -18,8 +18,9 @@ Feature: Reauthenticate When I fill in "Password" with "Secret!123" And I press the "Let me back in" button And I am not in an iframe - And I click "ADMIN" in the "#Root_Users" element - Then I should see "Save" in the "#Form_ItemEditForm_action_doSave" element + And I go to "/admin/security" + When I press the "Add Member" button + Then I should see "Create" in the "#Form_ItemEditForm_action_doSave" element Scenario: Reauthenticate with wrong login When I press the "Add Member" button @@ -31,5 +32,6 @@ Feature: Reauthenticate When I fill in "Password" with "Secret!123" And I press the "Let me back in" button And I am not in an iframe - And I click "ADMIN" in the "#Root_Users" element - Then I should see "Save" in the "#Form_ItemEditForm_action_doSave" element + And I go to "/admin/security" + When I press the "Add Member" button + Then I should see "Create" in the "#Form_ItemEditForm_action_doSave" element diff --git a/tests/behat/src/CmsFormsContext.php b/tests/behat/src/CmsFormsContext.php index c345cb891..50fab1a8b 100644 --- a/tests/behat/src/CmsFormsContext.php +++ b/tests/behat/src/CmsFormsContext.php @@ -6,6 +6,7 @@ use BadMethodCallException; use Behat\Behat\Context\Context; use Behat\Mink\Exception\ElementHtmlException; use Behat\Gherkin\Node\TableNode; +use Behat\Mink\Session; use SilverStripe\BehatExtension\Context\MainContextAwareTrait; use SilverStripe\BehatExtension\Utility\StepHelper; use Symfony\Component\DomCrawler\Crawler; @@ -24,6 +25,9 @@ class CmsFormsContext implements Context /** * Get Mink session from MinkContext + * + * @param string $name + * @return Session */ public function getSession($name = null) { @@ -210,6 +214,7 @@ JS; $page = $this->getSession()->getPage(); $els = $page->findAll('named', array('field', "'$text'")); $matchedEl = null; + /** @var NodeElement $el */ foreach ($els as $el) { if ($el->isVisible()) { $matchedEl = $el; @@ -267,6 +272,7 @@ JS; public function iSelectValueInTreeDropdown($text, $selector) { $page = $this->getSession()->getPage(); + /** @var NodeElement $parentElement */ $parentElement = null; $this->retryThrowable(function () use (&$parentElement, &$page, $selector) { $parentElement = $page->find('css', $selector); diff --git a/tests/behat/src/CmsUiContext.php b/tests/behat/src/CmsUiContext.php index 3796faa4e..502a20932 100644 --- a/tests/behat/src/CmsUiContext.php +++ b/tests/behat/src/CmsUiContext.php @@ -2,13 +2,13 @@ namespace SilverStripe\Framework\Tests\Behaviour; -use Behat\Behat\Hook\Call\AfterStep; -use Behat\Behat\Hook\Scope\AfterStepScope; -use Behat\Mink\Element\NodeElement; -use Behat\Mink\Session; use Behat\Behat\Context\Context; +use Behat\Behat\Hook\Scope\AfterStepScope; +use Behat\Mink\Element\Element; +use Behat\Mink\Element\NodeElement; +use Behat\Mink\Selector\Xpath\Escaper; +use Behat\Mink\Session; use SilverStripe\BehatExtension\Context\MainContextAwareTrait; -use SilverStripe\BehatExtension\Context\RetryableContextTrait; use SilverStripe\BehatExtension\Utility\StepHelper; /** @@ -24,6 +24,7 @@ class CmsUiContext implements Context /** * Get Mink session from MinkContext * + * @param string $name * @return Session */ public function getSession($name = null) @@ -306,6 +307,7 @@ class CmsUiContext implements Context $page = $this->getSession()->getPage(); $toggle_elements = $page->findAll('css', '.toggle-expand'); assertNotNull($toggle_elements, 'Panel toggle not found'); + /** @var NodeElement $toggle */ foreach ($toggle_elements as $toggle) { if ($toggle->isVisible()) { $toggle->click(); @@ -354,7 +356,6 @@ SCRIPT public function iExpandInTheTree($action, $nodeText) { //Tries to find the first visiable matched Node in the page - $page = $this->getSession()->getPage(); $treeEl = $this->getCmsTreeElement(); $treeNode = $treeEl->findLink($nodeText); assertNotNull($treeNode, sprintf('%s link not found', $nodeText)); @@ -391,6 +392,7 @@ SCRIPT assertNotNull($tabsets, 'CMS tabs not found'); $tab_element = null; + /** @var NodeElement $tabset */ foreach ($tabsets as $tabset) { $tab_element = $tabset->find('named', array('link_or_button', "'$tab'")); if ($tab_element) { @@ -419,6 +421,7 @@ SCRIPT assertNotNull($tabsets, 'CMS tabs not found'); $tab_element = null; + /** @var NodeElement $tabset */ foreach ($tabsets as $tabset) { if ($tab_element) { continue; @@ -443,14 +446,10 @@ SCRIPT */ public function thePreviewContains($content) { - $driver = $this->getSession()->getDriver(); - // TODO Remove once we have native support in Mink and php-webdriver, // see https://groups.google.com/forum/#!topic/behat/QNhOuGHKEWI - $origWindowName = $driver->getWebDriverSession()->window_handle(); - - $driver->switchToIFrame('cms-preview-iframe'); + $this->getSession()->switchToIFrame('cms-preview-iframe'); $this->getMainContext()->assertPageContainsText($content); - $driver->switchToWindow($origWindowName); + $this->getSession()->switchToWindow(); } /** @@ -467,17 +466,13 @@ SCRIPT */ public function iWaitForThePreviewToLoad() { - $driver = $this->getSession()->getDriver(); - // TODO Remove once we have native support in Mink and php-webdriver, // see https://groups.google.com/forum/#!topic/behat/QNhOuGHKEWI - $origWindowName = $driver->getWebDriverSession()->window_handle(); - - $driver->switchToIFrame('cms-preview-iframe'); + $this->getSession()->switchToIFrame('cms-preview-iframe'); $this->getSession()->wait( 5000, "window.jQuery && !window.jQuery('iframe[name=cms-preview-iframe]').hasClass('loading')" ); - $driver->switchToWindow($origWindowName); + $this->getSession()->switchToWindow(); } /** @@ -504,14 +499,10 @@ SCRIPT */ public function thePreviewDoesNotContain($content) { - $driver = $this->getSession()->getDriver(); - // TODO Remove once we have native support in Mink and php-webdriver, // see https://groups.google.com/forum/#!topic/behat/QNhOuGHKEWI - $origWindowName = $driver->getWebDriverSession()->window_handle(); - - $driver->switchToIFrame('cms-preview-iframe'); + $this->getSession()->switchToIFrame('cms-preview-iframe'); $this->getMainContext()->assertPageNotContainsText($content); - $driver->switchToWindow($origWindowName); + $this->getSession()->switchToWindow(); } /** @@ -521,16 +512,12 @@ SCRIPT */ public function clickLinkInPreview($link) { - $driver = $this->getSession()->getDriver(); // TODO Remove once we have native support in Mink and php-webdriver, // see https://groups.google.com/forum/#!topic/behat/QNhOuGHKEWI - $origWindowName = $driver->getWebDriverSession()->window_handle(); - $driver->switchToIFrame('cms-preview-iframe'); - + $this->getSession()->switchToIFrame('cms-preview-iframe'); $link = $this->fixStepArgument($link); $this->getSession()->getPage()->clickLink($link); - - $driver->switchToWindow($origWindowName); + $this->getSession()->switchToWindow(); } /** @@ -540,16 +527,11 @@ SCRIPT */ public function pressButtonInPreview($button) { - $driver = $this->getSession()->getDriver(); - // TODO Remove once we have native support in Mink and php-webdriver, // see https://groups.google.com/forum/#!topic/behat/QNhOuGHKEWI - $origWindowName = $driver->getWebDriverSession()->window_handle(); - $driver->switchToIFrame('cms-preview-iframe'); - + $this->getSession()->switchToIFrame('cms-preview-iframe'); $button = $this->fixStepArgument($button); $this->getSession()->getPage()->pressButton($button); - - $driver->switchToWindow($origWindowName); + $this->getSession()->switchToWindow(); } /** @@ -563,9 +545,10 @@ SCRIPT $field = $this->fixStepArgument($field); $value = $this->fixStepArgument($value); + $escaper = new Escaper(); $nativeField = $this->getSession()->getPage()->find( 'named', - array('select', $this->getSession()->getSelectorsHandler()->xpathLiteral($field)) + array('select', $escaper->escapeLiteral($field)) ); if ($nativeField && $nativeField->isVisible()) { $nativeField->selectOption($value); @@ -614,6 +597,7 @@ SCRIPT )); // Traverse up to field holder + /** @var NodeElement $container */ $container = null; foreach ($formFields as $formField) { $container = $this->findParentByClass($formField, 'field');