cypress-allure-plugin
cypress-allure-plugin copied to clipboard
cypress plugin to use allure reporter api in tests
cypress-allure-plugin
Plugin for integrating allure reporter in Cypress with support of Allure API.
Installation
-
Allure binary: directly from allure2 or allure-commandline npm package.
-
Java 8 (required to run allure binary)
-
There is no need to set this plugin as reporter in Cypress or use any other allure reporters. Just download:
- using yarn:
yarn add -D @shelex/cypress-allure-plugin
- using npm:
npm i -D @shelex/cypress-allure-plugin
Setup
-
(Before Cypress 10) Connect plugin in
cypress/plugins/index.js
. Take into account that Cypress generate plugins file withmodule.exports
on the first initialization but you should have only one export section. In order to add Allure writer task just replace it or add writer task somewhere before returning config:const allureWriter = require('@shelex/cypress-allure-plugin/writer'); // import allureWriter from "@shelex/cypress-allure-plugin/writer"; module.exports = (on, config) => { allureWriter(on, config); return config; };
-
(After Cypress 10) Use
defineConfig
andsetupNodeEvents
inside config.js\config.ts files:module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { AllureWriter(on, config); return config; } } });
-
if you have webpack or other preprocessors
- (Before Cypress 10) please set allure writer before returning "config":
module.exports = (on, config) => { on('file:preprocessor', webpackPreprocessor); allureWriter(on, config); return config; };
- (After Cypress 10) use
defineConfig
andsetupNodeEvents
inside config.js\config.ts files:
module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { on('file:preprocessor', webpackPreprocessor); AllureWriter(on, config); return config; } } });
-
-
Register commands in
cypress/support/index.js
(orcypress/support/e2e.js
for cypress 10+) file:- with
import
:
import '@shelex/cypress-allure-plugin';
- with
require
:
require('@shelex/cypress-allure-plugin');
- with
-
for IntelliSense (autocompletion) support in your IDE add
tsconfig.json
and specifytypes
property forcompilerOptions
:
"compilerOptions": {
"allowJs": true,
"baseUrl": "./",
"types": ["@shelex/cypress-allure-plugin"],
"noEmit": true
},
Configuration
Plugin is customizable via Cypress environment variables:
env variable name | description | default |
---|---|---|
allure |
enable Allure plugin | false |
allureResultsPath |
customize path to allure results folder | allure-results |
tmsPrefix |
just a prefix substring or pattern with * for links from allure API in tests to test management system |
`` |
issuePrefix |
prefix for links from allure API in tests to bug tracking system | `` |
allureLogCypress |
log cypress chainer (commands) and display them as steps in report | true |
allureLogGherkin |
log gherkin steps from cucumber-preprocessor | inherits allureLogCypress value if not specified directly |
allureAttachRequests |
attach cy.request headers, body, response headers, respose body to step automatically |
false |
allureOmitPreviousAttemptScreenshots |
omit screenshots attached in previous attempts when retries are used | false |
allureSkipAutomaticScreenshots |
do not add screenshots automatically (for those who uses custom scripts, etc.) | false |
allureClearSkippedTests |
remove skipped tests from report | false |
allureAddAnalyticLabels |
add framework and language labels to tests (used for allure analytics only) | false |
allureAddVideoOnPass |
attach video to report for passed tests | false |
These options could be passed in multiple ways, you can check docs.
But also you can use allure.properties
file (but you still need to enable allure by passing allure=true
to cypress env variables):
allure.results.directory=custom_dir
allure.link.issue.pattern=https://example.com/task_
allure.link.tms.pattern=https://example.com/test_case_
allure.cypress.log.commands=true
allure.cypress.log.requests=true
allure.cypress.log.gherkin=true
allure.omit.previous.attempt.screenshot=true
allure.analytics=false
allure.video.passed=false
Execution
- To enable Allure results writing just pass environment variable
allure=true
, example:
npx cypress run --env allure=true
- if allure is enabled, you can check gathered data, in cypress window with Chrome Developer tools console:
Cypress.Allure.reporter.runtime.writer;
Debugging
- for in-browser information (cypress events, mocha events, allure events, data collecting)
execute
localStorage.debug = 'allure-plugin*'
in DevTools console - for writer task information (writing results to disk, handling attachments, plugin events)
add
DEBUG=allure-plugin*
before cypress run\open command
Examples
See cypress-allure-plugin-example project, which is already configured to use this plugin, hosting report as github page and run by github action. It has configuration with complete history (allure can display 20 build results ) with links to older reports and links to CI builds.
There are also existing solutions that may help you prepare your report infrastructure:
- Allure docker service - highly customizable feature-rich container
- Allure Server - self-hosted portal with your reports
- allure-reports-portal - another portal which allows to gather reports for multiple projects in single ui
- allure-static-booster - solution for generating self-hosted Allure report on GitLab pages including the tables with results, pipeline links and navigation between the different Allure reports.
- Github Action - report generation + better implementation for historic reports described above
How to open report
Assuming allure is already installed:
- serve report based on current "allure-results" folder:
allure serve
- generate new report based on current "allure-results" folder:
allure generate
- open generated report from "allure-report" folder:
allure open
API
There are three options of using allure api inside tests:
- Using interface from
Cypress.Allure.reporter.getInterface()
- synchronous
const allure = Cypress.Allure.reporter.getInterface();
allure.feature('This is our feature');
allure.epic('This is epic');
allure.issue('google', 'https://google.com');
- Using Cypress custom commands, always starting from
cy.allure()
- chainer
cy.allure()
.feature('This is feature')
.epic('This is epic')
.issue('google', 'https://google.com')
.parameter('name', 'value')
.tag('this is nice tag', 'as well as this');
- Using Cypress-cucumber-preprocessor with cucumber tags:
@AS_ID("id_of_test_for_testops")
@parentSuite("someParentSuite")
@suite("someSuite")
@subSuite("someSubSuite")
@epic("thisisepic")
@feature("nice")
@story("cool")
@severity("critical")
@owner("IAMOwner")
@issue("jira","JIRA-1234")
@tms("tms","TC-1234")
@link("other","url")
@someOtherTagsWillBeAddedAlso
Scenario: Here is scenario
...
Allure API available:
- testID(id: string)
- epic(epic: string)
- feature(feature: string)
- story(story: string)
- parentSuite(name: string)
- suite(name: string)
- subSuite(name:string)
- label(name: LabelName, value: string)
- parameter(name: string, value: string)
- testParameter(name: string, value: string)
- testName(name: string)
- link(url: string, name?: string, type?: LinkType)
- issue(name: string, url: string)
- tms(name: string, url: string)
- description(markdown: string)
- descriptionHtml(html: string)
- owner(owner: string)
- severity(severity: Severity)
- tag(tags: ...string)
- attachment(name: string, content: Buffer | string, type: ContentType)
- testAttachment(name: string, content: Buffer | string, type: ContentType)
- fileAttachment(name: string, path: string, type: ContentType)
- startStep(name: string)
- endStep()
- step(name: string, isParent: boolean)
- logStep(name: string)
Gherkin and tms or issue links
It is posible to pass tms link or issue link with tags tms("ABC-111")
and issue("ABC-222")
.
However, that will not work well with Scenario Outlines which may have different examples being linked to different tasks or test cases in tms.
So, plugin will also parse your scenario outlines with examples and in case header in table will be tms
or issue
- it will add it as link to report.
Scenario Outline: Some scenario
Given User want to link test <number> to tms
When User creates examples table with tms and issue headers
Then Links will be added to allure
Examples:
| tms | issue | number |
| TEST-1 | JIRA-11 | 1 |
| TEST-2 | JIRA-22 | 2 |
VS Code for cypress + cucumber
In case you are using VS Code and Cypress Helper extension, it has configuration for allure cucumber tags autocompletion available:
"cypressHelper.cucumberTagsAutocomplete": {
"enable": true,
"allurePlugin": true,
"tags": ["focus", "someOtherTag"]
}
Screenshots and Videos
Screenshots are attached automatically, for other type of content feel free to use testAttachment
(for current test), attachment
(for current executable), fileAttachment
(for existing file).
Videos are attached for failed tests only from path specified in cypress config videosFolder
and in case you have not passed video=false
to Cypress configuration.
Before version 2.21.0
In case you want to attach videos for passed tests please use allureAddVideoOnPass=true
env variable.
Videos are quite tricky as Cypress has no events which we can use to catch event with video name as it is processed when test runner itself (cy) has closed. As a workaround we can add video link before even video is saved and then we have two options:
-
videosFolder
is set asallure-results
(or custom value you can pass asallureResultsPath
) in cypress.json or configuration options. in this case video is written directly in allure-results and will be linked by name. -
videosFolder
is outsideallure-results
relative path fromallure-report
tovideosFolder
will be added.
Please take into account, that in case spec files have same name, cypress is creating subfolders in videos folder, and it is not handled from plugin unfortunately, so video may not have correct path in such edge case.
Update in version 2.21.0
As Cypress has released After Spec API now this event could be evaluated for attachments. Now it will be used for:
- run mode with v6.7.0 and above
- run mode with v6.2.0 and above (but below v6.7.0) with
experimentalRunEvents
enabled - interactive (open) mode for v7.1.0 with
experimentalInteractiveRunEvents
enabled When one of this conditions is satisfied -after:spec
event will be used for attachments. It will reliably copy all screenshots available for each test and video (if available) to yourallure-results
folder and attach to each of your tests, so you don't need to somehow upload your videos and configure paths, etc.
Suite structuring
Allure support 3 levels of suite structure:
-
Suite
tab:parentSuite
->suite
->subSuite
-> tests -
Behaviors
tab:epic
->feature
->story
-> tests
They are defined automatically by structure passed from cypress mocha test object with titles of each parent.
So an array of names of describe
blocks is just transformed into:
[parentSuite, suite, "subsuite1 -> subsuite2 -> ..."]
However, since v2.29.0 you can modify the strategy of defining names for structuring the tests by overwriting the function in support/index
file using Cypress.Allure.reporter.getInterface().defineSuiteLabels
which will accept your function:
// remove all describe block names and leave just last one:
Cypress.Allure.reporter
.getInterface()
.defineSuiteLabels((titlePath, fileInfo) => {
return [titlePath.pop()];
});
This function will have 2 arguments. titlePath
is that array of describe names, and fileInfo
is a parsed representation of a filepath for cases when you want to include folder or filename into some names, or just wrap suites in folders, or implement any of your ideas how to structure tests in reports.
// supplement parentSuite name with folder name
Cypress.Allure.reporter
.getInterface()
.defineSuiteLabels((titlePath, fileInfo) => {
const [parentSuite, suite, ...subSuites] = titlePath;
return [`${fileInfo.folder} | ${parentSuite}`, suite, ...subSuites];
});
// make folder name a parentSuite:
Cypress.Allure.reporter
.getInterface()
.defineSuiteLabels((titlePath, fileInfo) => {
return [fileInfo.folder, ...titlePath];
});
// remove any other describe blocks and just show last one:
Cypress.Allure.reporter
.getInterface()
.defineSuiteLabels((titlePath, fileInfo) => {
return [titlePath.pop()];
});
// remove describe names and just place tests in folder -> filename structure:
Cypress.Allure.reporter
.getInterface()
.defineSuiteLabels((titlePath, fileInfo) => {
return [fileInfo.folder, fileInfo.name];
});
Cypress commands as steps
Commands are producing allure steps automatically based on cypress events and are trying to represent how code and custom commands are executed with nested structure.
Moreover, steps functionality could be expanded with:
-
cy.allure().step('name')
- will create step "name" for current test. This step will be finished when next such step is created or test is finished. -
cy.allure().step('name', false)
ORcy.allure().logStep('name')
- will create step "name" for current parent step/hook/test. Will be finished when next step is created or test finished. -
cy.allure().startStep('name')
- will create step "name" for current cypress command step / current step / current parent step / current hook or test. Is automatically finished on fail event or test end, but I would recommend to explicitly mentioncy.allure().endStep()
which will finish last created step.
Testing
-
npm run test:prepare:basic
- generate allure results for tests incypress/integration/basic
folder -
npm run test:prepare:cucumber
- generate allure results for tests incypress/integration/cucumber
folder -
test
- run tests fromcypress/integration/results
against these allure results
Credits
A lot of respect to Sergey Korol who made Allure-mocha reporter. Base integration with Cypress internal mocha runner is based on that solution.
License
Copyright 2020-2022 Oleksandr Shevtsov [email protected].
This project is licensed under the Apache 2.0 License.