From 36d31f3727a1924ecdd3b8bb9347efd40fa7f1eb Mon Sep 17 00:00:00 2001
From: Stanley SERVICAL <32981008+stanlee974@users.noreply.github.com>
Date: Sat, 5 Aug 2023 01:33:16 +0200
Subject: [PATCH] feat: add mechanism for reusable scenarios, #198
---
.gitignore | 4 +
.../docs/03-wordings/03-reusable-scenarios.md | 71 ++++++++++
.../03-wordings/03-reusable-scenarios.md | 71 ++++++++++
packages/runner-commons/src/index.ts | 2 +-
.../runner/formatter/uuv-custom-formatter.ts | 113 ---------------
.../src/step-definition-generator/common.ts | 27 +++-
.../generate-playbook-step-definitions.ts | 129 ++++++++++++++++++
.../generate-step-definitions.ts | 3 +
.../.cypress-cucumber-preprocessorrc.json | 3 +-
packages/runner-cypress/cypress.config.ts | 3 +-
.../e2e/playbook/example1.playbooked.feature | 5 +
.../e2e/playbook/example2.playbooked.feature | 9 ++
.../template/template.playbook.feature | 9 ++
.../template/template2.playbook.feature | 5 +
.../generate-playbook-step-definitions.ts | 19 +++
packages/runner-cypress/package.json | 1 +
.../cypress/_playbook-engine.ts | 17 +++
.../cypress/base-check-engine.ts | 2 +-
packages/runner-cypress/src/lib/uuv-cli.ts | 28 ++--
.../.cypress-cucumber-preprocessorrc.json | 3 +-
.../target-config/cypress.config.ts | 3 +-
packages/runner-playwright/cucumber.cjs | 3 +-
.../e2e/playbook/example1.playbooked.feature | 6 +
.../e2e/playbook/example2.playbooked.feature | 10 ++
.../template/template.playbook.feature | 10 ++
.../template/template2.playbook.feature | 6 +
.../generate-playbook-step-definitions.ts | 19 +++
packages/runner-playwright/package.json | 1 +
.../playwright/_playbook-engine.ts | 16 +++
.../playwright/base-check-engine.ts | 2 +-
packages/runner-playwright/src/lib/uuv-cli.ts | 9 ++
.../target-config/cucumber.cjs | 3 +-
32 files changed, 480 insertions(+), 132 deletions(-)
create mode 100644 packages/docs/docs/03-wordings/03-reusable-scenarios.md
create mode 100644 packages/docs/i18n/fr/docusaurus-plugin-content-docs/current/03-wordings/03-reusable-scenarios.md
delete mode 100644 packages/runner-commons/src/runner/formatter/uuv-custom-formatter.ts
create mode 100644 packages/runner-commons/src/step-definition-generator/generate-playbook-step-definitions.ts
create mode 100644 packages/runner-cypress/e2e/playbook/example1.playbooked.feature
create mode 100644 packages/runner-cypress/e2e/playbook/example2.playbooked.feature
create mode 100644 packages/runner-cypress/e2e/playbook/template/template.playbook.feature
create mode 100644 packages/runner-cypress/e2e/playbook/template/template2.playbook.feature
create mode 100644 packages/runner-cypress/generate-playbook-step-definitions.ts
create mode 100644 packages/runner-cypress/src/cucumber/step_definitions/cypress/_playbook-engine.ts
create mode 100644 packages/runner-playwright/e2e/playbook/example1.playbooked.feature
create mode 100644 packages/runner-playwright/e2e/playbook/example2.playbooked.feature
create mode 100644 packages/runner-playwright/e2e/playbook/template/template.playbook.feature
create mode 100644 packages/runner-playwright/e2e/playbook/template/template2.playbook.feature
create mode 100644 packages/runner-playwright/generate-playbook-step-definitions.ts
create mode 100644 packages/runner-playwright/src/cucumber/step_definitions/playwright/_playbook-engine.ts
diff --git a/.gitignore b/.gitignore
index 8b6ad09c2..68ec75ad6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,12 +43,16 @@ testem.log
Thumbs.db
*.iml
packages/runner-cypress/cypress/screenshots/
+packages/runner-cypress/generated
+packages/runner-cypress/e2e/generated
packages/docs/docs/03-wordings/01-generated-wording-description/
packages/runner-playwright/src/cucumber/step_definitions/playwright/generated/
packages/runner-playwright/reports/
packages/runner-playwright/tests/.features-gen
+packages/runner-playwright/generated
+packages/runner-playwright/e2e/generated
packages/docs/i18n/fr/docusaurus-plugin-content-docs/current/03-wordings/01-generated-wording-description/
packages/docs/static/assistant/uuv-assistant-resources.bundle.js
packages/docs/static/assistant/index.html
diff --git a/packages/docs/docs/03-wordings/03-reusable-scenarios.md b/packages/docs/docs/03-wordings/03-reusable-scenarios.md
new file mode 100644
index 000000000..d05dbce9f
--- /dev/null
+++ b/packages/docs/docs/03-wordings/03-reusable-scenarios.md
@@ -0,0 +1,71 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Reusable scenarios
+
+:::caution
+**Only available for developers**
+
+Reusable scenarios cannot be used in conjunction with each other
+:::
+
+## Create file with extension .playbook.feature
+File with this extension contains reusable scenarios.
+
+```gherkin title='uuv/e2e/playbook/template.playbook.feature'
+@Ignore //Only used with playwright
+Feature: Template
+
+ Scenario: I go to town list
+ When I visit path "https://e2e-test-quest.github.io/weather-app/"
+ And Within a button named "Get started"
+ And I click
+
+ Scenario: I select douala
+ When I visit path "https://e2e-test-quest.github.io/weather-app/"
+ And Within a button named "Get started"
+ And I click
+ And I reset context
+ And Within a list named "Available Towns"
+ And Within a list item named "Douala"
+ And I click
+ And I reset context
+```
+
+## Create a file with extension .playbooked.feature
+Files with this extension contains scenarios using reusable scenarios.
+
+```gherkin title='uuv/e2e/playbook/weatherApp.playbooked.feature'
+@Ignore //Only used with playwright
+Feature: Feature using reusable scenarios
+
+ Scenario: vital check on first page
+ Given I go to town list
+ Then I should see a title named "Nothing to display"
+
+ Scenario: vital check on second page
+ Given I select douala
+ Then Within the element with aria-label "Weather of Douala"
+ And I should see a title named "Douala"
+ And I should see an element with content "min: 10.8 °c"
+```
+
+## Launch script to generate executable feature
+this script replace playbook scenarios name by playbook scenarios steps.
+
+
+
+
+```shell
+npx uuv playbook
+```
+
+
+
+
+```shell
+yarn uuv playbook
+```
+
+
+
diff --git a/packages/docs/i18n/fr/docusaurus-plugin-content-docs/current/03-wordings/03-reusable-scenarios.md b/packages/docs/i18n/fr/docusaurus-plugin-content-docs/current/03-wordings/03-reusable-scenarios.md
new file mode 100644
index 000000000..728d31c2d
--- /dev/null
+++ b/packages/docs/i18n/fr/docusaurus-plugin-content-docs/current/03-wordings/03-reusable-scenarios.md
@@ -0,0 +1,71 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Scénarios réutilisables
+
+:::caution
+**Disponible seulement pour les développeurs**
+
+Les scénarios réutilisables ne peuvent être utilisés entre eux.
+:::
+
+## Créer un fichier avec l'extension .playbook.feature
+Les fichiers avec cette extension contiennent des scénarios réutilisables
+
+```gherkin title='uuv/e2e/playbook/template.playbook.feature'
+@Ignore //Seulement utile avec playwright
+ #language: fr
+Fonctionnalité: Template
+
+ Scénario: j'aille à la liste des villes
+ Lorsque je visite l'Url "https://e2e-test-quest.github.io/weather-app/"
+ Et je vais à l'intérieur de bouton nommé "Get started"
+ Et je clique
+
+ Scénario: je sélectionne douala
+ Lorsque je visite l'Url "https://e2e-test-quest.github.io/weather-app/"
+ Et je vais à l'intérieur de bouton nommé "Get started"
+ Et je clique
+ Et je reinitialise le contexte
+ Et je vais à l'intérieur de liste nommée "Available Towns"
+ Et je vais à l'intérieur de élément de liste nommé "Douala"
+ Et je clique
+ Et je reinitialise le contexte
+```
+
+## Créer un fichier avec l'extension .playbooked.feature
+Les fichiers avec cet extension contiennent des scénarios utilisant les scénarios réutilisables
+
+```gherkin title='uuv/e2e/playbook/weatherApp.playbooked.feature'
+@Ignore //Seulement utile avec playwright
+ #language: fr
+ Fonctionnalité: Fonctionnalité utilisant les scénarios réutilisables
+ Scénario: vérification vital de la première page
+ Etant donné que j'aille à la liste des villes
+ Alors je dois voir un titre nommé "Nothing to display"
+ Scénario: vérification vital de la seconde page
+ Etant donné que je sélectionne douala
+ Lorsque je vais à l'intérieur de l'élément ayant pour aria-label "Weather of Douala"
+ Alors je dois voir un titre nommé "Douala"
+ Et je dois voir un élément qui contient "min: 10.8 °c"
+```
+
+## Lancement du script de génération de feature éxecutable
+Ce script remplace les noms de scénarios des playbooks par les étapes de scénarios des playbooks.
+
+
+
+
+```shell
+npx uuv playbook
+```
+
+
+
+
+```shell
+yarn uuv playbook
+```
+
+
+
diff --git a/packages/runner-commons/src/index.ts b/packages/runner-commons/src/index.ts
index afc62b887..c2793576a 100644
--- a/packages/runner-commons/src/index.ts
+++ b/packages/runner-commons/src/index.ts
@@ -1,8 +1,8 @@
export * from "./step-definition-generator/common";
export * from "./step-definition-generator/generate-step-definitions";
export * from "./step-definition-generator/generate-step-definitions-documentation";
+export * from "./step-definition-generator/generate-playbook-step-definitions";
export * from "./runner/step-definitions/_constant";
export * from "./runner/step-definitions/_i-context";
-export * from "./runner/formatter/uuv-custom-formatter";
import key from "./assets/i18n/template.json";
export { key };
diff --git a/packages/runner-commons/src/runner/formatter/uuv-custom-formatter.ts b/packages/runner-commons/src/runner/formatter/uuv-custom-formatter.ts
deleted file mode 100644
index f1bd76476..000000000
--- a/packages/runner-commons/src/runner/formatter/uuv-custom-formatter.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { Formatter } from "cucumber-json-report-formatter";
-
-// FIXME remove this class when the PR https://github.com/vrymar/cucumber-json-report-formatter/pull/20 will be merged
-export class UuvCustomFormatter extends Formatter {
- constructor() {
- super();
- }
- override async parseCucumberJson(sourceFile, outputFile) {
- console.info(`Start formatting file '${sourceFile}' into '${outputFile}'`);
- const report = await this.helper.readFileIntoJson(sourceFile);
- const gherkinDocumentJson = this.helper.getJsonFromArray(report, "gherkinDocument");
- const cucumberReport = [];
- gherkinDocumentJson.forEach(gherkinJson => {
- let gherkinDocument;
- try {
- gherkinDocument = JSON.parse(gherkinJson).gherkinDocument;
- } catch (err) {
- console.error("Error parsing JSON string.", err);
- }
- const feature = gherkinDocument.feature;
- const featureChildren = feature.children;
- const scenariosJson = [];
- const background = {};
- featureChildren.forEach(featureChild => {
- if (featureChild.rule) {
- featureChild.rule.steps = [];
- featureChild.rule.children.forEach(ruleChildren => {
- this.buildAndAddScenario(ruleChildren, report, background, feature, scenariosJson, featureChild.rule);
- });
- } else {
- this.buildAndAddScenario(featureChild, report, background, feature, scenariosJson, undefined);
- }
- });
- const rootJson = {
- comments: this.getComments(gherkinDocument.comments),
- description: gherkinDocument.feature.description,
- elements: scenariosJson,
- id: feature.name,
- keyword: feature.keyword,
- line: feature.location.line,
- name: feature.name,
- uri: gherkinDocument.uri,
- tags: this.getTags(gherkinDocument.feature.tags)
- };
- // @ts-ignore
- cucumberReport.push(rootJson);
- });
- await this.validateReportSchema(report);
- const reportString = JSON.stringify(cucumberReport);
- console.info(`Finished formatting file '${sourceFile}'`);
- this.helper.writeFile(outputFile, reportString);
- }
-
- private buildAndAddScenario(child, report: string[], background: {}, feature, scenariosJson: any[], rule) {
- let steps = [];
- let stepJson = {};
- // Background
- if (child.scenario === undefined) {
- child.background.steps.forEach(step => {
- stepJson = this.createStepJson(step, report, 0);
- // @ts-ignore
- steps.push(stepJson);
- });
- background = this.createScenarioJson(feature, child.background, steps, "background");
- // eslint-disable-next-line brace-style
- }
- // Normal Scenario
- else if (!child.scenario.keyword.includes("Outline")) {
- child.scenario.steps.forEach(step => {
- stepJson = this.createStepJson(step, report, 0);
- // @ts-ignore
- steps.push(stepJson);
- });
- const scenario = this.createScenarioJson(feature, child.scenario, steps, "scenario");
- if (rule) {
- scenario.id = `${feature.name};${rule.name};${scenario.name}`;
- }
- if (Object.keys(background).length !== 0 && background !== undefined) {
- // @ts-ignore
- scenariosJson.push(background);
- }
- // @ts-ignore
- scenariosJson.push(scenario);
- }
- // Scenario Outline
- else if (child.scenario.examples[0].tableBody !== undefined) {
- const numberOfExecutions = child.scenario.examples[0].tableBody.length;
- const numberOfStepsEachExecution = child.scenario.steps.length;
- let scenarioIndex = 0;
- while (scenarioIndex < numberOfExecutions) {
- let currentStep = 0;
- steps = [];
- while (currentStep < numberOfStepsEachExecution) {
- stepJson = this.createStepJson(child.scenario.steps[currentStep], report, scenarioIndex);
- currentStep++;
- // @ts-ignore
- steps.push(stepJson);
- }
- const scenario = this.createScenarioJson(feature, child.scenario, steps, "scenario", scenarioIndex);
- if (rule) {
- scenario.id = `${feature.name};${rule.name};${scenario.name}`;
- }
- if (Object.keys(background).length !== 0 && background !== undefined) {
- // @ts-ignore
- scenariosJson.push(background);
- }
- // @ts-ignore
- scenariosJson.push(scenario);
- scenarioIndex++;
- }
- }
- }
-}
diff --git a/packages/runner-commons/src/step-definition-generator/common.ts b/packages/runner-commons/src/step-definition-generator/common.ts
index 4bcfa5b95..c2afa7eaf 100644
--- a/packages/runner-commons/src/step-definition-generator/common.ts
+++ b/packages/runner-commons/src/step-definition-generator/common.ts
@@ -14,6 +14,7 @@
*/
import fs from "fs";
+import glob from "glob";
export { fs };
@@ -43,7 +44,14 @@ export enum TEST_RUNNER_ENUM {
export enum STEP_DEFINITION_FILE_NAME {
BASE = "base-check-engine",
- BY_ROLE = "based-role-check-engine"
+ BY_ROLE = "based-role-check-engine",
+ BY_SCENARIO_TEMPLATE = "_playbook-engine",
+}
+
+export enum UUV_ENVELOPE {
+ PLAYBOOK = "playbook.feature",
+ PLAYBOOKED = "playbooked.feature",
+ PLAYBOOKED_GEN = "playbooked.generated.feature",
}
export enum KEY_PRESS {
@@ -98,4 +106,21 @@ export class Common {
`[WRITE] ${generatedFile} written successfully`
);
}
+
+ static getFileList(dirName) {
+ let files : string[] = [];
+ const items = fs.readdirSync(dirName, { withFileTypes: true });
+ for (const item of items) {
+ if (item.isDirectory()) {
+ files = [
+ ...files,
+ ...(Common.getFileList(`${dirName}/${item.name}`)),
+ ];
+ } else {
+ files.push(`${dirName}/${item.name}`);
+ }
+ }
+
+ return files;
+ }
}
diff --git a/packages/runner-commons/src/step-definition-generator/generate-playbook-step-definitions.ts b/packages/runner-commons/src/step-definition-generator/generate-playbook-step-definitions.ts
new file mode 100644
index 000000000..922ab855d
--- /dev/null
+++ b/packages/runner-commons/src/step-definition-generator/generate-playbook-step-definitions.ts
@@ -0,0 +1,129 @@
+/**
+ * Software Name : UUV
+ *
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2023 Orange
+ * SPDX-License-Identifier: MIT
+ *
+ * This software is distributed under the MIT License,
+ * the text of which is available at https://spdx.org/licenses/MIT.html
+ * or see the "LICENSE" file for more details.
+ *
+ * Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
+ * Software description: Make test writing fast, understandable by any human
+ * understanding English or French.
+ */
+
+import { Common, fs, GenerateFileProcessing, STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM, UUV_ENVELOPE } from "./common";
+import chalk from "chalk";
+
+export class PlaybookStepDefinition extends GenerateFileProcessing {
+ override generatedDir = "";
+ UUV_FOLDER = `${this.baseDir}/e2e`;
+ SCENARIO_REGEXP = RegExp("(Scenario: |Scénario: |Scenario : |Scénario : |Scenario:|Scénario:|Scenario :|Scénario :)(.+)");
+
+ constructor(baseDir: string, runner: TEST_RUNNER_ENUM, stepDefinitionFileName: STEP_DEFINITION_FILE_NAME) {
+ super(baseDir, runner, stepDefinitionFileName);
+ }
+
+ runGenerate() {
+ this.generatedDir = `${this.UUV_FOLDER}/generated`;
+ const generatedStepDefinitionDir = `${this.UUV_FOLDER}/../generated/`;
+ const generatedFile = `${generatedStepDefinitionDir}_playbook-step-definitions.ts`;
+
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ Common.cleanFolderIfExists(this.generatedDir);
+ Common.buildDirIfNotExists(this.generatedDir);
+ Common.cleanFolderIfExists(generatedStepDefinitionDir);
+ Common.buildDirIfNotExists(generatedStepDefinitionDir);
+ this.generateWordingFiles(generatedFile);
+ }
+
+ computeWordingFile(data: string, wordingFile: string): string {
+ data =
+ "/*******************************\n" +
+ "NE PAS MODIFIER, FICHIER GENERE\n" +
+ "*******************************/\n\n" +
+ data;
+ const foundPlaybookedFile = this.initializeGeneratedPlaybookedFile();
+ Common.getFileList(this.UUV_FOLDER).forEach(file => {
+ // chaque template
+ if (file.includes(UUV_ENVELOPE.PLAYBOOK.toString())) {
+ const templateFile = fs.readFileSync(file);
+ // récupère noms scénario
+ const scenarioRow = templateFile.toString().split(this.SCENARIO_REGEXP);
+ if (scenarioRow) {
+ // chaque scénario
+ scenarioRow.forEach((value, index) => {
+ if (value.includes("Scenario") || value.includes("Scénario")) {
+ if (index + 1 <= scenarioRow.length) {
+ const scenarioName = scenarioRow[index + 1];
+ const scenarioSteps = scenarioRow[index + 2];
+ if (foundPlaybookedFile) {
+ this.generatePlaybookedFile(scenarioName, scenarioSteps);
+ }
+ // construit la phrase cucumber
+ data += `Given("${scenarioName}", function() {
+ return;
+ });
+`;
+ }
+ }
+ });
+ }
+ }
+ });
+ return data;
+ }
+
+ generateWordingFiles(
+ generatedFile: string
+ ): void {
+ const wordingFile = `${__dirname}/uuv/template-config.json`;
+ const definitionSteps = fs.readFileSync(
+ this.stepDefinitionFile!,
+ { encoding: "utf8" });
+ const updatedData = this.computeWordingFile(definitionSteps, wordingFile);
+ Common.writeWordingFile(generatedFile, updatedData);
+ }
+
+ private generatePlaybookedFile(wording, steps): void {
+ const stepsToCopy = `
+ ##### Start playbook "Given ${wording}"
+${steps}
+ ##### End playbook
+
+ `;
+ Common.getFileList(this.UUV_FOLDER).forEach(file => {
+ if (file.includes(UUV_ENVELOPE.PLAYBOOKED.toString())) {
+ const fileNamePath = file.split("/");
+ const fileName = fileNamePath[fileNamePath.length - 1];
+ const generatedPlaybookedFile = fs.readFileSync(`${this.generatedDir}/_${fileName.replace(UUV_ENVELOPE.PLAYBOOKED.toString(), UUV_ENVELOPE.PLAYBOOKED_GEN.toString())}`).toString();
+ const generatedPlaybookedFileUpdated = generatedPlaybookedFile.replaceAll(RegExp(`Given ${wording}$`, "gm"), stepsToCopy);
+ const consumerFileNameTab = file.split(".");
+ let generatedFeatureName = consumerFileNameTab[consumerFileNameTab.length - 3].concat(`.${UUV_ENVELOPE.PLAYBOOKED_GEN.toString()}`);
+ const generatedFeaturePathSplitByDir = generatedFeatureName.split("/");
+ if (generatedFeaturePathSplitByDir.length > 1) {
+ generatedFeatureName = generatedFeaturePathSplitByDir[generatedFeaturePathSplitByDir.length - 1];
+ }
+ Common.writeWordingFile(this.generatedDir + "/_" + generatedFeatureName, generatedPlaybookedFileUpdated);
+ }
+ });
+ }
+
+ private initializeGeneratedPlaybookedFile(): boolean {
+ let foundPlaybook = false;
+ Common.getFileList(this.UUV_FOLDER).forEach(file => {
+ if (file.includes(UUV_ENVELOPE.PLAYBOOKED.toString())) {
+ foundPlaybook = true;
+ const fileContent = fs.readFileSync(file).toString();
+ const fileNamePath = file.split("/");
+ const fileName = fileNamePath[fileNamePath.length - 1];
+ Common.writeWordingFile(this.generatedDir + "/_" + fileName.replace(UUV_ENVELOPE.PLAYBOOKED.toString(), UUV_ENVELOPE.PLAYBOOKED_GEN.toString()), fileContent);
+ }
+ });
+ if (!foundPlaybook) {
+ console.error(chalk.red("no playbook found at path ./e2e"));
+ }
+ return foundPlaybook;
+ }
+}
diff --git a/packages/runner-commons/src/step-definition-generator/generate-step-definitions.ts b/packages/runner-commons/src/step-definition-generator/generate-step-definitions.ts
index 8c63aefed..f42bb6a74 100644
--- a/packages/runner-commons/src/step-definition-generator/generate-step-definitions.ts
+++ b/packages/runner-commons/src/step-definition-generator/generate-step-definitions.ts
@@ -16,6 +16,7 @@
import { BaseStepDefinition } from "./generate-base-step-definitions";
import { BasedRoleStepDefinition } from "./generate-based-role-step-definitions";
import { STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM } from "./common";
+import { PlaybookStepDefinition } from "./generate-playbook-step-definitions";
export function generateStepDefinitionForRunner(baseDir: string, runner: TEST_RUNNER_ENUM) {
@@ -23,4 +24,6 @@ export function generateStepDefinitionForRunner(baseDir: string, runner: TEST_RU
cypressBaseStepDefinition.runGenerate();
const cypressBasedRoleStepDefinition: BasedRoleStepDefinition = new BasedRoleStepDefinition(baseDir, runner, STEP_DEFINITION_FILE_NAME.BY_ROLE);
cypressBasedRoleStepDefinition.runGenerate();
+ const cypressPlaybookStepDefinition: PlaybookStepDefinition = new PlaybookStepDefinition(baseDir, runner, STEP_DEFINITION_FILE_NAME.BY_SCENARIO_TEMPLATE);
+ cypressPlaybookStepDefinition.runGenerate();
}
diff --git a/packages/runner-cypress/.cypress-cucumber-preprocessorrc.json b/packages/runner-cypress/.cypress-cucumber-preprocessorrc.json
index 28a3a40f0..3e2022440 100644
--- a/packages/runner-cypress/.cypress-cucumber-preprocessorrc.json
+++ b/packages/runner-cypress/.cypress-cucumber-preprocessorrc.json
@@ -1,6 +1,7 @@
{
"stepDefinitions": [
"src/cucumber/step_definitions/cypress/generated/**/*.{js,ts}",
- "src/cucumber/step_definitions/cypress/unsafe/*.{js,ts}"
+ "src/cucumber/step_definitions/cypress/unsafe/*.{js,ts}",
+ "generated/*.{js,ts}"
]
}
diff --git a/packages/runner-cypress/cypress.config.ts b/packages/runner-cypress/cypress.config.ts
index 0590ebe20..d6a9ed6cc 100644
--- a/packages/runner-cypress/cypress.config.ts
+++ b/packages/runner-cypress/cypress.config.ts
@@ -6,7 +6,8 @@ export default defineConfig({
video: true,
e2e: {
baseUrl: "https://e2e-test-quest.github.io/simple-webapp",
- specPattern: "e2e/**/*.{cy.ts,feature}",
+ specPattern: ["e2e/**/*.cy.ts", "e2e/**/*.feature"],
+ excludeSpecPattern: ["e2e/**/*.playbook.feature", "e2e/**/*.playbooked.feature"],
supportFile: false,
setupNodeEvents,
viewportWidth: 1536,
diff --git a/packages/runner-cypress/e2e/playbook/example1.playbooked.feature b/packages/runner-cypress/e2e/playbook/example1.playbooked.feature
new file mode 100644
index 000000000..3bed37d47
--- /dev/null
+++ b/packages/runner-cypress/e2e/playbook/example1.playbooked.feature
@@ -0,0 +1,5 @@
+Feature: Accessibility Step Definition
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte3
+ Then I should not see an element with aria-label "[NOT] flegend"
diff --git a/packages/runner-cypress/e2e/playbook/example2.playbooked.feature b/packages/runner-cypress/e2e/playbook/example2.playbooked.feature
new file mode 100644
index 000000000..00127c2ea
--- /dev/null
+++ b/packages/runner-cypress/e2e/playbook/example2.playbooked.feature
@@ -0,0 +1,9 @@
+Feature: Accessibility Step Definition
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte
+ Then I should not see an element with aria-label "[NOT] flegend"
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte2
+ Then I should not see an element with aria-label "[NOT] flegend"
diff --git a/packages/runner-cypress/e2e/playbook/template/template.playbook.feature b/packages/runner-cypress/e2e/playbook/template/template.playbook.feature
new file mode 100644
index 000000000..6df99ae3f
--- /dev/null
+++ b/packages/runner-cypress/e2e/playbook/template/template.playbook.feature
@@ -0,0 +1,9 @@
+Feature: Template
+
+ Scenario: je me connecte
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template1"
+ Then I should see an element with aria-label "flegend"
+
+ Scenario: je me connecte3
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template3"
+ Then I should see an element with aria-label "flegend"
diff --git a/packages/runner-cypress/e2e/playbook/template/template2.playbook.feature b/packages/runner-cypress/e2e/playbook/template/template2.playbook.feature
new file mode 100644
index 000000000..f7293521e
--- /dev/null
+++ b/packages/runner-cypress/e2e/playbook/template/template2.playbook.feature
@@ -0,0 +1,5 @@
+Feature: Template
+
+ Scenario: je me connecte2
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template2"
+ Then I should see an element with aria-label "flegend"
diff --git a/packages/runner-cypress/generate-playbook-step-definitions.ts b/packages/runner-cypress/generate-playbook-step-definitions.ts
new file mode 100644
index 000000000..ec1e837a1
--- /dev/null
+++ b/packages/runner-cypress/generate-playbook-step-definitions.ts
@@ -0,0 +1,19 @@
+/**
+* Software Name : UUV
+*
+* SPDX-FileCopyrightText: Copyright (c) 2022-2023 Orange
+* SPDX-License-Identifier: MIT
+*
+* This software is distributed under the MIT License,
+* the text of which is available at https://spdx.org/licenses/MIT.html
+* or see the "LICENSE" file for more details.
+*
+* Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
+* Software description: Make test writing fast, understandable by any human
+* understanding English or French.
+*/
+
+import { STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM, PlaybookStepDefinition } from "@uuv/runner-commons";
+
+const playbookStepDefinition: PlaybookStepDefinition = new PlaybookStepDefinition(__dirname, TEST_RUNNER_ENUM.CYPRESS, STEP_DEFINITION_FILE_NAME.BY_SCENARIO_TEMPLATE);
+playbookStepDefinition.runGenerate();
diff --git a/packages/runner-cypress/package.json b/packages/runner-cypress/package.json
index 69e312fdc..a8d98871e 100644
--- a/packages/runner-cypress/package.json
+++ b/packages/runner-cypress/package.json
@@ -35,6 +35,7 @@
"scripts": {
"generate:step-definitions": "ts-node generate-step-definitions.ts",
"generate:step-definitions-documentation": "ts-node generate-step-definitions-documentation.ts",
+ "generate:playbook-step-definitions": "ts-node generate-playbook-step-definitions.ts",
"package": "npm pack --pack-destination=\"../../dist/packages\"",
"postinstall": "node postinstall.js",
"test:run": "node test.js --run",
diff --git a/packages/runner-cypress/src/cucumber/step_definitions/cypress/_playbook-engine.ts b/packages/runner-cypress/src/cucumber/step_definitions/cypress/_playbook-engine.ts
new file mode 100644
index 000000000..66aa219a1
--- /dev/null
+++ b/packages/runner-cypress/src/cucumber/step_definitions/cypress/_playbook-engine.ts
@@ -0,0 +1,17 @@
+/**
+ * Software Name : UUV
+ *
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2023 Orange
+ * SPDX-License-Identifier: MIT
+ *
+ * This software is distributed under the MIT License,
+ * the text of which is available at https://spdx.org/licenses/MIT.html
+ * or see the "LICENSE" file for more details.
+ *
+ * Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
+ * Software description: Make test writing fast, understandable by any human
+ * understanding English or French.
+ */
+
+import { defineStep as Given } from "@badeball/cypress-cucumber-preprocessor";
+
diff --git a/packages/runner-cypress/src/cucumber/step_definitions/cypress/base-check-engine.ts b/packages/runner-cypress/src/cucumber/step_definitions/cypress/base-check-engine.ts
index e96ea28c0..1f3dda239 100644
--- a/packages/runner-cypress/src/cucumber/step_definitions/cypress/base-check-engine.ts
+++ b/packages/runner-cypress/src/cucumber/step_definitions/cypress/base-check-engine.ts
@@ -13,7 +13,7 @@
* understanding English or French.
*/
-import { DataTable, Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
+import { DataTable, Given, Then, When, defineStep as UuvTemplate } from "@badeball/cypress-cucumber-preprocessor";
import { Context } from "./_context";
import "../../../cypress/commands";
import { Method } from "cypress/types/net-stubbing";
diff --git a/packages/runner-cypress/src/lib/uuv-cli.ts b/packages/runner-cypress/src/lib/uuv-cli.ts
index 31fd170fb..0a8a7e187 100644
--- a/packages/runner-cypress/src/lib/uuv-cli.ts
+++ b/packages/runner-cypress/src/lib/uuv-cli.ts
@@ -25,6 +25,7 @@ import fs from "fs";
import cypress from "cypress";
import { UuvCustomFormatter } from "../cucumber/uuv-custom-formatter";
+import { PlaybookStepDefinition, STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM } from "@uuv/runner-commons";
export async function main() {
const JSON_REPORT_DIR = "./uuv/reports/e2e/json";
@@ -37,15 +38,19 @@ export async function main() {
const argv = minimist(process.argv.slice(2));
const command = findTargetCommand(argv);
console.info(chalk.blueBright(`Executing UUV command ${command}...`));
- switch (command) {
- case "open":
- await openCypress(argv);
- break;
- case "e2e":
- await runE2ETests(argv);
- break;
- default:
- console.error(chalk.red("Unknown command"));
+
+ switch (command) {
+ case "open":
+ await openCypress(argv);
+ break;
+ case "e2e":
+ await runE2ETests(argv);
+ break;
+ case "playbook":
+ await runPlaybook();
+ break;
+ default:
+ console.error(chalk.red("Unknown command"));
process.exit(1);
}
console.info(`UUV command ${command} executed`);
@@ -97,6 +102,11 @@ export async function main() {
});
}
+ async function runPlaybook(): Promise {
+ const playbookStepDefinition: PlaybookStepDefinition = new PlaybookStepDefinition(__dirname + "/../..", TEST_RUNNER_ENUM.CYPRESS, STEP_DEFINITION_FILE_NAME.BY_SCENARIO_TEMPLATE);
+ playbookStepDefinition.runGenerate();
+ }
+
async function formatCucumberMessageFile() {
// Creating needed dirs
if (!fs.existsSync(JSON_REPORT_DIR)) {
diff --git a/packages/runner-cypress/target-config/.cypress-cucumber-preprocessorrc.json b/packages/runner-cypress/target-config/.cypress-cucumber-preprocessorrc.json
index 7ffa6d8de..93e53e052 100644
--- a/packages/runner-cypress/target-config/.cypress-cucumber-preprocessorrc.json
+++ b/packages/runner-cypress/target-config/.cypress-cucumber-preprocessorrc.json
@@ -1,7 +1,8 @@
{
"stepDefinitions": [
"cucumber/step_definitions/**/*.{js,ts}",
- "../node_modules/@uuv/cypress/dist/cucumber/step_definitions/cypress/{generated,unsafe}/**/*.{js,ts}"
+ "../node_modules/@uuv/cypress/dist/cucumber/step_definitions/cypress/{generated,unsafe}/**/*.{js,ts}",
+ "uuv/generated/*.{js,ts}"
],
"messages": {
"enabled": true
diff --git a/packages/runner-cypress/target-config/cypress.config.ts b/packages/runner-cypress/target-config/cypress.config.ts
index d19999192..dd2ff4d2c 100644
--- a/packages/runner-cypress/target-config/cypress.config.ts
+++ b/packages/runner-cypress/target-config/cypress.config.ts
@@ -8,7 +8,8 @@ export default defineConfig({
screenshotsFolder: "reports/screenshots",
e2e: {
baseUrl: "http://localhost:4200",
- specPattern: "e2e/**/*.{cy.ts,feature}",
+ specPattern: ["e2e/**/*.cy.ts", "e2e/**/*.feature"],
+ excludeSpecPattern: ["e2e/**/*.playbook.feature", "e2e/**/*.playbooked.feature"],
supportFile: false,
setupNodeEvents,
viewportWidth: 1536,
diff --git a/packages/runner-playwright/cucumber.cjs b/packages/runner-playwright/cucumber.cjs
index ea49ddde1..09cd87ec2 100644
--- a/packages/runner-playwright/cucumber.cjs
+++ b/packages/runner-playwright/cucumber.cjs
@@ -1,10 +1,11 @@
module.exports = {
default: {
- paths: [ 'e2e/*.feature' ],
+ paths: [ 'e2e/**/*.feature'],
require: [ 'src/cucumber/step_definitions/playwright/**/*.{ts,js}' ],
publishQuiet: true,
format: ['html:report/playwright/cucumber-report.html', 'message:report/cucumber-messages.ndjson', 'html:cucumber-report.html'],
compiler: 'ts:ts-node/register',
requireModule: ['ts-node/register'],
+ tags: 'not @Ignore'
},
};
diff --git a/packages/runner-playwright/e2e/playbook/example1.playbooked.feature b/packages/runner-playwright/e2e/playbook/example1.playbooked.feature
new file mode 100644
index 000000000..78a7cdcf6
--- /dev/null
+++ b/packages/runner-playwright/e2e/playbook/example1.playbooked.feature
@@ -0,0 +1,6 @@
+@Ignore
+Feature: Accessibility Step Definition
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte3
+ Then I should not see an element with aria-label "[NOT] flegend"
diff --git a/packages/runner-playwright/e2e/playbook/example2.playbooked.feature b/packages/runner-playwright/e2e/playbook/example2.playbooked.feature
new file mode 100644
index 000000000..248f42500
--- /dev/null
+++ b/packages/runner-playwright/e2e/playbook/example2.playbooked.feature
@@ -0,0 +1,10 @@
+@Ignore
+Feature: Accessibility Step Definition
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte
+ Then I should not see an element with aria-label "[NOT] flegend"
+
+ Scenario: key.then.a11y.check.default
+ Given je me connecte2
+ Then I should not see an element with aria-label "[NOT] flegend"
diff --git a/packages/runner-playwright/e2e/playbook/template/template.playbook.feature b/packages/runner-playwright/e2e/playbook/template/template.playbook.feature
new file mode 100644
index 000000000..bc45ae11b
--- /dev/null
+++ b/packages/runner-playwright/e2e/playbook/template/template.playbook.feature
@@ -0,0 +1,10 @@
+@Ignore
+Feature: Template
+
+ Scenario: je me connecte
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template1"
+ Then I should see an element with aria-label "flegend"
+
+ Scenario: je me connecte3
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template3"
+ Then I should see an element with aria-label "flegend"
diff --git a/packages/runner-playwright/e2e/playbook/template/template2.playbook.feature b/packages/runner-playwright/e2e/playbook/template/template2.playbook.feature
new file mode 100644
index 000000000..34ff5b629
--- /dev/null
+++ b/packages/runner-playwright/e2e/playbook/template/template2.playbook.feature
@@ -0,0 +1,6 @@
+@Ignore
+Feature: Template
+
+ Scenario: je me connecte2
+ When I visit path "https://e2e-test-quest.github.io/simple-webapp/?template2"
+ Then I should see an element with aria-label "flegend"
diff --git a/packages/runner-playwright/generate-playbook-step-definitions.ts b/packages/runner-playwright/generate-playbook-step-definitions.ts
new file mode 100644
index 000000000..1a889235b
--- /dev/null
+++ b/packages/runner-playwright/generate-playbook-step-definitions.ts
@@ -0,0 +1,19 @@
+/**
+* Software Name : UUV
+*
+* SPDX-FileCopyrightText: Copyright (c) 2022-2023 Orange
+* SPDX-License-Identifier: MIT
+*
+* This software is distributed under the MIT License,
+* the text of which is available at https://spdx.org/licenses/MIT.html
+* or see the "LICENSE" file for more details.
+*
+* Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
+* Software description: Make test writing fast, understandable by any human
+* understanding English or French.
+*/
+
+import { STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM, PlaybookStepDefinition } from "@uuv/runner-commons";
+
+const playbookStepDefinition: PlaybookStepDefinition = new PlaybookStepDefinition(__dirname, TEST_RUNNER_ENUM.PLAYWRIGHT, STEP_DEFINITION_FILE_NAME.BY_SCENARIO_TEMPLATE);
+playbookStepDefinition.runGenerate();
diff --git a/packages/runner-playwright/package.json b/packages/runner-playwright/package.json
index b91a1d5bb..d7b42b945 100644
--- a/packages/runner-playwright/package.json
+++ b/packages/runner-playwright/package.json
@@ -34,6 +34,7 @@
],
"scripts": {
"generate:step-definitions": "ts-node generate-step-definitions.ts",
+ "generate:playbook-step-definitions": "ts-node generate-playbook-step-definitions.ts",
"package": "npm pack --pack-destination=\"../../dist/packages\"",
"postinstall": "node postinstall.js",
"serverTest:run": "ts-node playwright/run-test-app.ts 9002",
diff --git a/packages/runner-playwright/src/cucumber/step_definitions/playwright/_playbook-engine.ts b/packages/runner-playwright/src/cucumber/step_definitions/playwright/_playbook-engine.ts
new file mode 100644
index 000000000..0bf552786
--- /dev/null
+++ b/packages/runner-playwright/src/cucumber/step_definitions/playwright/_playbook-engine.ts
@@ -0,0 +1,16 @@
+/**
+ * Software Name : UUV
+ *
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2023 Orange
+ * SPDX-License-Identifier: MIT
+ *
+ * This software is distributed under the MIT License,
+ * the text of which is available at https://spdx.org/licenses/MIT.html
+ * or see the "LICENSE" file for more details.
+ *
+ * Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
+ * Software description: Make test writing fast, understandable by any human
+ * understanding English or French.
+ */
+
+import { Given } from "@cucumber/cucumber";
diff --git a/packages/runner-playwright/src/cucumber/step_definitions/playwright/base-check-engine.ts b/packages/runner-playwright/src/cucumber/step_definitions/playwright/base-check-engine.ts
index 9b9cf53ae..164742c8d 100644
--- a/packages/runner-playwright/src/cucumber/step_definitions/playwright/base-check-engine.ts
+++ b/packages/runner-playwright/src/cucumber/step_definitions/playwright/base-check-engine.ts
@@ -14,7 +14,7 @@
*/
import { DEFAULT_TIMEOUT, fs, key, KEY_PRESS } from "@uuv/runner-commons";
-import { checkA11y, configureAxe, injectAxe } from "axe-playwright";
+import { checkA11y, injectAxe } from "axe-playwright";
import { Locator } from "playwright";
import { devices, expect } from "@playwright/test";
import { Page } from "playwright";
diff --git a/packages/runner-playwright/src/lib/uuv-cli.ts b/packages/runner-playwright/src/lib/uuv-cli.ts
index c0a5cac0e..f8642a265 100644
--- a/packages/runner-playwright/src/lib/uuv-cli.ts
+++ b/packages/runner-playwright/src/lib/uuv-cli.ts
@@ -21,6 +21,7 @@ import figlet from "figlet";
import minimist from "minimist";
import { run } from "./runner-playwright";
import fs from "fs";
+import { PlaybookStepDefinition, STEP_DEFINITION_FILE_NAME, TEST_RUNNER_ENUM } from "@uuv/runner-commons";
export async function main() {
const PROJECT_DIR = "uuv";
@@ -37,6 +38,9 @@ export async function main() {
case "e2e":
await runE2ETests(argv);
break;
+ case "playbook":
+ await runPlaybook();
+ break;
default:
console.error(chalk.red("Unknown command"));
process.exit(1);
@@ -79,6 +83,11 @@ export async function main() {
});
}
+ async function runPlaybook(): Promise {
+ const playbookStepDefinition: PlaybookStepDefinition = new PlaybookStepDefinition(__dirname + "/../..", TEST_RUNNER_ENUM.PLAYWRIGHT, STEP_DEFINITION_FILE_NAME.BY_SCENARIO_TEMPLATE);
+ playbookStepDefinition.runGenerate();
+ }
+
function findTargetCommand(argv: any) {
if (argv._.length < 1) {
console.error(chalk.red("No command specified"));
diff --git a/packages/runner-playwright/target-config/cucumber.cjs b/packages/runner-playwright/target-config/cucumber.cjs
index e498637fb..5dd065709 100644
--- a/packages/runner-playwright/target-config/cucumber.cjs
+++ b/packages/runner-playwright/target-config/cucumber.cjs
@@ -8,6 +8,7 @@ module.exports = {
publishQuiet: true,
requireModule: [
'ts-node/register'
- ]
+ ],
+ tags: 'not @Ignore'
},
};