diff --git a/.ahoy.yml b/.ahoy.yml index 0153cd31c..3c9891eac 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -179,7 +179,7 @@ commands: lint: usage: Lint back-end and front-end code. - cmd: ahoy lint-be && ahoy lint-fe + cmd: ahoy lint-be && ahoy lint-fe && lint-tests lint-be: usage: Lint back-end code. @@ -195,6 +195,11 @@ commands: ahoy cli vendor/bin/twig-cs-fixer lint ahoy cli "npm run --prefix \${DREVOPS_WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" + lint-tests: + usage: Lint tests code. + cmd: | + ahoy cli vendor/bin/gherkinlint lint tests/behat/features + lint-fix: usage: Fix lint issues of back-end and front-end code. cmd: ahoy lint-be-fix && ahoy lint-fe-fix diff --git a/.circleci/config.yml b/.circleci/config.yml index 19a568e8c..15d830ce4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -290,6 +290,10 @@ jobs: name: Lint code with Twig CS Fixer command: docker compose exec -T cli vendor/bin/twig-cs-fixer || [ "${DREVOPS_CI_TWIG_CS_FIXER_IGNORE_FAILURE:-0}" -eq 1 ] + - run: + name: Lint code with Gherkin Lint + command: docker compose exec -T cli vendor/bin/gherkinlint lint tests/behat/features || [ "${DREVOPS_CI_GHERKIN_LINT_IGNORE_FAILURE:-0}" -eq 1 ] + - run: name: Lint code with NPM linters command: docker compose exec -T cli bash -c "npm run --prefix \${DREVOPS_WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" || [ "${DREVOPS_CI_NPM_LINT_IGNORE_FAILURE:-0}" -eq 1 ] diff --git a/.dockerignore b/.dockerignore index 10d9596d9..c3559eb4d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -31,6 +31,7 @@ drush/contrib/ !.eslintrc.json !.sass-lint.yml !.twig-cs-fixer.php +!gherkinlint.json !Gruntfile.js !auth.json !behat.yml diff --git a/.scaffold/.ahoy.yml b/.scaffold/.ahoy.yml index 5ec25635f..41a5bca04 100644 --- a/.scaffold/.ahoy.yml +++ b/.scaffold/.ahoy.yml @@ -20,7 +20,7 @@ commands: cmd: | ahoy lint-scripts ahoy lint-dockerfiles - ahoy lint-docs + ahoy test-docs lint-scripts: cmd: ./tests/lint.scripts.sh diff --git a/.scaffold/docs/.utils/variables/extra/ci.variables.sh b/.scaffold/docs/.utils/variables/extra/ci.variables.sh index 50156b943..3d3f64dfc 100755 --- a/.scaffold/docs/.utils/variables/extra/ci.variables.sh +++ b/.scaffold/docs/.utils/variables/extra/ci.variables.sh @@ -33,6 +33,9 @@ DREVOPS_CI_TWIG_CS_FIXER_IGNORE_FAILURE=0 # Ignore NPM linters failures. DREVOPS_CI_NPM_LINT_IGNORE_FAILURE=0 +# Ignore Gherkin Lint failures. +DREVOPS_CI_GHERKIN_LINT_IGNORE_FAILURE=0 + # Ignore PHPUnit test failures. DREVOPS_CI_PHPUNIT_IGNORE_FAILURE=0 diff --git a/.scaffold/docs/content/tools/README.mdx b/.scaffold/docs/content/tools/README.mdx index c4b0a19fb..c66742571 100644 --- a/.scaffold/docs/content/tools/README.mdx +++ b/.scaffold/docs/content/tools/README.mdx @@ -22,6 +22,7 @@ Head over to the tool-specific documentation to learn more. | [Docker](docker.mdx) | A platform for containerizing and running applications | | [Doctor](doctor.mdx) | Check DrevOps Scaffold project requirements or print info | | [Drush](drush.mdx) | Command line shell and Unix scripting interface for Drupal | +| [Gherkin Lint](gherkin-lint.mdx) | Provides a Gherkin linter for PHP | | [Git artifact](git-artifact.mdx) | Package and push files to remote repositories | | [PHPCS](phpcs.mdx) | Check that code adheres to coding standards | | [PHPMD](phpmd.mdx) | Detect code smells and possible errors | diff --git a/.scaffold/docs/content/tools/gherkin-lint.mdx b/.scaffold/docs/content/tools/gherkin-lint.mdx new file mode 100644 index 000000000..bc63c8c94 --- /dev/null +++ b/.scaffold/docs/content/tools/gherkin-lint.mdx @@ -0,0 +1,63 @@ +# Gherkin Lint + +https://github.com/dantleech/gherkin-lint-php + +> Provides a Gherkin linter for PHP. + +DrevOps Scaffold comes with [Gherkin Lint configuration](https://github.com/drevops/scaffold/blob/develop/gherkinlint.json) for Behat tests. + +## Usage + +```shell +vendor/bin/gherkinlint lint tests/behat/features +``` +or +```shell +ahoy lint-tests +``` + +## Configuration + +See [configuration reference](https://github.com/dantleech/gherkin-lint-php?tab=readme-ov-file#configuration) and [rules](https://github.com/dantleech/gherkin-lint-php/blob/master/docs/rules.md). + +All global configuration takes place in the [`gherkinlint.json`](https://github.com/drevops/scaffold/blob/develop/gherkinlint.json) file. +The values are merged with the default configuration. + +To check enabled rules, run + +```shell +vendor/bin/gherkinlint rules +``` + +## Ignoring + +Ignoring rules **globally** takes place in the [`gherkinlint.json`](https://github.com/drevops/scaffold/blob/develop/gherkinlint.json) file. +```json +{ + "rules": { + "filename": { + "enabled": false + } + } +} +``` + +Gherkin Lint does not support ignoring of all rules in the file. + +To ignore **a specific rule** within a file, place in the file header: +```yaml +# @gherkinlint-disable-rule keyword-order, someother-rule +``` + +Gherkin Lint does not support ignoring of the **code blocks**. + +Gherkin Lint does not support ignoring rules on the **current line**. + +Gherkin Lint does not support ignoring rules on the **next line**. + +## Ignoring fail in CI + +This tool runs in CI by default and fails the build if there are any violations. + +Set `DREVOPS_CI_GHERKIN_LINT_IGNORE_FAILURE` environment variable to `1` to +ignore failures. The tool will still run and report violations, if any. diff --git a/.scaffold/docs/content/workflows/variables.mdx b/.scaffold/docs/content/workflows/variables.mdx index 482ac46f8..33ddfcd22 100644 --- a/.scaffold/docs/content/workflows/variables.mdx +++ b/.scaffold/docs/content/workflows/variables.mdx @@ -96,6 +96,14 @@ Default value: `UNDEFINED` Defined in: `CI config` +### `DREVOPS_CI_GHERKIN_LINT_IGNORE_FAILURE` + +Ignore Gherkin Lint failures. + +Default value: `UNDEFINED` + +Defined in: `CI config` + ### `DREVOPS_CI_HADOLINT_IGNORE_FAILURE` Ignore Hadolint failures. diff --git a/.scaffold/docs/cspell.json b/.scaffold/docs/cspell.json index c0b418e38..56b19621e 100644 --- a/.scaffold/docs/cspell.json +++ b/.scaffold/docs/cspell.json @@ -25,6 +25,7 @@ "dealerdirect", "drevops", "drush", + "gherkinlint", "hadolint", "initialise", "lagooncli", @@ -46,8 +47,8 @@ "phpstorm", "pyrech", "ruleset", - "shellvar", "sanitised", + "shellvar", "standardise", "utilising", "vlucas", diff --git a/.scaffold/tests/bats/_helper.bash b/.scaffold/tests/bats/_helper.bash index 586ae7816..563612433 100644 --- a/.scaffold/tests/bats/_helper.bash +++ b/.scaffold/tests/bats/_helper.bash @@ -396,12 +396,13 @@ assert_files_present_drevops() { assert_file_exists ".editorconfig" assert_file_exists ".env" assert_file_not_exists ".gitattributes" + assert_file_exists ".ahoy.local.example.yml" + assert_file_exists ".env.local.default" assert_file_exists ".gitignore" assert_file_exists "behat.yml" assert_file_exists "composer.json" - assert_file_exists ".ahoy.local.example.yml" - assert_file_exists ".env.local.default" assert_file_exists "docker-compose.yml" + assert_file_exists "gherkinlint.json" assert_file_exists "phpcs.xml" assert_file_exists "phpstan.neon" assert_file_exists "phpunit.xml" diff --git a/.scaffold/tests/bats/_helper.deployment.bash b/.scaffold/tests/bats/_helper.deployment.bash index 6fb4085b4..e640fcbd7 100644 --- a/.scaffold/tests/bats/_helper.deployment.bash +++ b/.scaffold/tests/bats/_helper.deployment.bash @@ -14,9 +14,9 @@ assert_deployment_files_present() { assert_dir_not_exists .docker assert_dir_not_exists .github assert_dir_not_exists .gitignore.artifact + assert_dir_not_exists .logs/screenshots assert_dir_not_exists node_modules assert_dir_not_exists patches - assert_dir_not_exists .logs/screenshots assert_dir_not_exists tests assert_file_not_exists .ahoy.yml assert_file_not_exists .dockerignore @@ -24,14 +24,15 @@ assert_deployment_files_present() { assert_file_not_exists .eslintrc.json assert_file_not_exists .lagoon.yml assert_file_not_exists .stylelintrc.json + assert_file_not_exists LICENSE + assert_file_not_exists README.md assert_file_not_exists behat.yml assert_file_not_exists composer.lock - assert_file_not_exists renovate.json assert_file_not_exists docker-compose.yml - assert_file_not_exists LICENSE + assert_file_not_exists gherkinlint.json assert_file_not_exists phpcs.xml assert_file_not_exists phpstan.neon - assert_file_not_exists README.md + assert_file_not_exists renovate.json assert_dir_exists scripts assert_dir_exists vendor diff --git a/.scaffold/tests/bats/_helper.workflow.bash b/.scaffold/tests/bats/_helper.workflow.bash index 8f04592ad..5414e46a2 100644 --- a/.scaffold/tests/bats/_helper.workflow.bash +++ b/.scaffold/tests/bats/_helper.workflow.bash @@ -346,6 +346,7 @@ assert_ahoy_lint() { assert_ahoy_lint_be "${webroot}" assert_ahoy_lint_fe "${webroot}" + assert_ahoy_lint_test } assert_ahoy_lint_be() { @@ -391,6 +392,23 @@ assert_ahoy_lint_fe() { assert_failure } +assert_ahoy_lint_test() { + step "Run Test linter checks" + + substep "Assert that Test lint works for Gherkin Lint" + run ahoy lint-test + assert_success + + substep "Assert that Test lint failure works for Gherkin Lint" + echo "Feature:" >> "tests/behat/features/test.feature" + sync_to_container + run ahoy lint-test + assert_failure + rm -f "tests/behat/features/test.feature" + ahoy cli rm -f "tests/behat/features/test.feature" + sync_to_container +} + assert_ahoy_test() { local webroot="${1:-web}" local is_fast="${2:-0}" diff --git a/composer.json b/composer.json index b1a4298ab..d069351ae 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,7 @@ }, "require-dev": { "behat/behat": "^3.14", + "dantleech/gherkin-lint": "^0.2.3", "dealerdirect/phpcodesniffer-composer-installer": "^0.7", "drevops/behat-format-progress-fail": "^1.2", "drevops/behat-screenshot": "^1.5", diff --git a/gherkinlint.json b/gherkinlint.json new file mode 100644 index 000000000..49de8655e --- /dev/null +++ b/gherkinlint.json @@ -0,0 +1,16 @@ +{ + "rules": { + "indentation": { + "width": 2 + }, + "keyword-order": { + "enabled": false + }, + "no-homogenous-tags": { + "enabled": false + }, + "scenario-size": { + "enabled": false + } + } +} diff --git a/tests/behat/features/homepage.feature b/tests/behat/features/homepage.feature index a3dba7931..fbd0b9613 100644 --- a/tests/behat/features/homepage.feature +++ b/tests/behat/features/homepage.feature @@ -10,7 +10,7 @@ Feature: Homepage Then I save screenshot @api @javascript - Scenario: Anonymous user visits homepage + Scenario: Anonymous user visits homepage using a real browser Given I go to the homepage And I should be in the "" path Then I save screenshot diff --git a/tests/behat/features/login.feature b/tests/behat/features/login.feature index d006637a6..b5acfa579 100644 --- a/tests/behat/features/login.feature +++ b/tests/behat/features/login.feature @@ -10,7 +10,7 @@ Feature: Login Then I save screenshot @api @javascript - Scenario: Administrator user logs in + Scenario: Administrator user logs in using a real browser Given I am logged in as a user with the "administer site configuration, access administration pages" permissions When I go to "admin" Then I save screenshot