From 47491b701e6207b4e5845308aaa537810476b3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Costa=20Silva?= <1574795+joaocsilva@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:41:47 +0100 Subject: [PATCH] DQA-9679: Add Behat Lint (#790) --- .gitignore | 1 + composer.json | 1 + config/commands/lint.yml | 4 + config/runner/toolkit-test.yml | 3 + docs/guide/testing-project.rst | 19 +++++ resources/cspell/dictionary.txt | 1 + resources/gherkinlint.json | 73 +++++++++++++++++++ src/TaskRunner/Commands/LintCommands.php | 33 +++++++++ tests/fixtures/commands/lint.yml | 21 ++++++ .../fixtures/samples/sample-gherkinlint.json | 73 +++++++++++++++++++ 10 files changed, 229 insertions(+) create mode 100644 resources/gherkinlint.json create mode 100644 tests/fixtures/samples/sample-gherkinlint.json diff --git a/.gitignore b/.gitignore index 0bbc3b3b5..084c04e52 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ package.json package-lock.json /docs_tmp/ /.toolkit-mock +/gherkinlint.json # Documentation folder exclusions. !docs/ diff --git a/composer.json b/composer.json index 49804330c..316b655f1 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "consolidation/annotated-command": "^4.7.0", "consolidation/robo": "^3.0 || ^4.0 || ^5.0", "cweagans/composer-patches": "^1.7 || ^2.0", + "dantleech/gherkin-lint": "^0.2.3", "drush/drush": "^11.0.4 || ^12.0 || ^13.0", "ec-europa/qa-automation": "^9.3", "ec-europa/toolkit-composer-plugin": "^0.0.1", diff --git a/config/commands/lint.yml b/config/commands/lint.yml index 32a323515..9ea8b5a64 100644 --- a/config/commands/lint.yml +++ b/config/commands/lint.yml @@ -30,3 +30,7 @@ command: config: ${toolkit.lint.cspell.config} files: ${toolkit.lint.cspell.files} options: ${toolkit.lint.cspell.options} + lint-behat: + options: + config: ${toolkit.lint.behat.config} + files: ${toolkit.lint.behat.files} diff --git a/config/runner/toolkit-test.yml b/config/runner/toolkit-test.yml index 249b08f9a..29a65842e 100644 --- a/config/runner/toolkit-test.yml +++ b/config/runner/toolkit-test.yml @@ -109,6 +109,9 @@ toolkit: config: '.cspell.json' files: '${toolkit.build.custom-code-folder}/' options: '--dot --gitignore' + behat: + config: 'gherkinlint.json' + files: 'tests/features' axe-scan: config: axe-scan.config.json urls: diff --git a/docs/guide/testing-project.rst b/docs/guide/testing-project.rst index bcdb5c102..d796b57c7 100644 --- a/docs/guide/testing-project.rst +++ b/docs/guide/testing-project.rst @@ -368,6 +368,25 @@ These are the default configurations in the ``runner.yml`` file. files: 'lib/' options: '--dot --gitignore' +Behat lint testing +^^^^^^^^^^^^^^^^^^^ + +To run the Behat lint you can make use of the ``toolkit:lint-behat`` command: + +.. code-block:: + + docker-compose exec web ./vendor/bin/run toolkit:lint-behat + +These are the default configurations in the ``runner.yml`` file. + +.. code-block:: yaml + + toolkit: + lint: + behat: + config: 'gherkinlint.json' + files: 'tests/features' + Testing in CI ------------- diff --git a/resources/cspell/dictionary.txt b/resources/cspell/dictionary.txt index 3d5761ec0..7101107b8 100644 --- a/resources/cspell/dictionary.txt +++ b/resources/cspell/dictionary.txt @@ -28,6 +28,7 @@ ewppa EXITCODE expirable fpfis +gherkinlint grasmash grumphp gulpfile diff --git a/resources/gherkinlint.json b/resources/gherkinlint.json new file mode 100644 index 000000000..ea0d2d45a --- /dev/null +++ b/resources/gherkinlint.json @@ -0,0 +1,73 @@ +{ + "rules": { + "allowed-tags": { + "enabled": false + }, + "filename": { + "enabled": true, + "style": "snake_case" + }, + "indentation": { + "width": 2, + "feature": 0, + "rule": 1, + "background": 1, + "scenario": 1, + "step": 2, + "table": 3, + "literalBlock": 2, + "examples": 2, + "examplesTable": 3 + }, + "keyword-order": { + "enabled": false, + "tolerateThenBeforeWhen": true + }, + "no-background-with-single-scenario": { + "enabled": true + }, + "no-consecutive-empty-lines": { + "enabled": true + }, + "no-restricted-patterns": { + "enabled": false + }, + "no-duplicate-tags": { + "enabled": true + }, + "no-duplicated-feature-names": { + "enabled": true + }, + "no-duplicated-scenario-names": { + "enabled": true + }, + "no-empty-background": { + "enabled": true + }, + "no-empty-file": { + "enabled": true + }, + "no-empty-scenarios": { + "enabled": true + }, + "no-homogenous-tags": { + "enabled": true + }, + "no-trailing-spaces": { + "enabled": true + }, + "no-unnamed-features": { + "enabled": true + }, + "one-space-between-tags": { + "enabled": true + }, + "scenario-size": { + "enabled": false + }, + "scenarios-per-file": { + "enabled": true, + "min": 1 + } + } +} diff --git a/src/TaskRunner/Commands/LintCommands.php b/src/TaskRunner/Commands/LintCommands.php index 7abd1ee3b..15f45e280 100644 --- a/src/TaskRunner/Commands/LintCommands.php +++ b/src/TaskRunner/Commands/LintCommands.php @@ -338,4 +338,37 @@ public function toolkitLintCsPell(array $options = [ return $this->collectionBuilder()->addTaskList($tasks); } + /** + * Run lint Behat. + * + * @command toolkit:lint-behat + * + * @option config The path to the config file. + * @option files The files to check. + * + * @aliases tk-lbehat + * + * @usage --files='tests/features' --config='gherkinlint.json' + */ + public function toolkitLintBehat(array $options = [ + 'config' => InputOption::VALUE_REQUIRED, + 'files' => InputOption::VALUE_REQUIRED, + ]) + { + $tasks = []; + $bin = $this->getBinPath('gherkinlint'); + + // Ensure the config file exists. + if (!file_exists($options['config'])) { + $this->output->writeln('Could not find the config file, the default will be created in the project root.'); + $tasks[] = $this->taskFilesystemStack()->copy( + Toolkit::getToolkitRoot() . '/resources/gherkinlint.json', + $options['config'] + ); + } + + $tasks[] = $this->taskExec($bin . ' lint ' . $options['files']); + return $this->collectionBuilder()->addTaskList($tasks); + } + } diff --git a/tests/fixtures/commands/lint.yml b/tests/fixtures/commands/lint.yml index 1c7fde4b0..97205dcca 100644 --- a/tests/fixtures/commands/lint.yml +++ b/tests/fixtures/commands/lint.yml @@ -141,3 +141,24 @@ ->option('show-deprecated') ->rawArg('.') [Simulator] Running ./vendor/bin/parallel-lint --exclude dist/ --exclude .cache/ --exclude vendor/ --exclude web/ -e 'php,module,inc,theme,install' --show-deprecated . + +- command: 'toolkit:lint-behat' + configuration: [] + resources: [] + expectations: + - contains: | + Could not find the config file, the default will be created in the project root. + [Simulator] Simulating Filesystem\FilesystemStack() + ->copy('/test/toolkit/resources/gherkinlint.json', 'gherkinlint.json') + [Simulator] Simulating Exec('./vendor/bin/gherkinlint lint tests/features') + [Simulator] Running ./vendor/bin/gherkinlint lint tests/features + +- command: 'toolkit:lint-behat' + configuration: [] + resources: + - from: sample-gherkinlint.json + to: gherkinlint.json + expectations: + - contains: | + [Simulator] Simulating Exec('./vendor/bin/gherkinlint lint tests/features') + [Simulator] Running ./vendor/bin/gherkinlint lint tests/features diff --git a/tests/fixtures/samples/sample-gherkinlint.json b/tests/fixtures/samples/sample-gherkinlint.json new file mode 100644 index 000000000..ea0d2d45a --- /dev/null +++ b/tests/fixtures/samples/sample-gherkinlint.json @@ -0,0 +1,73 @@ +{ + "rules": { + "allowed-tags": { + "enabled": false + }, + "filename": { + "enabled": true, + "style": "snake_case" + }, + "indentation": { + "width": 2, + "feature": 0, + "rule": 1, + "background": 1, + "scenario": 1, + "step": 2, + "table": 3, + "literalBlock": 2, + "examples": 2, + "examplesTable": 3 + }, + "keyword-order": { + "enabled": false, + "tolerateThenBeforeWhen": true + }, + "no-background-with-single-scenario": { + "enabled": true + }, + "no-consecutive-empty-lines": { + "enabled": true + }, + "no-restricted-patterns": { + "enabled": false + }, + "no-duplicate-tags": { + "enabled": true + }, + "no-duplicated-feature-names": { + "enabled": true + }, + "no-duplicated-scenario-names": { + "enabled": true + }, + "no-empty-background": { + "enabled": true + }, + "no-empty-file": { + "enabled": true + }, + "no-empty-scenarios": { + "enabled": true + }, + "no-homogenous-tags": { + "enabled": true + }, + "no-trailing-spaces": { + "enabled": true + }, + "no-unnamed-features": { + "enabled": true + }, + "one-space-between-tags": { + "enabled": true + }, + "scenario-size": { + "enabled": false + }, + "scenarios-per-file": { + "enabled": true, + "min": 1 + } + } +}