diff --git a/README.md b/README.md index 3f8c4d9..50bd375 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Zero config Mochawesome reporter for Cypress with screenshots attached to tests. import 'cypress-mochawesome-reporter/cucumberSupport'; ``` - > ⚠️ `cypress-cucumber-preprocessor` uses the same hooks as `cypress-mochawesome-reporter`, you also need to install [cypress-on-fix](https://github.com/bahmutov/cypress-on-fix). + > ⚠️ `cypress-cucumber-preprocessor` uses the same hooks as `cypress-mochawesome-reporter`, you also need to install [cypress-on-fix](https://github.com/bahmutov/cypress-on-fix). Full example of using `cypress-mochawesome-reporter` with `cypress-cucumber-preprocessor` can be found [here](examples/cucumber). 5. run cypress @@ -121,7 +121,7 @@ module.exports = defineConfig({ Additional reporter options: | name | type | default | description | -|-----------------------| --------- | ------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| --------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `embeddedScreenshots` | `boolean` | `false` | Embedded external screenshots into HTML using base64, use with `inlineAssets` option to produce a single HTML file | | `ignoreVideos` | `boolean` | `false` | Will not copy videos recorded by Cypress nor show them in the mochawesome report. Requires that Cypress config option `video` is set to `true` for the option to have any effect
Because mochawesome doesn't support context per spec file, each test will have the whole spec file video. More info can be found [here](https://github.com/LironEr/cypress-mochawesome-reporter/issues/43) | | `videoOnFailOnly` | `boolean` | `false` | If Videos are recorded and added to the report, setting this to `true` will add the videos only to tests with failures.
Do not that this will NOT cause video's to only record failed tests, just they not be added to passed tests in the mochawesome report | @@ -143,6 +143,7 @@ Add extra information to the report manually by using `cy.addTestContext()` as s 4. [Change default screenshots folder in `cypress.json`](examples/screenshots-folder) 5. [Using `cypress-mochawesome-reporter` with typescript](examples/simple-typescript) 6. [Using `cypress-mochawesome-reporter` with `cypress-parallel`](examples/cypress-parallel) +7. [Using `cypress-mochawesome-reporter` with `cypress-cucumber-preprocessor`](examples/cucumber) Run `npm i` in root directory then: diff --git a/cypress/e2e/cucumber.cy.js b/cypress/e2e/cucumber.cy.js new file mode 100644 index 0000000..886320b --- /dev/null +++ b/cypress/e2e/cucumber.cy.js @@ -0,0 +1,104 @@ +describe(`cucumber folder`, () => { + beforeEach(() => { + cy.visit(`examples/cucumber/cypress/reports/html/index.html`); + }); + + it('Validate all tests exists', () => { + cy.get('li[title="Suites"]').contains(1); + cy.get('li[title="Tests"]').contains(5); + cy.get('li[title="Passed"]').contains(4); + cy.get('li[title="Failed"]').contains(1); + }); + + it('screenshot exist for failed test', () => { + // 2 retries + cy.validateTestHasScreenshot('fail', 2); + }); + + it('video exist for tests', () => { + cy.validateTestHasVideo('pass'); + cy.validateTestHasVideo('fail'); + cy.validateTestHasVideo('pass with examples (example #1)'); + cy.validateTestHasVideo('pass with examples (example #2)'); + cy.validateTestHasVideo('pass with examples (example #3)'); + }); + + describe('Validate test code text', () => { + it('pass', () => { + cy.validateTestCode( + 'pass', + ` +Feature: Test 1 + + Scenario: pass + When I visit "site/index.html" + Then The list has 4 items +` + ); + }); + + it('fail', () => { + cy.validateTestCode( + 'fail', + ` +Feature: Test 1 + + Scenario: fail + When I visit "site/index.html" + Then The list has 5 items +` + ); + }); + + it('pass with examples (example #1)', () => { + cy.validateTestCode( + 'pass with examples (example #1)', + ` +Feature: Test 1 + + Scenario Outline: pass with examples + When I visit "site/index.html" + Then The list has more than items + + Examples: + | num | + | 1 | +` + ); + }); + + it('pass with examples (example #2)', () => { + cy.validateTestCode( + 'pass with examples (example #2)', + ` +Feature: Test 1 + + Scenario Outline: pass with examples + When I visit "site/index.html" + Then The list has more than items + + Examples: + | num | + | 2 | +` + ); + }); + + it('pass with examples (example #3)', () => { + cy.validateTestCode( + 'pass with examples (example #3)', + ` +Feature: Test 1 + + Scenario Outline: pass with examples + When I visit "site/index.html" + Then The list has more than items + + Examples: + | num | + | 3 | +` + ); + }); + }); +}); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 1ea41c8..fdfe9c7 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -19,32 +19,51 @@ Cypress.Commands.add('validateTestHasScreenshot', (testTitle, numberOfScreenshot }); }); }); + Cypress.Commands.add('validateTestHasVideo', (testTitle) => { - cy.get(`[title="${testTitle}"]`) - .click() - .parents('li[class*="test--component"]') - .then(([$el]) => { - cy.wrap($el) - .find('video') - .then(($vids) => { - cy.wrap($vids) - .should('have.length', 1) - .each(([$vid]) => { - cy.wrap($vid) - .should('be.visible') - .find('source') - .should('have.attr', 'type', 'video/mp4') - }); - }); + cy.get(`[title="${testTitle}"]`) + .click() + .parents('li[class*="test--component"]') + .then(([$el]) => { + cy.wrap($el) + .find('video') + .then(($vids) => { + cy.wrap($vids) + .should('have.length', 1) + .each(([$vid]) => { + cy.wrap($vid).should('be.visible').find('source').should('have.attr', 'type', 'video/mp4'); + }); }); + }); }); + Cypress.Commands.add('validateTestHasNoVideo', (testTitle) => { - cy.get(`[title="${testTitle}"]`) - .click() - .parents('li[class*="test--component"]') - .then(([$el]) => { - cy.wrap($el) - .find('video') - .should('not.exist') + cy.get(`[title="${testTitle}"]`) + .click() + .parents('li[class*="test--component"]') + .then(([$el]) => { + cy.wrap($el).find('video').should('not.exist'); + }); +}); + +Cypress.Commands.add('validateTestCode', (testTitle, content) => { + // cy.get('code').debug(); + cy.get(`[title="${testTitle}"]`) + .click() + .parents('li[class*="test--component"]') + .then(([$el]) => { + cy.wrap($el) + .find('code') + .then(($codes) => { + cy.wrap($codes) + .last() + .wrap(($code) => { + cy.wrap($code) + .should('be.visible') + .wrap(($c) => { + expect($c.text().trim(), 'match content').to.be.equal(content.trim()); + }); + }); }); + }); }); diff --git a/examples/cucumber/README.md b/examples/cucumber/README.md new file mode 100644 index 0000000..30fbe6e --- /dev/null +++ b/examples/cucumber/README.md @@ -0,0 +1,47 @@ +# Setup with `cypress-cucumber-preprocessor` + +> ⚠️ `@badeball/cypress-cucumber-preprocessor` require node >= 18 + +1. Follow the steps in the [main README](../../README.md) to setup the reporter. + +1. Your `cypress.config.js` file should look like: + + ```js + const { defineConfig } = require('cypress'); + const cypressOnFix = require('cypress-on-fix'); + const createBundler = require('@bahmutov/cypress-esbuild-preprocessor'); + const { addCucumberPreprocessorPlugin } = require('@badeball/cypress-cucumber-preprocessor'); + const { createEsbuildPlugin } = require('@badeball/cypress-cucumber-preprocessor/esbuild'); + + module.exports = defineConfig({ + reporter: 'cypress-mochawesome-reporter', + video: true, + retries: 1, + e2e: { + specPattern: 'cypress/e2e/**/*.feature', + async setupNodeEvents(on, config) { + // "cypress-on-fix" is required because "cypress-mochawesome-reporter" and "cypress-cucumber-preprocessor" use the same hooks + on = cypressOnFix(on); + + require('cypress-mochawesome-reporter/plugin')(on); + + await addCucumberPreprocessorPlugin(on, config); + + on( + 'file:preprocessor', + createBundler({ + plugins: [createEsbuildPlugin(config)], + }) + ); + + return config; + }, + }, + }); + ``` + +1. Add to `cypress/support/step_definitions/index.js` + + ```js + import 'cypress-mochawesome-reporter/cucumberSupport'; + ``` diff --git a/examples/cucumber/package.json b/examples/cucumber/package.json index 99ff50e..c583673 100644 --- a/examples/cucumber/package.json +++ b/examples/cucumber/package.json @@ -7,6 +7,8 @@ }, "license": "MIT", "devDependencies": { + "@badeball/cypress-cucumber-preprocessor": "^19.2.0", + "@bahmutov/cypress-esbuild-preprocessor": "^2.2.0", "cypress": "^13.1.0", "cypress-on-fix": "^1.0.2", "cypress-mochawesome-reporter": "../../" diff --git a/package-lock.json b/package-lock.json index b41b6be..4c895f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ }, "devDependencies": { "@badeball/cypress-cucumber-preprocessor": "^19.2.0", - "@bahmutov/cypress-esbuild-preprocessor": "^2.2.0", "cypress": "^13.1.0", "lerna": "^7.1.4" }, @@ -357,35 +356,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/@bahmutov/cypress-esbuild-preprocessor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@bahmutov/cypress-esbuild-preprocessor/-/cypress-esbuild-preprocessor-2.2.0.tgz", - "integrity": "sha512-pTvxRi6+OFsXy6uCn/HlO5zi0fUZWbiCtTiLTDf/+kgEfZ/Y8WIxZ2pjuir9MEM8prQenBw60TLcM0wcazh7+Q==", - "dev": true, - "dependencies": { - "debug": "4.3.4" - }, - "peerDependencies": { - "esbuild": ">=0.17.0" - } - }, - "node_modules/@bahmutov/cypress-esbuild-preprocessor/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -11045,26 +11015,6 @@ } } }, - "@bahmutov/cypress-esbuild-preprocessor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@bahmutov/cypress-esbuild-preprocessor/-/cypress-esbuild-preprocessor-2.2.0.tgz", - "integrity": "sha512-pTvxRi6+OFsXy6uCn/HlO5zi0fUZWbiCtTiLTDf/+kgEfZ/Y8WIxZ2pjuir9MEM8prQenBw60TLcM0wcazh7+Q==", - "dev": true, - "requires": { - "debug": "4.3.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } - } - }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", diff --git a/package.json b/package.json index 0de82a8..aa2e5f7 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "scripts": { "lerna": "lerna", - "install-examples": "lerna exec --scope @example/* \"npm i\"", + "install-examples": "lerna exec --concurrency 1 --scope @example/* \"npm i\"", "test:prepare": "lerna run --stream --no-bail --concurrency 1 --scope @example/* test", "test": "cypress run", "cypress:open": "cypress open" @@ -41,7 +41,6 @@ }, "devDependencies": { "@badeball/cypress-cucumber-preprocessor": "^19.2.0", - "@bahmutov/cypress-esbuild-preprocessor": "^2.2.0", "cypress": "^13.1.0", "lerna": "^7.1.4" }, @@ -52,6 +51,7 @@ "lib", "register.js", "plugin.js", - "index.d.ts" + "index.d.ts", + "cucumberSupport.js" ] }