diff --git a/.ahoy.yml b/.ahoy.yml index 3d1ff181..bab29bf8 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -3,44 +3,49 @@ ahoyapi: v2 commands: - # Docker commands. build: usage: Build or rebuild project. cmd: | - ahoy title "Building project for Drupal $DRUPAL_VERSION" ahoy clean (docker network prune -f > /dev/null && docker network inspect amazeeio-network > /dev/null || docker network create amazeeio-network) - ahoy up -- --build --force-recreate - ahoy install-dev + ahoy up -- --build --force-recreate + docker cp -L . "$(docker-compose ps -q cli)":/app/ ahoy install-site - ahoy title "Build complete" ahoy info 1 info: usage: Print information about this project. cmd: | - ahoy line "Project : " $(ahoy cli echo \${PROJECT}) - ahoy line "Drupal version : " $(ahoy cli echo \$DRUPAL_VERSION) - ahoy line "Site local URL : " $(ahoy cli echo \$LOCALDEV_URL) - ahoy line "Path to project : " $(ahoy cli echo /app) - ahoy line "Path to web root : " $(ahoy cli echo /app/build/web) - ahoy line "DB port on host : " $(docker port $(docker-compose ps -q mariadb) 3306 | cut -d : -f 2) - ahoy line "Xdebug : " $(ahoy cli php -v|grep -q Xdebug && echo "Enabled" || echo "Disabled") - if [ "$1" ]; then - ahoy line "One-time login : " $(ahoy login -- --no-browser) + echo " Project : " $(ahoy cli echo \${PROJECT}) + echo " Drupal version : " $(ahoy cli echo \$DRUPAL_VERSION) + echo " Site local URL : " $(ahoy cli echo \$LOCALDEV_URL) + echo " Path to project : " $(ahoy cli echo /app) + echo " Path to web root : " $(ahoy cli echo /app/build/web) + echo " DB port on host : " $(docker port $(docker-compose ps -q mariadb) 3306 | cut -d : -f 2) + echo " Xdebug : " $(ahoy cli php -v|grep -q Xdebug && echo "Enabled" || echo "Disabled") + if [ -n "$1" ]; then + echo " One-time login : " $(ahoy login -- --no-browser) fi + db: + usage: Open DB in Sequel Ace. + cmd: | + uname -a | grep -i -q darwin && mdfind -name 'Sequel Ace'|grep -q "Ace" \ + && DREVOPS_HOST_DB_PORT="$(docker port $(docker-compose ps -q mariadb 2>/dev/null) 3306 2>/dev/null | cut -d : -f 2)" \ + && open "mysql://drupal:drupal@127.0.0.1:${DREVOPS_HOST_DB_PORT}/drupal" -a "Sequel Ace" \ + || echo "Not a supported OS or Sequel Ace is not installed." + + # ---------------------------------------------------------------------------- + # Docker commands. + # ---------------------------------------------------------------------------- + up: usage: Build and start Docker containers. - cmd: | - docker-compose up -d "$@" - sleep 10 # Wait for DB container to come up without using Dockerize. - if docker-compose logs | grep -q "\[Error\]"; then docker-compose logs; exit 1; fi - docker ps -a --filter name=^/${COMPOSE_PROJECT_NAME:-behat-steps}_ + cmd: docker-compose up -d "$@" && if docker-compose logs | grep -q "\[Error\]"; then exit 1; fi down: usage: Stop Docker containers and remove container, images, volumes and networks. - cmd: "if [ -f \"docker-compose.yml\" ]; then docker-compose down --volumes; fi" + cmd: if [ -f "docker-compose.yml" ]; then docker-compose down --volumes > /dev/null 2>&1; fi start: usage: Start existing Docker containers. @@ -60,43 +65,31 @@ commands: pull: usage: Pull latest docker images. - cmd: if [ ! -z "$(docker image ls -q)" ]; then docker image ls --format \"{{.Repository}}:{{.Tag}}\" | grep amazeeio/ | grep -v none | xargs -n1 docker pull | cat; fi + cmd: if [ ! -z "$(docker image ls -q)" ]; then docker image ls --format \"{{.Repository}}:{{.Tag}}\" | grep uselagoon/ | grep -v none | xargs -n1 docker pull | cat; fi cli: usage: Start a shell inside CLI container or run a command. - cmd: if \[ "${#}" -ne 0 \]; then docker exec -i $(docker-compose ps -q cli) bash -c "$*"; else docker exec -it $(docker-compose ps -q cli) bash; fi + cmd: if \[ "${#}" -ne 0 \]; then docker-compose exec -T cli bash -c "$*"; else docker-compose exec cli bash; fi + + composer: + usage: Run Composer commands in the CLI service container. + cmd: docker-compose exec -T cli composer "$@" drush: - usage: Run drush commands in the CLI service container. + usage: Run Drush commands in the CLI service container. cmd: docker-compose exec -T cli bash -c "drush -r /app/build/web -l \${LOCALDEV_URL} $*" + # ---------------------------------------------------------------------------- # Application commands. + # ---------------------------------------------------------------------------- + login: usage: Login to a website. - cmd: ahoy drush uublk 1 -q && ahoy drush uli "$@" + cmd: ahoy drush uli "$@" install-site: usage: Install a fixture test site. - cmd: | - ahoy title "Installing fixture Drupal $DRUPAL_VERSION site" - # Remove exiting build assets. - ahoy cli "chmod -Rf 777 /app/build/web || true; rm -Rf /app/build/web || true; rm -Rf /app/build/vendor || true; mkdir -p /app/build/web" - # Copy fixture files to the build dir. - ahoy cli "cp -Rf /app/tests/behat/fixtures/d\$DRUPAL_VERSION/. /app/build/" - # In CI, where volume mounting into container is not supported, copy all files into container. - [ ${CI+x} ] && docker cp -L . $(docker-compose ps -q cli):/app/ || true - # Copy tool configs and tests into build dir. - docker cp -L phpcs.xml $(docker-compose ps -q cli):/app/build - docker cp -L behat.yml $(docker-compose ps -q cli):/app/build - docker cp -L tests $(docker-compose ps -q cli):/app/build - # Install Composer dependencies inside of the build dir. - ahoy cli "COMPOSER_MEMORY_LIMIT=-1 composer --working-dir=/app/build install --prefer-dist --no-suggest" - # Install Drupal site. - ahoy cli "/usr/bin/env PHP_OPTIONS='-d sendmail_path=/bin/true' /app/build/vendor/bin/drush -r /app/build/web si standard -y --db-url=mysql://drupal:drupal@mariadb/drupal --account-name=admin --account-pass=admin install_configure_form.enable_update_status_module=NULL install_configure_form.enable_update_status_emails=NULL --uri=http://nginx" - # Run post-install commands defined in the composer.json for each sepecific fixture. - ahoy cli "composer --working-dir=/app/build drupal-post-install" - # Copy test fixture. - ahoy cli "cp /app/tests/behat/fixtures/relative.html /app/build/web/sites/default/files/relative.html" + cmd: ahoy cli "./.circleci/install-site.sh" clean: usage: Remove containers and all build files. @@ -112,59 +105,29 @@ commands: reset: usage: "Reset environment: remove containers, all build, manually created and Drupal-Dev files." - cmd: | - ahoy clean - rm -rf ./screenshots \ - ./composer.lock - - install-dev: - usage: Install dependencies for this package. - cmd: | - ahoy cli "mkdir -p /app/build" - [ ${CI+x} ] && docker cp -L . $(docker-compose ps -q cli):/app/ || true - docker cp -L tests $(docker-compose ps -q cli):/app/ - docker cp -L phpcs.xml $(docker-compose ps -q cli):/app/ - docker cp -L behat.yml $(docker-compose ps -q cli):/app/build/ - ahoy cli "COMPOSER_MEMORY_LIMIT=-1 composer install -n --ansi --prefer-dist" - hide: true - - update-fixtures: - usage: Update fixture files for Drupal - cmd: rsync -av --delete --no-progress --exclude-from=tests/behat/fixtures/d$DRUPAL_VERSION/.rsync-exclude build/ tests/behat/fixtures/d$DRUPAL_VERSION/ + cmd: ahoy clean && rm -rf ./screenshots ./composer.lock lint: - usage: Lint all code. - cmd: | - ahoy cli "vendor/bin/parallel-lint --exclude vendor --exclude node_modules -e \$PHP_LINT_EXTENSIONS \${PHP_LINT_TARGETS//,/ }" && \ - ahoy cli "vendor/bin/phpcs -v \${PHPCS_TARGETS//,/ }" + usage: Lint code. + cmd: ahoy cli "cd /app/build && vendor/bin/phpcs --standard=../phpcs.xml" test-bdd: usage: Run BDD tests. - cmd: ahoy cli "cd /app/build && BEHAT_SCREENSHOT_DIR=/app/screenshots BEHAT_SCREENSHOT_PURGE=${BEHAT_SCREENSHOT_PURGE:-} vendor/bin/behat --strict --colors --profile=d$DRUPAL_VERSION $@" + cmd: ahoy cli "cd /app/build && vendor/bin/behat -c /app/behat.yml --strict --colors --profile=d${DRUPAL_VERSION} $@" debug: - usage: Enable debug configuration. + usage: Enable PHP Xdebug. cmd: ahoy cli php -v | grep -q Xdebug || XDEBUG_ENABLE=true ahoy up cli php nginx && ahoy cli php -v | grep -q Xdebug && echo "Enabled debug confguration. Use 'ahoy up' to disable." - # Utilities. - confirm: - cmd: read -r -p "${@} [y/N] " response; [ ${response} = "y" ] - hide: true - - title: - cmd: printf "$(tput -Txterm setaf 4)==> ${1}$(tput -Txterm sgr0)\n" - hide: true - - line: - cmd: printf "$(tput -Txterm setaf 2)${1}$(tput -Txterm sgr0)${2}\n" - hide: true + update-fixtures: + usage: Update fixture files for Drupal. + cmd: rsync -av --delete --no-progress --exclude-from=tests/behat/fixtures/d$DRUPAL_VERSION/.rsync-exclude build/ tests/behat/fixtures/d$DRUPAL_VERSION/ entrypoint: - bash - "-c" - "-e" - | - [ -f .env ] && [ -s .env ] && export $(grep -v '^#' .env | xargs) && if [ -f .env.local ] && [ -s .env.local ]; then export $(grep -v '^#' .env.local | xargs); fi export DRUPAL_VERSION=${DRUPAL_VERSION:-9} bash -e -c "$0" "$@" - '{{cmd}}' diff --git a/.circleci/build.sh b/.circleci/build.sh deleted file mode 100755 index 9088c016..00000000 --- a/.circleci/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -## -# Build. -# -set -e - -echo "==> Validate composer" -composer validate --ansi --strict - -# Process Docker Compose configuration. This is used to avoid multiple -# docker-compose.yml files. -# Remove lines containing '###'. -sed -i -e "/###/d" docker-compose.yml -# Uncomment lines containing '##'. -sed -i -e "s/##//" docker-compose.yml - -echo "==> Initialise Drupal site" -ahoy build diff --git a/.circleci/config.yml b/.circleci/config.yml index 0cc05d59..3c7e1940 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,15 +12,28 @@ aliases: steps: - checkout - setup_remote_docker + - run: + name: Adjust codebase for CI + command: sed -i -e "/###/d" docker-compose.yml && sed -i -e "s/##//" docker-compose.yml - run: name: Build - command: .circleci/build.sh + command: ahoy build no_output_timeout: 30m - - run: .circleci/test.sh + - run: + name: Lint code + command: ahoy lint + - run: + name: Run tests + command: ahoy test-bdd - run: name: Process artifacts - command: .circleci/process-artifacts.sh + command: | + ahoy cli "mkdir -p /app/screenshots" + mkdir -p /tmp/artifacts/behat + docker cp "$(docker-compose ps -q cli)":/app/screenshots /tmp/artifacts/behat when: always + - store_test_results: + path: /tmp/test_results - store_artifacts: path: /tmp/artifacts diff --git a/.circleci/install-site.sh b/.circleci/install-site.sh new file mode 100755 index 00000000..9c8c3eb9 --- /dev/null +++ b/.circleci/install-site.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +## +# Install site. +# +# shellcheck disable=SC2015,SC2094 + +set -e +[ -n "${DREVOPS_DEBUG}" ] && set -x + +DRUPAL_VERSION="${DRUPAL_VERSION:-9}" + +echo "==> Starting installation of fixture Drupal $DRUPAL_VERSION site." + +echo " > Removing existing build assets." +chmod -Rf 777 /app/build || true; rm -Rf /app/build || true + +echo " > Copying fixture files to the build dir." +cp -Rf "/app/tests/behat/fixtures/d${DRUPAL_VERSION}/." /app/build/ + +echo " > Validating fixture Composer configuration." +composer --working-dir=/app/build validate --ansi --strict --no-check-all + +echo " > Merging configuration from module's composer.json." +php -r "echo json_encode(array_replace_recursive(json_decode(file_get_contents('/app/composer.json'), true),json_decode(file_get_contents('/app/build/composer.json'), true)),JSON_PRETTY_PRINT);" > "/app/build/composer2.json" && mv -f "/app/build/composer2.json" "/app/build/composer.json" + +echo " > Updating relative paths in build composer.json." +sed_opts=(-i) && [ "$(uname)" == "Darwin" ] && sed_opts=(-i '') +sed "${sed_opts[@]}" "s|\"src|\"../src|" "build/composer.json" && sleep 2 + +echo " > Validating merged fixture Composer configuration." +composer --working-dir=/app/build validate --ansi --strict --no-check-all + +echo " > Installing Composer dependencies inside the build dir." +COMPOSER_MEMORY_LIMIT=-1 composer --working-dir=/app/build install --prefer-dist + +echo " > Installing Drupal site." +/usr/bin/env PHP_OPTIONS='-d sendmail_path=/bin/true' /app/build/vendor/bin/drush -r /app/build/web si standard -y --db-url=mysql://drupal:drupal@mariadb/drupal --account-name=admin --account-pass=admin install_configure_form.enable_update_status_module=NULL install_configure_form.enable_update_status_emails=NULL --uri=http://nginx + +echo " > Running post-install commands defined in the composer.json for each specific fixture." +composer --working-dir=/app/build drupal-post-install + +echo " > Copying test fixture." +cp /app/tests/behat/fixtures/relative.html /app/build/web/sites/default/files/relative.html + +echo " > Bootstrapping site." +/app/build/vendor/bin/drush -r /app/build/web --uri=http://nginx status --fields=bootstrap | grep -q "Successful" && echo " Success" || ( echo "ERROR: Unable to bootstrap a site" && exit 1 ) + +echo "==> Finished installation of fixture Drupal $DRUPAL_VERSION site." diff --git a/.circleci/process-artifacts.sh b/.circleci/process-artifacts.sh deleted file mode 100755 index e5d99ce5..00000000 --- a/.circleci/process-artifacts.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -## -# Process test artifacts. -# -set -e - -# Create screenshots directory in case it was not created before. This is to -# avoid this script to fail when copying artifacts. -ahoy cli "mkdir -p /app/screenshots" - -# Copy from the app container to the build host for storage. -mkdir -p /tmp/artifacts/behat -docker cp "$(docker-compose ps -q cli)":/app/screenshots /tmp/artifacts/behat diff --git a/.circleci/test.sh b/.circleci/test.sh deleted file mode 100755 index eb9556a2..00000000 --- a/.circleci/test.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -## -# Run tests. -# -set -e - -echo "==> Lint code" -ahoy lint - -echo "==> Run BDD tests" -ahoy test-bdd -- "--format=progress_fail" || ahoy test-bdd -- "--rerun --format=progress_fail" diff --git a/.gitattributes b/.gitattributes index c7dc854e..805e2546 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,12 @@ # Ignore files for distribution archives. -.circleci export-ignore -.ahoy.yml export-ignore -.editorconfig export-ignore -.env export-ignore -.gitattributes export-ignore -.gitignore export-ignore -behat.yml export-ignore -docker-compose.yml export-ignore -phpcs.xml export-ignore -tests export-ignore +.circleci export-ignore +.ahoy.yml export-ignore +.editorconfig export-ignore +.env export-ignore +.gitattributes export-ignore +.gitignore export-ignore +behat.yml export-ignore +default.docker-compose.override.yml export-ignore +docker-compose.yml export-ignore +phpcs.xml export-ignore +tests export-ignore diff --git a/.gitignore b/.gitignore index de2df32b..45a72793 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,5 @@ vendor /composer.lock build screenshots -.env.local docker-compose.override.yml todo.txt diff --git a/README.md b/README.md index 4fb488d4..8684eed7 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,26 @@ # Behat Steps -Collection of Behat steps for Drupal 9, Drupal 8 and Drupal 7. +Collection of Behat steps for Drupal -[![CircleCI](https://circleci.com/gh/drevops/behat-steps.svg?style=shield)](https://circleci.com/gh/drevops/behat-steps) +[![CircleCI](https://dl.circleci.com/status-badge/img/gh/drevops/behat-steps/tree/master.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/drevops/behat-steps/tree/master) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/drevops/behat-steps) [![Total Downloads](https://poser.pugx.org/drevops/behat-steps/downloads)](https://packagist.org/packages/drevops/behat-steps) ![LICENSE](https://img.shields.io/github/license/drevops/behat-steps) # Why traits? -Usually, such packages implement own Drupal driver with several contexts, service containers and a lot of other useful architectural structures. -But for this simple library, using traits helps to lower entry barrier for usage, maintenance and support. + +Usually, such packages implement own Drupal driver with several contexts, +service containers and a lot of other useful architectural structures. +But for this simple library, using traits helps to lower entry barrier for usage, +maintenance and support. This package may later be refactored to use proper architecture. # Installation + `composer require --dev drevops/behat-steps` # Usage -Add required traits to `FeatureContext.php`: + +Add required traits to `FeatureContext.php` ([example](tests/behat/bootstrap/FeatureContext.php)): ``` warning - - - * - - - - src/*Trait.php - tests/behat/bootstrap/*.php - - - - * - - - - * - - - - * - diff --git a/src/ContentTrait.php b/src/ContentTrait.php index 55dff75d..1aa42a31 100644 --- a/src/ContentTrait.php +++ b/src/ContentTrait.php @@ -8,6 +8,8 @@ /** * Trait ContentTrait. * + * Content-related steps. + * * @package DrevOps\BehatSteps */ trait ContentTrait { @@ -133,6 +135,8 @@ public function contentModeratePageWithTitle($type, $title, $old_state, $new_sta } /** + * Visit scheduled-transition page for node with title. + * * @When I visit :type :title scheduled transitions */ public function contentVisitScheduledTransitionsPageWithTitle($type, $title) { @@ -151,7 +155,7 @@ public function contentVisitScheduledTransitionsPageWithTitle($type, $title) { } /** - * Helper to load multiple nodes with specified type and conditions. + * Load multiple nodes with specified type and conditions. * * @param string $type * The node type. diff --git a/src/D7/ContentTrait.php b/src/D7/ContentTrait.php index 78da893f..cbf1423e 100644 --- a/src/D7/ContentTrait.php +++ b/src/D7/ContentTrait.php @@ -7,6 +7,8 @@ /** * Trait ContentTrait. * + * Steps to work with content for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait ContentTrait { diff --git a/src/D7/DomainTrait.php b/src/D7/DomainTrait.php index 61826d39..9dd1cfc8 100644 --- a/src/D7/DomainTrait.php +++ b/src/D7/DomainTrait.php @@ -8,6 +8,8 @@ /** * Trait DomainTrait. * + * Steps to work with Domain for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait DomainTrait { @@ -85,7 +87,7 @@ public function domainVisitHomepage($subdomain) { } /** - * Helper to build URL from the result of parse_url(). + * Build URL from the result of parse_url(). */ protected function domainBuildUrl(array $parts) { return (isset($parts['scheme']) ? "{$parts['scheme']}:" : '') . diff --git a/src/D7/EmailTrait.php b/src/D7/EmailTrait.php index 785a6d7a..b7156f2f 100644 --- a/src/D7/EmailTrait.php +++ b/src/D7/EmailTrait.php @@ -9,11 +9,15 @@ /** * Trait EmailTrait. * + * Steps to work with emails for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait EmailTrait { /** + * Enable email tracking before scenario. + * * @BeforeScenario */ public function emailBeforeScenarioEnableTestEmailSystem(BeforeScenarioScope $scope) { @@ -28,6 +32,8 @@ public function emailBeforeScenarioEnableTestEmailSystem(BeforeScenarioScope $sc } /** + * Disable email tracking before scenario. + * * @AfterScenario */ public function emailAfterScenarioDisableTestEmailSystem(AfterScenarioScope $scope) { @@ -165,7 +171,7 @@ public function emailAssertFieldContains($field, PyStringNode $string, $exact = $string = strval($string); $string = $exact ? $string : trim(preg_replace('/\s+/', ' ', $string)); foreach ($this->emailGetCollectedEmails() as $email) { - $field_string = $exact ? $email[$field] : trim(preg_replace('/\s+/', ' ', $email[$field]));; + $field_string = $exact ? $email[$field] : trim(preg_replace('/\s+/', ' ', $email[$field])); if (strpos($field_string, $string) !== FALSE) { return $email; } @@ -210,7 +216,7 @@ public function emailAssertFieldNotContains($field, PyStringNode $string, $exact $string = strval($string); $string = $exact ? $string : trim(preg_replace('/\s+/', ' ', $string)); foreach ($this->emailGetCollectedEmails() as $email) { - $field_string = $exact ? $email[$field] : trim(preg_replace('/\s+/', ' ', $email[$field]));; + $field_string = $exact ? $email[$field] : trim(preg_replace('/\s+/', ' ', $email[$field])); if (strpos($field_string, $string) !== FALSE) { throw new \Exception(sprintf('Found email with%s text "%s" in field "%s" retrieved from test email collector, but should not.', ($exact ? ' exact' : ''), $string, $field)); } diff --git a/src/D7/FieldCollectionTrait.php b/src/D7/FieldCollectionTrait.php index 16aae817..9451a777 100644 --- a/src/D7/FieldCollectionTrait.php +++ b/src/D7/FieldCollectionTrait.php @@ -9,6 +9,8 @@ /** * Trait FieldCollectionTrait. * + * Steps to work with Field Collections for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait FieldCollectionTrait { @@ -28,6 +30,8 @@ trait FieldCollectionTrait { protected static $fieldCollectionItemsFields; /** + * Parse fields for a field collection. + * * @BeforeNodeCreate */ public static function fieldCollectionParseFields(BeforeNodeCreateScope $scope) { diff --git a/src/D7/FileDownloadTrait.php b/src/D7/FileDownloadTrait.php index f86519ee..4cfc3a93 100644 --- a/src/D7/FileDownloadTrait.php +++ b/src/D7/FileDownloadTrait.php @@ -29,6 +29,8 @@ trait FileDownloadTrait { protected $fileDownloadFileInfo; /** + * Prepare scenario to work with this trait. + * * @BeforeScenario */ public function fileDownloadBeforeScenario(BeforeScenarioScope $scope) { @@ -44,6 +46,8 @@ public function fileDownloadBeforeScenario(BeforeScenarioScope $scope) { } /** + * Cleanup after scenario run. + * * @AfterScenario */ public function fileDownloadAfterScenario(AfterScenarioScope $scope) { @@ -349,7 +353,7 @@ protected function fileDownloadProcess($url, $options = []) { } /** - * Helper to extract downloaded file information from the response headers. + * Extract downloaded file information from the response headers. * * @param array $headers * Array of headers from CURL. @@ -376,7 +380,7 @@ protected function fileDownloadParseHeaders(array $headers) { } /** - * Helper to prepare temporary directory for file downloads. + * Prepare temporary directory for file downloads. */ protected function fileDownloadPrepareTempDir() { $fs = new Filesystem(); @@ -386,7 +390,7 @@ protected function fileDownloadPrepareTempDir() { } /** - * Helper to remove temporary directory for file downloads. + * Remove temporary directory for file downloads. */ protected function fileDownloadRemoveTempDir() { $fs = new Filesystem(); diff --git a/src/D7/FileTrait.php b/src/D7/FileTrait.php index c264a06b..cbbcdb94 100644 --- a/src/D7/FileTrait.php +++ b/src/D7/FileTrait.php @@ -7,6 +7,8 @@ /** * Trait FileTrait. * + * Steps to work with files for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait FileTrait { @@ -73,6 +75,8 @@ public function fileCreateManaged(TableNode $nodesTable) { } /** + * Remove all created files. + * * @AfterFeature */ public static function fileRemoveAll() { diff --git a/src/D7/MediaTrait.php b/src/D7/MediaTrait.php index caf4dd30..be34e8f0 100644 --- a/src/D7/MediaTrait.php +++ b/src/D7/MediaTrait.php @@ -5,6 +5,8 @@ /** * Trait MediaTrait. * + * Steps to work with media for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait MediaTrait { diff --git a/src/D7/ParagraphsTrait.php b/src/D7/ParagraphsTrait.php index 44268732..01ce8da1 100644 --- a/src/D7/ParagraphsTrait.php +++ b/src/D7/ParagraphsTrait.php @@ -7,6 +7,8 @@ /** * Trait ParagraphsTrait. * + * Steps to work with paragraphs for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait ParagraphsTrait { diff --git a/src/D7/TaxonomyTrait.php b/src/D7/TaxonomyTrait.php index 7b5382b3..c9fdd078 100644 --- a/src/D7/TaxonomyTrait.php +++ b/src/D7/TaxonomyTrait.php @@ -7,6 +7,8 @@ /** * Trait TaxonomyTrait. * + * Steps to work with Taxonopmy Terms for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait TaxonomyTrait { diff --git a/src/D7/UserTrait.php b/src/D7/UserTrait.php index fceb6bd2..8e82a282 100644 --- a/src/D7/UserTrait.php +++ b/src/D7/UserTrait.php @@ -7,6 +7,8 @@ /** * Trait UserTrait. * + * Steps to work with users for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait UserTrait { diff --git a/src/D7/VariableTrait.php b/src/D7/VariableTrait.php index daf19861..4c4754ea 100644 --- a/src/D7/VariableTrait.php +++ b/src/D7/VariableTrait.php @@ -8,11 +8,15 @@ /** * Trait VariableTrait. * + * Steps to work with variables for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait VariableTrait { /** + * Set a variable to a value. + * * @Given I set variable :name to value :value * @Given I set variable :name to value: */ @@ -22,6 +26,8 @@ public function variableSet($name, $value) { } /** + * Delete a variable with a name. + * * @Given I delete variable :name */ public function variableDelete($name) { @@ -30,6 +36,8 @@ public function variableDelete($name) { } /** + * Assert that a variable has a value. + * * @Then variable :name has value :value * @Then variable :name has value: */ @@ -42,6 +50,8 @@ public function variableAssertValue($name, $value) { } /** + * Assert that a variable does not have a value. + * * @Then variable :name does not have value :value */ public function variableAssertNotValue($name, $value) { @@ -53,6 +63,8 @@ public function variableAssertNotValue($name, $value) { } /** + * Assert that a variable does not have a value. + * * @Then variable :name does not have a value */ public function variableAssertNullValue($name) { @@ -82,6 +94,8 @@ public function variableStoreOriginal($variable_name) { } /** + * Restore original variable values. + * * @Given I restore original variables */ public function variableRestoreOriginal() { diff --git a/src/D7/WatchdogTrait.php b/src/D7/WatchdogTrait.php index 71ca2e86..0848c957 100644 --- a/src/D7/WatchdogTrait.php +++ b/src/D7/WatchdogTrait.php @@ -8,6 +8,8 @@ /** * Trait WatchdogTrait. * + * Steps to work with watchdog for Drupal 7. + * * @package DrevOps\BehatSteps\D7 */ trait WatchdogTrait { diff --git a/src/DateTrait.php b/src/DateTrait.php index 7a094e0d..4067dcac 100644 --- a/src/DateTrait.php +++ b/src/DateTrait.php @@ -5,6 +5,8 @@ /** * Trait DateTrait. * + * Date-related steps. + * * @package DrevOps\BehatSteps */ trait DateTrait { diff --git a/src/DraggableViewsTrait.php b/src/DraggableViewsTrait.php index 1d6ae1cb..d5d75375 100644 --- a/src/DraggableViewsTrait.php +++ b/src/DraggableViewsTrait.php @@ -11,11 +11,15 @@ /** * Trait DraggableViewsTrait. * - * @note: This is currently limited to nodes only. + * Draggable Views-related steps. + * + * @note This is currently limited to nodes only. */ trait DraggableViewsTrait { /** + * Save order of the Draggable Order items. + * * @Then I save draggable views :view_id view :views_display_id display :bundle items in the following order: */ public function draggableViewsSaveBundleOrder($view_id, $view_display_id, $bundle, TableNode $order_table) { diff --git a/src/EckTrait.php b/src/EckTrait.php index 7e95ae75..fc668505 100644 --- a/src/EckTrait.php +++ b/src/EckTrait.php @@ -9,7 +9,9 @@ /** * Trait EckTrait. * - * @package IntegratedExperts\BehatSteps\D8 + * Entity Contraction Kit-related steps. + * + * @package DrevOps\BehatSteps */ trait EckTrait { @@ -60,6 +62,8 @@ public function eckDeleteEntities($bundle, $entity_type, TableNode $table) { } /** + * Remove ECK types and entities. + * * @AfterScenario */ public function eckEntitiesCleanAll(AfterScenarioScope $scope) { @@ -85,7 +89,7 @@ public function eckEntitiesCleanAll(AfterScenarioScope $scope) { } /** - * Helper to load multiple entities with specified type and conditions. + * Load multiple entities with specified type and conditions. * * @param string $entity_type * The entity type. @@ -112,7 +116,7 @@ protected function eckEntityLoadMultiple($entity_type, $bundle, array $condition } /** - * Helper to create custom content entities. + * Create custom content entities. * * @param string $entity_type * The content entity type. @@ -130,7 +134,7 @@ protected function eckCreateEntities($entity_type, $bundle, TableNode $table) { } /** - * Helper to create a single content entity. + * Create a single content entity. * * @param string $entity_type * The content entity type. diff --git a/src/ElementTrait.php b/src/ElementTrait.php index 1b2f3b6b..f493d1f1 100644 --- a/src/ElementTrait.php +++ b/src/ElementTrait.php @@ -5,11 +5,15 @@ /** * Trait Element. * + * Steps to work with HTML element. + * * @package DrevOps\BehatSteps */ trait ElementTrait { /** + * Assert that an element with selector and attribute with a value exists. + * * @Then I( should) see the :selector element with the :attribute attribute set to :value */ public function elementAssertAttributeHasValue($selector, $attribute, $value) { diff --git a/src/EmailTrait.php b/src/EmailTrait.php index 6794d513..193c81c1 100644 --- a/src/EmailTrait.php +++ b/src/EmailTrait.php @@ -10,6 +10,8 @@ /** * Trait EmailTrait. * + * Email-related steps. + * * Behat trait for email interactions. */ trait EmailTrait { @@ -29,6 +31,8 @@ trait EmailTrait { protected $emailDebug = FALSE; /** + * Enable email tracking. + * * @BeforeScenario */ public function emailBeforeScenarioEnableTestEmailSystem(BeforeScenarioScope $scope) { @@ -55,6 +59,8 @@ public function emailBeforeScenarioEnableTestEmailSystem(BeforeScenarioScope $sc } /** + * Disable email tracking. + * * @AfterScenario */ public function emailAfterScenarioDisableTestEmailSystem(AfterScenarioScope $scope) { @@ -69,6 +75,8 @@ public function emailAfterScenarioDisableTestEmailSystem(AfterScenarioScope $sco } /** + * Enable test email system. + * * @Given I enable the test email system */ public function emailEnableTestEmailSystem() { @@ -89,6 +97,8 @@ public function emailEnableTestEmailSystem() { } /** + * Disable test email system. + * * @Given I disable the test email system */ public function emailDisableTestEmailSystem() { @@ -103,6 +113,8 @@ public function emailDisableTestEmailSystem() { } /** + * Clear test email system queue. + * * @When I clear the test email system queue */ public function emailClearTestEmailSystemQueue($force = FALSE) { @@ -114,6 +126,8 @@ public function emailClearTestEmailSystemQueue($force = FALSE) { } /** + * Assert that an email was sent to an address. + * * @Then an email is sent to :address */ public function emailAssertEmailIsSentTo($address) { @@ -128,6 +142,8 @@ public function emailAssertEmailIsSentTo($address) { } /** + * Assert that no email messages were sent. + * * @Then no emails were sent */ public function emailAssertNoEmailsWereSent() { @@ -137,6 +153,8 @@ public function emailAssertNoEmailsWereSent() { } /** + * Assert that no email messages were sent to a specified address. + * * @Then no emails were sent to :address */ public function emailAssertNoEmailsWereSentToAddress($address) { @@ -163,6 +181,8 @@ public function emailAssertNoEmailsWereSentToAddress($address) { } /** + * Assert that an email message header contains specified content. + * * @Then an email header :header contains: */ public function emailAssertEmailHeadersContains($header, PyStringNode $string, $exact = FALSE) { @@ -181,6 +201,8 @@ public function emailAssertEmailHeadersContains($header, PyStringNode $string, $ } /** + * Assert that an email message header contains exact specified content. + * * @Then an email header :header contains exact: */ public function emailAssertEmailHeadersContainsExact($header, PyStringNode $string) { @@ -188,6 +210,8 @@ public function emailAssertEmailHeadersContainsExact($header, PyStringNode $stri } /** + * Assert that an email message was sent or not sent to a user with content. + * * @Then /^an email to "(?P[^"]*)" user is "(?P[^"]*)" with "(?P[^"]*)" content:$/ */ public function emailAssertEmailToUserIsActionWithContent($name, $action, $field, PyStringNode $string) { @@ -209,6 +233,8 @@ public function emailAssertEmailToUserIsActionWithContent($name, $action, $field } /** + * Assert that an email message field contains a value. + * * @Then an email :field contains * @Then an email :field contains: */ @@ -231,6 +257,8 @@ public function emailAssertEmailContains($field, PyStringNode $string, $exact = } /** + * Assert that an email message field contains an exact value. + * * @Then an email :field contains exact * @Then an email :field contains exact: */ @@ -239,6 +267,8 @@ public function emailAssertEmailContainsExact($field, PyStringNode $string) { } /** + * Assert that an email message field does not contain a value. + * * @Then an email :field does not contain * @Then an email :field does not contain: */ @@ -258,6 +288,8 @@ public function emailAssertEmailNotContains($field, PyStringNode $string, $exact } /** + * Assert that an email message field does not contain an exact value. + * * @Then an email :field does not contain exact * @Then an email :field does not contain exact: */ @@ -266,6 +298,8 @@ public function emailAssertEmailNotContainsExact($field, PyStringNode $string) { } /** + * Visit a link from the email. + * * @When I follow the link number :number in the email with the subject * @When I follow the link number :number in the email with the subject: */ @@ -285,6 +319,8 @@ public function emailFollowLinkNumber($number, PyStringNode $subject) { } /** + * Assert that a file is attached to an email message with specified subject. + * * @Then file :name attached to the email with the subject * @Then file :name attached to the email with the subject: */ diff --git a/src/FieldTrait.php b/src/FieldTrait.php index 0ee5d5a4..86a38c4d 100644 --- a/src/FieldTrait.php +++ b/src/FieldTrait.php @@ -7,6 +7,8 @@ /** * Trait Field. * + * Field-related steps. + * * @package DrevOps\BehatSteps */ trait FieldTrait { @@ -59,8 +61,6 @@ public function fieldAssertNotExists($field_name) { /** * Assert whether the field exists on the page using id,name,label or value. * - * Shorthand helper to use in Scenario Outline. - * * @code * Then field "Body" "exists" on the page * Then field "field_body" "exists" on the page @@ -105,8 +105,6 @@ public function fieldAssertState($field_name, $disabled) { /** * Assert whether the field exists on the page and has a state. * - * Shorthand helper to use in Scenario Outline. - * * @code * Then field "Body" should be "present" on the page and have state "enabled" * Then field "Tags" should be "absent" on the page and have state "n/a" diff --git a/src/FileDownloadTrait.php b/src/FileDownloadTrait.php index 0e2448a5..a18c042b 100644 --- a/src/FileDownloadTrait.php +++ b/src/FileDownloadTrait.php @@ -11,6 +11,10 @@ /** * Trait FileDownloadTrait. + * + * Steps to work with file downloads. + * + * @package DrevOps\BehatSteps */ trait FileDownloadTrait { @@ -22,6 +26,8 @@ trait FileDownloadTrait { protected $fileDownloadDownloadedFileInfo; /** + * Prepare scenario to work with this trait. + * * @BeforeScenario */ public function fileDownloadBeforeScenario(BeforeScenarioScope $scope) { @@ -37,6 +43,8 @@ public function fileDownloadBeforeScenario(BeforeScenarioScope $scope) { } /** + * Cleanup after scenario run. + * * @AfterScenario */ public function fileDownloadAfterScenario(AfterScenarioScope $scope) { @@ -51,6 +59,8 @@ public function fileDownloadAfterScenario(AfterScenarioScope $scope) { } /** + * Download a file from the specified URL. + * * @Then I download file from :url */ public function fileDownloadFrom($url) { @@ -91,6 +101,8 @@ public function fileDownloadFrom($url) { } /** + * Download the file from the specified HTML link. + * * @Then I download file from link :link */ public function fileDownloadFromLink($link) { @@ -101,6 +113,8 @@ public function fileDownloadFromLink($link) { } /** + * Assert that an HTML link is present or absent on the page. + * * @Then I see download :link link :presence(on the page) */ public function fileDownloadAssertLinkPresence($link, $presense) { @@ -120,6 +134,8 @@ public function fileDownloadAssertLinkPresence($link, $presense) { } /** + * Assert the contents of the download file. + * * @Then downloaded file contains: */ public function fileDownloadAssertFileContains(PyStringNode $string) { @@ -143,6 +159,8 @@ public function fileDownloadAssertFileContains(PyStringNode $string) { } /** + * Assert the file name of the downloaded file. + * * @Then downloaded file name is :name */ public function fileDownloadAssertFileName($name) { @@ -156,6 +174,8 @@ public function fileDownloadAssertFileName($name) { } /** + * Assert downloaded file is a ZIP archive and it contains files. + * * @Then downloaded file is zip archive that contains files: */ public function fileDownloadAssertZipContains(TableNode $files) { @@ -174,6 +194,8 @@ public function fileDownloadAssertZipContains(TableNode $files) { } /** + * Assert downloaded file is a ZIP archive and it does not contain files. + * * @Then downloaded file is zip archive that does not contain files: */ public function fileDownloadAssertNoZipContains(TableNode $files) { @@ -288,7 +310,7 @@ protected function fileDownloadProcess($url, $options = []) { } /** - * Helper to extract downloaded file information from the response headers. + * Extract downloaded file information from the response headers. * * @param array $headers * Array of headers from CURL. @@ -314,7 +336,7 @@ protected function fileDownloadParseHeaders(array $headers) { } /** - * Helper to prepare temporary directory for file downloads. + * Prepare temporary directory for file downloads. */ protected function fileDownloadPrepareTempDir() { $fs = new Filesystem(); @@ -324,7 +346,7 @@ protected function fileDownloadPrepareTempDir() { } /** - * Helper to remove temporary directory for file downloads. + * Remove temporary directory for file downloads. */ protected function fileDownloadRemoveTempDir() { $fs = new Filesystem(); diff --git a/src/FileTrait.php b/src/FileTrait.php index 69aa03a2..3b02948a 100644 --- a/src/FileTrait.php +++ b/src/FileTrait.php @@ -11,6 +11,10 @@ /** * Trait FileTrait. + * + * File-related steps. + * + * @package DrevOps\BehatSteps */ trait FileTrait { @@ -53,6 +57,8 @@ public function fileBeforeScenarioInit(BeforeScenarioScope $scope) { } /** + * Create managed file with properties provided in the table. + * * @Given managed file: */ public function fileCreateManaged(TableNode $nodesTable) { @@ -113,6 +119,8 @@ protected function fileCreateEntity($stub) { } /** + * Clean all created managed files after scenario run. + * * @AfterScenario */ public function fileCleanAll(AfterScenarioScope $scope) { @@ -154,7 +162,7 @@ public function fileDeleteManagedFiles(TableNode $nodesTable) { } /** - * Helper to load multiple files with specified conditions. + * Load multiple files with specified conditions. * * @param array $conditions * Conditions keyed by field names. @@ -175,6 +183,8 @@ protected function fileLoadMultiple(array $conditions = []) { } /** + * Create an unmanaged file with specified content. + * * @Given unmanaged file :uri created */ public function fileCreateUnmanaged($uri, $content = 'test') { @@ -189,6 +199,8 @@ public function fileCreateUnmanaged($uri, $content = 'test') { } /** + * Create an unmanaged file with specified content. + * * @Given unmanaged file :uri created with content :content */ public function fileCreateUnmanagedWithContent($uri, $content) { @@ -196,15 +208,19 @@ public function fileCreateUnmanagedWithContent($uri, $content) { } /** + * Assert that an unmanaged file with specified URI exists. + * * @Then unmanaged file :uri exists */ public function fileAssertUnmanagedExists($uri) { if (!@file_exists($uri)) { - throw new \Exception(sprintf('The file %s does not exists.', $uri)); + throw new \Exception(sprintf('The file %s does not exist.', $uri)); } } /** + * Assert that an unmanaged file with specified URI does not exist. + * * @Then unmanaged file :uri does not exist */ public function fileAssertUnmanagedNotExists($uri) { @@ -214,6 +230,8 @@ public function fileAssertUnmanagedNotExists($uri) { } /** + * Assert that an unmanaged file exists and has specified content. + * * @Then unmanaged file :uri has content :content */ public function fileAssertUnmanagedHasContent($uri, $content) { @@ -227,6 +245,8 @@ public function fileAssertUnmanagedHasContent($uri, $content) { } /** + * Assert that an unmanaged file exists and does not have specified content. + * * @Then unmanaged file :uri does not have content :content */ public function fileAssertUnmanagedHasNoContent($uri, $content) { diff --git a/src/JsTrait.php b/src/JsTrait.php index de9c9469..d83a23c6 100644 --- a/src/JsTrait.php +++ b/src/JsTrait.php @@ -8,6 +8,8 @@ /** * Trait JsTrait. * + * JavaScript-related steps. + * * @package DrevOps\BehatSteps */ trait JsTrait { @@ -101,6 +103,8 @@ public function jsClickOnElement($element) { } /** + * Trigger an event on the specified element. + * * @When I trigger JS :event event on :selector element */ public function jsTriggerElementEvent($event, $selector) { diff --git a/src/KeyboardTrait.php b/src/KeyboardTrait.php index b3f500d5..ea9f3586 100644 --- a/src/KeyboardTrait.php +++ b/src/KeyboardTrait.php @@ -13,6 +13,8 @@ trait KeyboardTrait { /** + * Press multiple keyboard keys, optionally on element. + * * @Given I press the :keys keys * @Given I press the :keys keys on :selector */ diff --git a/src/LinkTrait.php b/src/LinkTrait.php index 1aca7348..69f71fde 100644 --- a/src/LinkTrait.php +++ b/src/LinkTrait.php @@ -5,6 +5,8 @@ /** * Trait LinkTrait. * + * Link-related steps. + * * @package DrevOps\BehatSteps */ trait LinkTrait { @@ -55,6 +57,8 @@ public function linkAssertTextHref($text, $href, $locator = NULL) { } /** + * Assert that a link with a title exists. + * * @Then the link with title :title exists */ public function linkAssertWithTitle($title) { @@ -70,6 +74,8 @@ public function linkAssertWithTitle($title) { } /** + * Assert that a link with a title does not exist. + * * @Then the link with title :title does not exist */ public function linkAssertWithNoTitle($title) { @@ -83,6 +89,8 @@ public function linkAssertWithNoTitle($title) { } /** + * Click on the link with a title. + * * @Then I click the link with title :title */ public function linkClickWithTitle($title) { diff --git a/src/MediaTrait.php b/src/MediaTrait.php index 043288ca..aaf2ad47 100644 --- a/src/MediaTrait.php +++ b/src/MediaTrait.php @@ -187,7 +187,7 @@ public function mediaEditWithName($type, $name) { } /** - * Helper to load multiple media entities with specified type and conditions. + * Load multiple media entities with specified type and conditions. * * @param string $type * The node type. diff --git a/src/MenuTrait.php b/src/MenuTrait.php index 2fbcefa1..3fbe6291 100644 --- a/src/MenuTrait.php +++ b/src/MenuTrait.php @@ -10,6 +10,8 @@ /** * Trait MenuTrait. * + * Menu-related steps. + * * @package DrevOps\BehatSteps */ trait MenuTrait { @@ -126,6 +128,8 @@ public function menuLinksCreate($menu_name, TableNode $table) { } /** + * Remove all menu items after scenario run. + * * @AfterScenario */ public function menuCleanAll(AfterScenarioScope $scope) { diff --git a/src/OverrideTrait.php b/src/OverrideTrait.php index b65a118d..db149f2b 100644 --- a/src/OverrideTrait.php +++ b/src/OverrideTrait.php @@ -33,6 +33,8 @@ public function createTerms($vocabulary, TableNode $table) { } /** + * Creates content of a given type provided in the tabular form. + * * @Given :type content: */ public function createNodes($type, TableNode $table) { @@ -43,6 +45,8 @@ public function createNodes($type, TableNode $table) { } /** + * Creates multiple users. + * * @Given users: */ public function createUsers(TableNode $table) { diff --git a/src/ParagraphsTrait.php b/src/ParagraphsTrait.php index d0c706b4..fcc8ad89 100644 --- a/src/ParagraphsTrait.php +++ b/src/ParagraphsTrait.php @@ -9,6 +9,10 @@ /** * Trait ParagraphsTrait. + * + * Paragraphs-related steps. + * + * @package DrevOps\BehatSteps */ trait ParagraphsTrait { @@ -20,6 +24,8 @@ trait ParagraphsTrait { protected static $paragraphs = []; /** + * Clean all paragraphs instances after scenario run. + * * @AfterScenario */ public function paragraphsCleanAll(AfterScenarioScope $scope) { diff --git a/src/PathTrait.php b/src/PathTrait.php index 217ea07f..67322697 100644 --- a/src/PathTrait.php +++ b/src/PathTrait.php @@ -5,6 +5,8 @@ /** * Trait PathTrait. * + * Path-related assertions. + * * @package DrevOps\BehatSteps */ trait PathTrait { diff --git a/src/ResponseTrait.php b/src/ResponseTrait.php index 772012fe..387dce6b 100644 --- a/src/ResponseTrait.php +++ b/src/ResponseTrait.php @@ -5,6 +5,8 @@ /** * Trait ResponseTrait. * + * Response-related steps. + * * @package DrevOps\BehatSteps */ trait ResponseTrait { diff --git a/src/RoleTrait.php b/src/RoleTrait.php index 654f0a52..b6da36ca 100644 --- a/src/RoleTrait.php +++ b/src/RoleTrait.php @@ -8,6 +8,10 @@ /** * Trait RoleTrait. + * + * Role-related steps. + * + * @package DrevOps\BehatSteps */ trait RoleTrait { @@ -19,6 +23,8 @@ trait RoleTrait { protected $roles = []; /** + * Create a single role with specified permisisons. + * * @Given role :name with permissions :permissions */ public function roleCreateSingle($name, $permissions) { @@ -51,6 +57,8 @@ public function roleCreateSingle($name, $permissions) { } /** + * Create multiple roles from the specified table. + * * @Given roles: */ public function roleCreateMultiple(TableNode $table) { @@ -66,6 +74,8 @@ public function roleCreateMultiple(TableNode $table) { } /** + * Remove all roles after scenario run. + * * @AfterScenario */ public function roleCleanAll(AfterScenarioScope $scope) { diff --git a/src/SearchApiTrait.php b/src/SearchApiTrait.php index 43bd6e97..3b360356 100644 --- a/src/SearchApiTrait.php +++ b/src/SearchApiTrait.php @@ -7,6 +7,8 @@ /** * Trait SearchApiTrait. * + * Search API-related steps. + * * @package DrevOps\BehatSteps */ trait SearchApiTrait { diff --git a/src/SelectTrait.php b/src/SelectTrait.php index a2f9ff67..d7b1b23e 100644 --- a/src/SelectTrait.php +++ b/src/SelectTrait.php @@ -5,11 +5,15 @@ /** * Trait SelectTrait. * + * Steps to work with HTML select element. + * * @package DrevOps\BehatSteps */ trait SelectTrait { /** + * Assert that a select has an option. + * * @Then select :select should have an option :option */ public function selectShouldHaveOption($select, $option) { @@ -25,6 +29,8 @@ public function selectShouldHaveOption($select, $option) { } /** + * Assert that a select does not have an option. + * * @Then select :select should not have an option :option */ public function selectShouldNotHaveOption($select, $option) { @@ -40,6 +46,8 @@ public function selectShouldNotHaveOption($select, $option) { } /** + * Assert that a select option is selected. + * * @Then /^the option "([^"]*)" from select "([^"]*)" is selected$/ */ public function selectOptionSelected($optionValue, $select) { diff --git a/src/TaxonomyTrait.php b/src/TaxonomyTrait.php index a67a8641..9a27e95b 100644 --- a/src/TaxonomyTrait.php +++ b/src/TaxonomyTrait.php @@ -9,6 +9,8 @@ /** * Trait TaxonomyTrait. * + * Taxonomy term-related steps. + * * @package DrevOps\BehatSteps */ trait TaxonomyTrait { @@ -87,6 +89,8 @@ public function taxonomyDeleteTerms($vocabulary, TableNode $termsTable) { } /** + * Visit specified vocabulary term page. + * * @When I visit :vocabulary vocabulary term :name */ public function taxonomyVisitTermPageWithName($vocabulary, $name) { @@ -107,6 +111,8 @@ public function taxonomyVisitTermPageWithName($vocabulary, $name) { } /** + * Visit specified vocabulary term edit page. + * * @When I edit :vocabulary vocabulary term :name */ public function taxonomyEditTermPageWithName($vocabulary, $name) { @@ -127,7 +133,7 @@ public function taxonomyEditTermPageWithName($vocabulary, $name) { } /** - * Helper to load multiple terms with specified vocabulary and conditions. + * Load multiple terms with specified vocabulary and conditions. * * @param string $vocabulary * The term vocabulary. diff --git a/src/UserTrait.php b/src/UserTrait.php index 202c9285..bc6b3075 100644 --- a/src/UserTrait.php +++ b/src/UserTrait.php @@ -8,11 +8,15 @@ /** * Trait UserTrait. * + * User-related steps. + * * @package DrevOps\BehatSteps\D7 */ trait UserTrait { /** + * Visit profile page of the specified user. + * * @When I visit user :name profile */ public function userVisitProfile($name) { @@ -27,6 +31,8 @@ public function userVisitProfile($name) { } /** + * Visit edit page of the specified user. + * * @When I go to my edit profile page */ public function userVisitOwnProfilePage() { @@ -39,6 +45,8 @@ public function userVisitOwnProfilePage() { } /** + * Remove users specified in the table. + * * @Given no users: */ public function userDelete(TableNode $usersTable) { @@ -64,6 +72,8 @@ public function userDelete(TableNode $usersTable) { } /** + * Assert that a user has roles assigned. + * * @Then user :name has :roles role(s) assigned */ public function userAssertHasRoles($name, $roles) { @@ -80,6 +90,8 @@ public function userAssertHasRoles($name, $roles) { } /** + * Assert that a user does not have roles assigned. + * * @Then user :name does not have :roles role(s) assigned */ public function userAssertHasNoRoles($name, $roles) { @@ -96,6 +108,8 @@ public function userAssertHasNoRoles($name, $roles) { } /** + * Assert that a user is active or not. + * * @Then user :name has :status status */ public function userAssertHasStatus($name, $status) { @@ -112,6 +126,8 @@ public function userAssertHasStatus($name, $status) { } /** + * Set a password for a user. + * * @Then I set user :user password to :password */ public function userSetPassword($name, $password) { @@ -172,7 +188,7 @@ protected function userGetByMail($mail) { } /** - * Helper to load multiple users with specified conditions. + * Load multiple users with specified conditions. * * @param array $conditions * Conditions keyed by field names. diff --git a/src/VisibilityTrait.php b/src/VisibilityTrait.php index d857a905..cd77f52e 100644 --- a/src/VisibilityTrait.php +++ b/src/VisibilityTrait.php @@ -5,6 +5,8 @@ /** * Trait VisibilityTrait. * + * Visibility-related steps. + * * @package DrevOps\BehatSteps */ trait VisibilityTrait { diff --git a/src/WaitTrait.php b/src/WaitTrait.php index f970c365..bcc11337 100644 --- a/src/WaitTrait.php +++ b/src/WaitTrait.php @@ -8,11 +8,15 @@ /** * Trait WaitTrait. * + * Wait for time or other actions on the page. + * * @package DrevOps\BehatSteps */ trait WaitTrait { /** + * Wait for a specified number of seconds. + * * @Then /^(?:|I )wait (\d+) second(s?)$/ */ public function waitSeconds($seconds) { diff --git a/src/WatchdogTrait.php b/src/WatchdogTrait.php index 68e66c6b..0f30c0df 100644 --- a/src/WatchdogTrait.php +++ b/src/WatchdogTrait.php @@ -9,6 +9,8 @@ /** * Trait WatchdogTrait. * + * Watchdog-related steps. + * * @package DrevOps\BehatSteps */ trait WatchdogTrait { diff --git a/tests/behat/bootstrap/BehatCliContext.php b/tests/behat/bootstrap/BehatCliContext.php index f6050b88..d1c13390 100644 --- a/tests/behat/bootstrap/BehatCliContext.php +++ b/tests/behat/bootstrap/BehatCliContext.php @@ -54,6 +54,14 @@ class BehatCliContext implements Context * @var string */ private $options = '--format-settings=\'{"timer": false}\' --no-interaction'; + /** + * @var array + */ + private $env = array(); + /** + * @var string + */ + private $answerString; /** * Cleans test folders in the temporary directory. @@ -87,8 +95,6 @@ public function prepareTestFolders() } $this->workingDir = $dir; $this->phpBin = $php; - $this->process = new Process(null); - $this->process->setTimeout(20); } /** @@ -180,13 +186,23 @@ public function fileShouldExist($path) /** * Sets specified ENV variable * + * @When /^the "([^"]*)" environment variable is set to "([^"]*)"$/ + */ + public function iSetEnvironmentVariable($name, $value) + { + $this->env = array($name => (string) $value); + } + + /** + * Sets the BEHAT_PARAMS env variable + * * @When /^"BEHAT_PARAMS" environment variable is set to:$/ * * @param PyStringNode $value */ - public function iSetEnvironmentVariable(PyStringNode $value) + public function iSetBehatParamsEnvironmentVariable(PyStringNode $value) { - $this->process->setEnv(array('BEHAT_PARAMS' => (string) $value)); + $this->env = array('BEHAT_PARAMS' => (string) $value); } /** @@ -200,17 +216,25 @@ public function iRunBehat($argumentsString = '') { $argumentsString = strtr($argumentsString, array('\'' => '"')); - $this->process->setWorkingDirectory($this->workingDir); - $this->process->setCommandLine( - sprintf( - '%s %s %s %s', - $this->phpBin, - escapeshellarg(BEHAT_BIN_PATH), - $argumentsString, - strtr($this->options, array('\'' => '"', '"' => '\"')) - ) + $cmd = sprintf( + '%s %s %s %s', + $this->phpBin, + escapeshellarg(BEHAT_BIN_PATH), + $argumentsString, + strtr($this->options, array('\'' => '"', '"' => '\"')) ); + $this->process = Process::fromShellCommandline($cmd); + + // Prepare the process parameters. + $this->process->setTimeout(20); + $this->process->setEnv($this->env); + $this->process->setWorkingDirectory($this->workingDir); + + if (!empty($this->answerString)) { + $this->process->setInput($this->answerString); + } + // Don't reset the LANG variable on HHVM, because it breaks HHVM itself if (!defined('HHVM_VERSION')) { $env = $this->process->getEnv(); @@ -231,11 +255,9 @@ public function iRunBehat($argumentsString = '') */ public function iRunBehatInteractively($answerString, $argumentsString) { - $env = $this->process->getEnv(); - $env['SHELL_INTERACTIVE'] = true; + $this->env['SHELL_INTERACTIVE'] = true; - $this->process->setEnv($env); - $this->process->setInput($answerString); + $this->answerString = $answerString; $this->options = '--format-settings=\'{"timer": false}\''; $this->iRunBehat($argumentsString); @@ -316,7 +338,10 @@ public function fileXmlShouldBeLike($path, PyStringNode $text) $fileContent = trim(file_get_contents($path)); - $fileContent = preg_replace('/time="(.*)"/', 'time="-IGNORE-VALUE-"', $fileContent); + $fileContent = preg_replace('/time="(.*)"/U', 'time="-IGNORE-VALUE-"', $fileContent); + + // The placeholder is necessary because of different separators on Unix and Windows environments + $text = str_replace('-DIRECTORY-SEPARATOR-', DIRECTORY_SEPARATOR, $text); $dom = new DOMDocument(); $dom->loadXML($text); @@ -364,6 +389,13 @@ private function getExpectedOutput(PyStringNode $expectedText) return str_replace('/', DIRECTORY_SEPARATOR, $matches[0]); }, $text ); + + // error stacktrace + $text = preg_replace_callback( + '/#\d+ [^:]+:/', function ($matches) { + return str_replace('/', DIRECTORY_SEPARATOR, $matches[0]); + }, $text + ); } return $text; @@ -418,14 +450,21 @@ private function getOutput() { $output = $this->process->getErrorOutput() . $this->process->getOutput(); - // Normalize the line endings in the output + // Normalize the line endings and directory separators in the output if ("\n" !== PHP_EOL) { $output = str_replace(PHP_EOL, "\n", $output); } + // Remove location of the project + $output = str_replace(realpath(dirname(dirname(__DIR__))).DIRECTORY_SEPARATOR, '', $output); + // Replace wrong warning message of HHVM $output = str_replace('Notice: Undefined index: ', 'Notice: Undefined offset: ', $output); + // replace error messages that changed in PHP8 + $output = str_replace('Warning: Undefined array key','Notice: Undefined offset:', $output); + $output = preg_replace('/Class "([^"]+)" not found/', 'Class \'$1\' not found', $output); + return trim(preg_replace("/ +$/m", '', $output)); } diff --git a/tests/behat/bootstrap/BehatCliTrait.php b/tests/behat/bootstrap/BehatCliTrait.php index a958a2b2..79efb323 100644 --- a/tests/behat/bootstrap/BehatCliTrait.php +++ b/tests/behat/bootstrap/BehatCliTrait.php @@ -1,5 +1,12 @@ log($level, 'test'); } diff --git a/tests/behat/bootstrap/FeatureContext.php b/tests/behat/bootstrap/FeatureContext.php index 535d186f..2fa1e519 100644 --- a/tests/behat/bootstrap/FeatureContext.php +++ b/tests/behat/bootstrap/FeatureContext.php @@ -2,18 +2,9 @@ /** * @file - * Feature context for testing Behat-steps traits for Drupal 8. - * - * This is a test for the test framework itself. Consumer project should not - * use any steps or functions from this file. - * - * However, consumer sites can use this file as an example of traits inclusion. - * The usage of these traits can be seen in *.feature files. + * Feature context for testing Behat-steps. */ -use Behat\Behat\Hook\Scope\AfterFeatureScope; -use Behat\Gherkin\Node\PyStringNode; -use Behat\Mink\Driver\Selenium2Driver; use DrevOps\BehatSteps\BigPipeTrait; use DrevOps\BehatSteps\ContentTrait; use DrevOps\BehatSteps\DraggableViewsTrait; @@ -41,11 +32,7 @@ use DrevOps\BehatSteps\WaitTrait; use DrevOps\BehatSteps\WatchdogTrait; use DrevOps\BehatSteps\WysiwygTrait; -use Drupal\Core\Database\Database; -use Drupal\Core\Extension\MissingDependencyException; use Drupal\DrupalExtension\Context\DrupalContext; -use Drupal\file\Entity\File; -use Drupal\user\Entity\User; /** * Defines application features from the specific context. @@ -80,187 +67,6 @@ class FeatureContext extends DrupalContext { use WaitTrait; use WysiwygTrait; - /** - * Clean watchdog after feature with an error. - * - * @AfterFeature @errorcleanup - */ - public static function cleanWatchdog(AfterFeatureScope $scope) { - $database = Database::getConnection(); - if ($database->schema()->tableExists('watchdog')) { - $database->truncate('watchdog')->execute(); - } - } - - /** - * @Then user :name does not exists - */ - public function userDoesNotExist($name) { - // We need to check that user was removed from both DB and test variables. - $users = $this->userLoadMultiple(['name' => $name]); - $user = reset($users); - - if ($user) { - throw new \Exception(sprintf('User "%s" exists in DB but should not', $name)); - } - - try { - $this->getUserManager()->getUser($name); - } - catch (\Exception $exception) { - return; - } - - throw new \Exception(sprintf('User "%s" does not exist in DB, but still exists in test variables', $name)); - } - - /** - * @Given set watchdog error level :level - */ - public function setWatchdogErrorDrupal8($level) { - \Drupal::logger('php')->log($level, 'test'); - } - - /** - * @Given cookie :name exists - */ - public function assertCookieExists($name) { - $cookies = $this->getCookies(); - - if (!isset($cookies[$name])) { - throw new \Exception(sprintf('Cookie "%s" does not exist.', $name)); - } - } - - /** - * Get a list of cookies. - */ - protected function getCookies() { - $cookie_list = []; - - /** @var Behat\Mink\Driver\BrowserKitDriver $driver */ - $driver = $this->getSession()->getDriver(); - if ($driver instanceof Selenium2Driver) { - $cookies = $driver->getWebDriverSession()->getAllCookies(); - foreach ($cookies as $cookie) { - $cookie_list[$cookie['name']] = $cookie['value']; - } - } - else { - $cookie_list = $driver->getClient()->getCookieJar()->allValues($driver->getCurrentUrl()); - } - - return $cookie_list; - } - - /** - * @Given cookie :name does not exist - */ - public function assertCookieNotExists($name) { - $cookies = $this->getCookies(); - - if (isset($cookies[$name])) { - throw new \Exception(sprintf('Cookie "%s" exists but should not.', $name)); - } - } - - /** - * @Given I install a :name module - */ - public function installModule($name) { - /** @var \Drupal\Core\Extension\ModuleHandler $module_handler */ - $module_handler = \Drupal::service('module_handler'); - if ($module_handler->moduleExists($name)) { - return; - } - - /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */ - $module_installer = \Drupal::service('module_installer'); - - try { - $result = $module_installer->install([$name]); - } - catch (MissingDependencyException $exception) { - throw new \Exception(sprintf('Unable to install a module "%s": %s.', $name, $exception->getMessage())); - } - - if (!$result) { - throw new \Exception(sprintf('Unable to install a module "%s".', $name)); - } - } - - /** - * @Given I uninstall a :name module - */ - public function uninstallModule($name) { - /** @var \Drupal\Core\Extension\ModuleHandler $module_handler */ - $module_handler = \Drupal::service('module_handler'); - if (!$module_handler->moduleExists($name)) { - throw new \RuntimeException(sprintf('Module "%s" does not exist.', $name)); - } - - /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */ - $module_installer = \Drupal::service('module_installer'); - - $result = $module_installer->uninstall([$name]); - - if (!$result) { - throw new \Exception(sprintf('Unable to uninstall a module "%s".', $name)); - } - } - - /** - * @When I send test email to :email with - * @When I send test email to :email with: - */ - public function sendTestEmail($email, PyStringNode $string) { - \Drupal::service('plugin.manager.mail')->mail( - 'mysite_core', - 'test_email', - $email, - \Drupal::languageManager()->getDefaultLanguage(), - ['body' => strval($string)], - FALSE - ); - } - - /** - * @Then :file_name file object exists - */ - public function fileObjectExist($file_name) { - $file_name = basename($file_name); - $fids = $this->fileLoadMultiple(['filename' => $file_name]); - if (empty($fids)) { - throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); - } - - $fid = reset($fids); - $file = File::load($fid); - - if ($file_name !== $file->label()) { - throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); - } - } - - /** - * Helper to load multiple files with specified conditions. - * - * @param array $conditions - * Conditions keyed by field names. - * - * @return array - * Array of file ids. - */ - protected function fileLoadMultiple(array $conditions = []) { - $query = \Drupal::entityQuery('file'); - $query->addMetaData('account', User::load(1)); - foreach ($conditions as $k => $v) { - $and = $query->andConditionGroup(); - $and->condition($k, $v); - $query->condition($and); - } - - return $query->execute(); - } + use FeatureContextTrait; } diff --git a/tests/behat/bootstrap/FeatureContextD7.php b/tests/behat/bootstrap/FeatureContextD7.php index d8966d6c..f30e7aae 100644 --- a/tests/behat/bootstrap/FeatureContextD7.php +++ b/tests/behat/bootstrap/FeatureContextD7.php @@ -2,17 +2,9 @@ /** * @file - * Feature context for testing Behat-steps traits for Drupal 7. - * - * This is a test for the test framework itself. Consumer project should not - * use any steps or functions from this file. - * - * However, consumer sites can use this file as an example of traits inclusion. - * The usage of these traits can be seen in *.feature files. + * Feature context for testing Behat-steps for Drupal 7. */ -use Behat\Behat\Hook\Scope\AfterFeatureScope; -use Behat\Gherkin\Node\PyStringNode; use DrevOps\BehatSteps\D7\ContentTrait; use DrevOps\BehatSteps\D7\EmailTrait; use DrevOps\BehatSteps\D7\FieldCollectionTrait; @@ -57,76 +49,6 @@ class FeatureContextD7 extends DrupalContext { use WaitTrait; use WatchdogTrait; - /** - * @Then user :name does not exists - */ - public function userDoesNotExist($name) { - // We need to check that user was removed from both DB and test variables. - $user = user_load($name); - - if ($user) { - throw new \Exception(sprintf('User "%s" exists in DB but should not', $name)); - } - - try { - $this->getUserManager()->getUser($name); - } - catch (\Exception $exception) { - return; - } - - throw new \Exception(sprintf('User "%s" does not exist in DB, but still exists in test variables', $name)); - } - - /** - * @When I send test email to :email with - * @When I send test email to :email with: - */ - public function sendTestEmail($email, PyStringNode $string) { - drupal_mail('mysite_core', 'test_email', $email, language_default(), ['body' => $string], FALSE); - } - - /** - * @Given I set test variable :name to value :value - */ - public function setTestVariable($name, $value) { - variable_set($name, (string) $value); - } - - /** - * @Given I delete test variable :name - */ - public function deleteTestVariable($name) { - variable_del($name); - } - - /** - * @Then :file_name file object exists - */ - public function fileObjectExist($file_name) { - $file_name = basename($file_name); - $file_name_in_db = file_load_multiple([], ['filename' => $file_name]); - if ($file_name !== current($file_name_in_db)->filename) { - throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); - } - } - - /** - * @Given set Drupal7 watchdog error level :level - */ - public function setWatchdogErrorDrupal7($level) { - watchdog('php', 'test', [], $level); - } - - /** - * Clean watchdog after feature with an error. - * - * @AfterFeature @errorcleanup - */ - public static function cleanWatchdog(AfterFeatureScope $scope) { - if (db_table_exists('watchdog')) { - db_truncate('watchdog')->execute(); - } - } + use FeatureContextD7Trait; } diff --git a/tests/behat/bootstrap/FeatureContextD7Trait.php b/tests/behat/bootstrap/FeatureContextD7Trait.php new file mode 100644 index 00000000..df045f29 --- /dev/null +++ b/tests/behat/bootstrap/FeatureContextD7Trait.php @@ -0,0 +1,97 @@ +getUserManager()->getUser($name); + } + catch (\Exception $exception) { + return; + } + + throw new \Exception(sprintf('User "%s" does not exist in DB, but still exists in test variables', $name)); + } + + /** + * Send email via Drupal. + * + * @When I send test email to :email with + * @When I send test email to :email with: + */ + public function sendTestEmail($email, PyStringNode $string) { + drupal_mail('mysite_core', 'test_email', $email, language_default(), ['body' => $string], FALSE); + } + + /** + * @Given I set test variable :name to value :value + */ + public function setTestVariable($name, $value) { + variable_set($name, (string) $value); + } + + /** + * @Given I delete test variable :name + */ + public function deleteTestVariable($name) { + variable_del($name); + } + + /** + * @Then :file_name file object exists + */ + public function fileObjectExist($file_name) { + $file_name = basename($file_name); + $file_name_in_db = file_load_multiple([], ['filename' => $file_name]); + if ($file_name !== current($file_name_in_db)->filename) { + throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); + } + } + + /** + * @Given set Drupal7 watchdog error level :level + */ + public function setWatchdogErrorDrupal7($level) { + watchdog('php', 'test', [], $level); + } + + /** + * Clean watchdog after feature with an error. + * + * @AfterFeature @errorcleanup + */ + public static function cleanWatchdog(AfterFeatureScope $scope) { + if (db_table_exists('watchdog')) { + db_truncate('watchdog')->execute(); + } + } + +} diff --git a/tests/behat/bootstrap/FeatureContextTrait.php b/tests/behat/bootstrap/FeatureContextTrait.php new file mode 100644 index 00000000..c00a196d --- /dev/null +++ b/tests/behat/bootstrap/FeatureContextTrait.php @@ -0,0 +1,187 @@ +schema()->tableExists('watchdog')) { + $database->truncate('watchdog')->execute(); + } + } + + /** + * @Then user :name does not exist + */ + public function userDoesNotExist($name) { + // We need to check that user was removed from both DB and test variables. + $users = $this->userLoadMultiple(['name' => $name]); + $user = reset($users); + + if ($user) { + throw new \Exception(sprintf('User "%s" exists in DB but should not', $name)); + } + + try { + $this->getUserManager()->getUser($name); + } + catch (\Exception $exception) { + return; + } + + throw new \Exception(sprintf('User "%s" does not exist in DB, but still exists in test variables', $name)); + } + + /** + * @Given set watchdog error level :level + */ + public function setWatchdogErrorDrupal9($level) { + \Drupal::logger('php')->log($level, 'test'); + } + + /** + * @Given cookie :name exists + */ + public function assertCookieExists($name) { + $cookies = $this->getCookies(); + + if (!isset($cookies[$name])) { + throw new \Exception(sprintf('Cookie "%s" does not exist.', $name)); + } + } + + /** + * Get a list of cookies. + */ + protected function getCookies() { + $cookie_list = []; + + /** @var Behat\Mink\Driver\BrowserKitDriver $driver */ + $driver = $this->getSession()->getDriver(); + if ($driver instanceof Selenium2Driver) { + $cookies = $driver->getWebDriverSession()->getAllCookies(); + foreach ($cookies as $cookie) { + $cookie_list[$cookie['name']] = $cookie['value']; + } + } + else { + $cookie_list = $driver->getClient()->getCookieJar()->allValues($driver->getCurrentUrl()); + } + + return $cookie_list; + } + + /** + * @Given cookie :name does not exist + */ + public function assertCookieNotExists($name) { + $cookies = $this->getCookies(); + + if (isset($cookies[$name])) { + throw new \Exception(sprintf('Cookie "%s" exists but should not.', $name)); + } + } + + /** + * @Given I install a :name module + */ + public function installModule($name) { + /** @var \Drupal\Core\Extension\ModuleHandler $module_handler */ + $module_handler = \Drupal::service('module_handler'); + if ($module_handler->moduleExists($name)) { + return; + } + + /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */ + $module_installer = \Drupal::service('module_installer'); + + try { + $result = $module_installer->install([$name]); + } + catch (MissingDependencyException $exception) { + throw new \Exception(sprintf('Unable to install a module "%s": %s.', $name, $exception->getMessage())); + } + + if (!$result) { + throw new \Exception(sprintf('Unable to install a module "%s".', $name)); + } + } + + /** + * @Given I uninstall a :name module + */ + public function uninstallModule($name) { + /** @var \Drupal\Core\Extension\ModuleHandler $module_handler */ + $module_handler = \Drupal::service('module_handler'); + if (!$module_handler->moduleExists($name)) { + throw new \RuntimeException(sprintf('Module "%s" does not exist.', $name)); + } + + /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */ + $module_installer = \Drupal::service('module_installer'); + + $result = $module_installer->uninstall([$name]); + + if (!$result) { + throw new \Exception(sprintf('Unable to uninstall a module "%s".', $name)); + } + } + + /** + * @When I send test email to :email with + * @When I send test email to :email with: + */ + public function sendTestEmail($email, PyStringNode $string) { + \Drupal::service('plugin.manager.mail')->mail( + 'mysite_core', + 'test_email', + $email, + \Drupal::languageManager()->getDefaultLanguage(), + ['body' => strval($string)], + FALSE + ); + } + + /** + * @Then :file_name file object exists + */ + public function fileObjectExist($file_name) { + $file_name = basename($file_name); + $fids = $this->fileLoadMultiple(['filename' => $file_name]); + if (empty($fids)) { + throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); + } + + $fid = reset($fids); + $file = File::load($fid); + + if ($file_name !== $file->label()) { + throw new \Exception(sprintf('"%s" file does not exist in DB, but it should', $file_name)); + } + } + +} diff --git a/tests/behat/features/behat.smoke.feature b/tests/behat/features/behat.smoke.feature index 568c7414..6f03e2af 100644 --- a/tests/behat/features/behat.smoke.feature +++ b/tests/behat/features/behat.smoke.feature @@ -1,13 +1,13 @@ @smoke Feature: Behat feature context smoke tests - Assertions for D7 and D8 feature context steps (in FeatureContextD7.php and + Assertions for D7 and feature context steps (in FeatureContextD7.php and FeatureContextD8.php) that are used to test the Behat-steps step definitions defined in `src`. Basically, tests for tests, which are testing our steps provided by this package. - @api @d8 @d9 + @api @d9 Scenario: Assert that a module can be installed and uninstalled Given I am logged in as a user with the "administer site configuration, administer modules" permissions When I go to "/admin/modules" @@ -24,7 +24,7 @@ Feature: Behat feature context smoke tests And the response status code should be 200 Then the "modules[book][enable]" checkbox should be unchecked - @api @d8 @d9 + @api @d9 Scenario: Assert that a cookie presence and absence assertions work Given I am logged in as a user with the "administer site configuration" permissions Then cookie "testcookiename" exists diff --git a/tests/behat/features/behatcli.feature b/tests/behat/features/behatcli.feature index 95ff762e..eee9fa7f 100644 --- a/tests/behat/features/behatcli.feature +++ b/tests/behat/features/behatcli.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @behatcli +@d7 @d9 @behatcli Feature: Behat CLI context Tests for BehatCliContext functionality that is used to test Behat Steps traits diff --git a/tests/behat/features/behatcli.steps.feature b/tests/behat/features/behatcli.steps.feature index 3062899d..2f693c6c 100644 --- a/tests/behat/features/behatcli.steps.feature +++ b/tests/behat/features/behatcli.steps.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @behatcli +@d7 @d9 @behatcli Feature: Behat CLI context additional steps @trait:PathTrait diff --git a/tests/behat/features/big_pipe.feature b/tests/behat/features/big_pipe.feature index ba754d94..530c0849 100644 --- a/tests/behat/features/big_pipe.feature +++ b/tests/behat/features/big_pipe.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that BigPipeTrait works for D8 or D9 +@d9 +Feature: Check that BigPipeTrait works for or D9 @api Scenario: Assert that Big Pipe cookie is set diff --git a/tests/behat/features/content.feature b/tests/behat/features/content.feature index ed7efe0d..d5305385 100644 --- a/tests/behat/features/content.feature +++ b/tests/behat/features/content.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that ContentTrait works for D8 or D9 +@d9 +Feature: Check that ContentTrait works for or D9 @api Scenario: Assert visiting page with title of specified content type diff --git a/tests/behat/features/d7.user.feature b/tests/behat/features/d7.user.feature index c1c438a3..1b3e9218 100644 --- a/tests/behat/features/d7.user.feature +++ b/tests/behat/features/d7.user.feature @@ -24,7 +24,7 @@ Feature: Check that UserTrait works for D7 | name | | authenticated_user | - Then user "authenticated_user" does not exists + Then user "authenticated_user" does not exist @api Scenario: Assert "Then user :name has :roles role(s) assigned" diff --git a/tests/behat/features/eck.feature b/tests/behat/features/eck.feature index 6278a87c..8772ea5e 100644 --- a/tests/behat/features/eck.feature +++ b/tests/behat/features/eck.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that EckTrait works for D8 or D9 +@d9 +Feature: Check that EckTrait works for or D9 Background: Given I am logged in as a user with the "administrator" role diff --git a/tests/behat/features/element.feature b/tests/behat/features/element.feature index 3d300acc..2c5f63b5 100644 --- a/tests/behat/features/element.feature +++ b/tests/behat/features/element.feature @@ -1,4 +1,4 @@ -@d8 +@d9 Feature: Check that ElementTrait works @api diff --git a/tests/behat/features/email.feature b/tests/behat/features/email.feature index 346737e2..73add938 100644 --- a/tests/behat/features/email.feature +++ b/tests/behat/features/email.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that email assertions work for D8 or D9 +@d9 +Feature: Check that email assertions work for or D9 @api Scenario: As a developer, I want to know that email step definitions work as diff --git a/tests/behat/features/field.feature b/tests/behat/features/field.feature index ea061d5f..e826f163 100644 --- a/tests/behat/features/field.feature +++ b/tests/behat/features/field.feature @@ -1,6 +1,6 @@ @d7 Feature: Check that FieldTrait works - # @todo: Implement controller with a form for D8 or D9 and add this test. + # @todo: Implement controller with a form for or D9 and add this test. Scenario: Assert field exists Given I go to "test-form" diff --git a/tests/behat/features/file-download.feature b/tests/behat/features/file-download.feature index 065248fe..1dec4fc0 100644 --- a/tests/behat/features/file-download.feature +++ b/tests/behat/features/file-download.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that FileDownloadTrait works for D8 or D9 +@d9 +Feature: Check that FileDownloadTrait works for or D9 Background: Given I am logged in as a user with the "administrator" role diff --git a/tests/behat/features/file.feature b/tests/behat/features/file.feature index e1d92dce..d51ed392 100644 --- a/tests/behat/features/file.feature +++ b/tests/behat/features/file.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that FileTrait works for D8 or D9 +@d9 +Feature: Check that FileTrait works for or D9 @api Scenario: Assert "Given managed file:" @@ -37,7 +37,7 @@ Feature: Check that FileTrait works for D8 or D9 When I run "behat --no-colors" Then it should fail with an error: """ - The file public://test4.txt does not exists. + The file public://test4.txt does not exist. """ @trait:FileTrait diff --git a/tests/behat/features/homepage.feature b/tests/behat/features/homepage.feature index bcda59ad..faeaa44d 100644 --- a/tests/behat/features/homepage.feature +++ b/tests/behat/features/homepage.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @smoke @homepage +@d7 @d9 @smoke @homepage Feature: Homepage Ensure that homepage is displayed as expected. diff --git a/tests/behat/features/keyboard.feature b/tests/behat/features/keyboard.feature index 05c3d204..e7b37dd4 100644 --- a/tests/behat/features/keyboard.feature +++ b/tests/behat/features/keyboard.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @keyboard +@d7 @d9 @keyboard Feature: Check that KeyboardTrait works @api @javascript diff --git a/tests/behat/features/link.feature b/tests/behat/features/link.feature index 2ceb2835..7aa3bdf4 100644 --- a/tests/behat/features/link.feature +++ b/tests/behat/features/link.feature @@ -1,19 +1,21 @@ Feature: Check that LinkTrait works - @d7 @d8 + @d7 @d9 Scenario: Assert link with href without locator Given I go to "/" Then I should see the link "Drupal" with "https://www.drupal.org" - @d7 @d8 + + @d7 @d9 Scenario: Assert link with href with locator Given I go to "/" Then I should see the link "Drupal" with "https://www.drupal.org" in "#block-system-powered-by,#block-bartik-powered" - @d7 @d8 + + @d7 @d9 Scenario: Assert link with wildcard in href without locator Given I go to "/" Then I should see the link "Drupal" with "https://www.drupal*" - @api @d8 + @api @d9 Scenario: Assert link with title Given I am logged in as a user with the "administrator" role When I go to "/" @@ -21,7 +23,7 @@ Feature: Check that LinkTrait works And the link with title "Some non-existing title" does not exist And I click the link with title "Return to site content" - @trait:LinkTrait @d8 + @trait:LinkTrait @d9 Scenario: Assert that negative assertions fail with an error Given some behat configuration And scenario steps: @@ -36,7 +38,7 @@ Feature: Check that LinkTrait works The link with title "Some non-existing title" does not exist. """ - @trait:LinkTrait @d8 + @trait:LinkTrait @d9 Scenario: Assert that negative assertions fail with an error Given some behat configuration And scenario steps: diff --git a/tests/behat/features/login.feature b/tests/behat/features/login.feature index 7476eae0..1572c643 100644 --- a/tests/behat/features/login.feature +++ b/tests/behat/features/login.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @smoke @login +@d7 @d9 @smoke @login Feature: Login Ensure that user can login. diff --git a/tests/behat/features/media.feature b/tests/behat/features/media.feature index 7668d48c..5dab2188 100644 --- a/tests/behat/features/media.feature +++ b/tests/behat/features/media.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that MediaTrait works for D8 or D9 +@d9 +Feature: Check that MediaTrait works for or D9 @api Scenario: Assert "When I attach the file :file to :field_name media field" diff --git a/tests/behat/features/menu.feature b/tests/behat/features/menu.feature index d8790b9a..8b753898 100644 --- a/tests/behat/features/menu.feature +++ b/tests/behat/features/menu.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that MenuTrait works for D8 or D9 +@d9 +Feature: Check that MenuTrait works for or D9 @api Scenario: Assert "Given menus:" diff --git a/tests/behat/features/override.feature b/tests/behat/features/override.feature index a34d2899..7c6f605a 100644 --- a/tests/behat/features/override.feature +++ b/tests/behat/features/override.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that OverrideTrait works for D8 or D9 +@d9 +Feature: Check that OverrideTrait works for or D9 @api Scenario Outline: Assert override of authentication by role works diff --git a/tests/behat/features/paragraphs.feature b/tests/behat/features/paragraphs.feature index bc611583..2e33e7eb 100644 --- a/tests/behat/features/paragraphs.feature +++ b/tests/behat/features/paragraphs.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that ParagraphsTrait works for D8 or D9 +@d9 +Feature: Check that ParagraphsTrait works for or D9 Background: Given I am logged in as a user with the "administrator" role diff --git a/tests/behat/features/path.feature b/tests/behat/features/path.feature index dd41d461..4e5eba89 100644 --- a/tests/behat/features/path.feature +++ b/tests/behat/features/path.feature @@ -1,4 +1,4 @@ -@d7 @d8 +@d7 @d9 Feature: Check that PathTrait works Scenario: User is at the path without prefixed slash. diff --git a/tests/behat/features/response.feature b/tests/behat/features/response.feature index 0c0b6762..f87f22bf 100644 --- a/tests/behat/features/response.feature +++ b/tests/behat/features/response.feature @@ -1,4 +1,4 @@ -@d7 @d8 +@d7 @d9 Feature: Check that ResponseTrait works Scenario: Assert header response diff --git a/tests/behat/features/role.feature b/tests/behat/features/role.feature index 57071b33..abc51131 100644 --- a/tests/behat/features/role.feature +++ b/tests/behat/features/role.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that RoleTrait works for D8 or D9 +@d9 +Feature: Check that RoleTrait works for or D9 @api Scenario: Assert "Given role :name with permissions :permissions" diff --git a/tests/behat/features/search.feature b/tests/behat/features/search.feature index c6bdf532..cd697c3e 100644 --- a/tests/behat/features/search.feature +++ b/tests/behat/features/search.feature @@ -1,4 +1,4 @@ -@d8 @d9 @search +@d9 @search Feature: Ensure Search work. Background: diff --git a/tests/behat/features/taxonomy.feature b/tests/behat/features/taxonomy.feature index 2b80800a..0019703e 100644 --- a/tests/behat/features/taxonomy.feature +++ b/tests/behat/features/taxonomy.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that TaxonomyTrait works for D8 or D9 +@d9 +Feature: Check that TaxonomyTrait works for or D9 Background: Given no "tags" terms: diff --git a/tests/behat/features/testmode.feature b/tests/behat/features/testmode.feature index b1d64f1f..0c37cbed 100644 --- a/tests/behat/features/testmode.feature +++ b/tests/behat/features/testmode.feature @@ -1,4 +1,4 @@ -@d8 +@d9 Feature: Ensure TestmodeTrait works. Background: diff --git a/tests/behat/features/user.feature b/tests/behat/features/user.feature index dd8dfdd4..8a5b82c5 100644 --- a/tests/behat/features/user.feature +++ b/tests/behat/features/user.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that UserTrait works for D8 or D9 +@d9 +Feature: Check that UserTrait works for or D9 Background: Given users: @@ -24,7 +24,7 @@ Feature: Check that UserTrait works for D8 or D9 | name | | authenticated_user | - Then user "authenticated_user" does not exists + Then user "authenticated_user" does not exist @api Scenario: Assert "Given no users:" by email @@ -36,7 +36,7 @@ Feature: Check that UserTrait works for D8 or D9 | mail | | authenticated_user@myexample.com | - Then user "authenticated_user" does not exists + Then user "authenticated_user" does not exist @api Scenario: Assert "Then user :name has :roles role(s) assigned" diff --git a/tests/behat/features/visibility.feature b/tests/behat/features/visibility.feature index bd9ecfe5..3dc4944a 100644 --- a/tests/behat/features/visibility.feature +++ b/tests/behat/features/visibility.feature @@ -1,4 +1,4 @@ -@d7 @d8 @d9 @visibility +@d7 @d9 @visibility @skipped Feature: Check that VisibilityTrait works @api @javascript @@ -68,6 +68,7 @@ Feature: Check that VisibilityTrait works """ Element(s) defined by "#sr-only" selector is not visually visible on the page. """ + @trait:VisibilityTrait Scenario: Assert step definition "Then /^(?:|I )should not see a visually hidden "(?P[^"]*)" element" fails as expected Given some behat configuration diff --git a/tests/behat/features/wait.feature b/tests/behat/features/wait.feature index 9478a0c0..017e1cc2 100644 --- a/tests/behat/features/wait.feature +++ b/tests/behat/features/wait.feature @@ -1,4 +1,4 @@ -@d7 @d8 @api @javascript +@d7 @@api @javascript Feature: Check that WaitTrait works Scenario: Anonymous user visits homepage diff --git a/tests/behat/features/watchdog.feature b/tests/behat/features/watchdog.feature index b2e716ec..553de01c 100644 --- a/tests/behat/features/watchdog.feature +++ b/tests/behat/features/watchdog.feature @@ -1,5 +1,5 @@ -@d8 @d9 @errorcleanup -Feature: Check that WatchdogTrait works for D8 or D9 +@d9 @errorcleanup +Feature: Check that WatchdogTrait works for or D9 @trait:WatchdogTrait Scenario: Assert that watchdog fails with an error diff --git a/tests/behat/features/wysisywg.feature b/tests/behat/features/wysisywg.feature index bf31ccaf..c277dcdd 100644 --- a/tests/behat/features/wysisywg.feature +++ b/tests/behat/features/wysisywg.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that WysiwygTrait works for D8 or D9 +@d9 +Feature: Check that WysiwygTrait works for or D9 @api Scenario: Assert "When I fill in WYSIWYG :field with :value" diff --git a/tests/behat/features/wysiwyg.feature b/tests/behat/features/wysiwyg.feature index 006a8762..8401334d 100644 --- a/tests/behat/features/wysiwyg.feature +++ b/tests/behat/features/wysiwyg.feature @@ -1,5 +1,5 @@ -@d8 @d9 -Feature: Check that WysiywgTrait works for D8 or D9 +@d9 +Feature: Check that WysiywgTrait works for or D9 @api Scenario: Assert "When I fill in WYSIWYG "field" with "value"" works as expected