I’ve created a simple repo to demonstrate how I’ve setup CucumberJS and Puppeteer. I wanted to extend this and be a little more than just “let’s get something running”, so I’ve added ability to do screenshots and generate reports (cucumber html and junit xml). I also wanted to demonstrate some of the other things that can be done with CucumberJS, so have opted to use a slightly different folder structure than the default — something like this:
└── features
├── simple.feature
├── support
│ └── hooks.js
└──step_definitions
└── steps.js
To something more like this ...
The folder structure:
.
├── README.md
└── e2e
├── config
│ └── properties.json
├── features
│ └── simple.feature
├── output
│ ├── report
│ └── screenshots
├── package.json
└── step_definitions
├── launch_steps.js
└── support
├── constants.js
├── hooks.js
└── scope.js
config/properties.json — is used by the npm library ‘konfig’ to determine what default/environment specific variables that need to be set. This is used in conjunction with step_definitions/support/constants.js
features/simple.feature — this contains the main feature file with our test scenarios
output — this folder contains the output; screenshots folder, reports folder
package.json — defines what dependencies and scripts are required for this project
step_definitions — this folder contains all the puppeteer steps and support files
step_definitions/launch_steps.js — this contains all the puppeteer step definitions
step_definitions/support — this folder contains relevant support files
step_definitions/support/constants.js — any global values that need to be defined, is used in conjunction with config/properties.json
step_definitions/support/hooks.js — is used by CucumberJS to define what needs to happen run before/after each run, scenario. It’s also where puppeteer is defined, and the browser object created.
step_definitions/support/scope.js — are global values used by puppeteer to define the browser, scope and page
- Clone the repo
git clone https://github.com/wxlam/simple-cucumber-puppeteer-example.git
2. Move into the e2e
folder
cd e2e
3. Install the npm packages
npm install
or yarn
4. Run the tests
npm run puppeteer
or yarn puppeteer
5. Generate the html reports; the reports require a JSON file with the results of the run, so it’s necessary to run the tests first.
npm run report:html
or yarn report:html
This will generate a html report of the result, you can find the report in the ‘output/report’ folder
for junit xml reports:
npm run report:junit
or yarn report:junit
When it comes to working with CucumberJS, there are many options you can set — you can specify which tags to run, which folder your step definitions exist in, if you want to output the results to a JSON file, and show progress of the execution using different flags.
./node_modules/cucumber/bin/cucumber-js --tags=@run -r step_definitions -f json:output/results.json -f progress
Tags:
If you just want to run scenarios tagged with @run
then use--tags=@run
If you want to run scenarios with multiple tags then you need to have a quote around the tags--tags='@run and @done'
If you want to run scenarios with one tag OR another then --tags='@run or @done'
And if you don’t want to run scenarios with a particular tag then --tags='not @done and @run'
Other flags:
step_definitions
So what if your step_definitions
folder isn’t going to sit inside the feature
folder? You can set the-r
flag, with the folder name so then CucumberJS will know to look for your step_definitions
folder elsewhere:
-r step_definitions
results.json
To generate a html or xml report, you need the results in a format that can be consumed by the plugin, such as JSON. You can do this by setting the -f
flag, if you want it to go to a specific location you can specify that too:
-f json:output/results.json
Run progress:
This will display the progress of your test with a ‘.’ for each step, by using the flag:
-f progress
example:
But what if you wanted to see the steps, then there’s a pretty formatter plugin cucumber-pretty
that can be used:
-f ./node_modules/cucumber-pretty
Run tests in parallel
How about running cucumber tests in parallel? With later versions of CucumberJS they have a new experimental feature to easily allow for parallel runs — all that is required is to add a --parallel <NUMBER_OF_WORKERS>
flag eg. --parallel 2
will run tests in parallel with 2 workers.
Reporting
There are many options available to generate different types of reports, a few examples are html and xml, as discussed below.
html reports
To generate the html reports we’re using the custom-cucumber-report-generator, which is a wrapper around cucumber-html-reporter that allows for flags to be set. The parameters that will be set for this report can be found in the config/properties.json
Information about the current run, such as browser, test environment, platform can be added in the support/hooks.js
To generate a html report you need to supply the results.json
and the report-config.json
:
./node_modules/.bin/custom-cucumber-report-generator -f output/results.json -i output/report-config.json
xml reports
When it comes to working with a CI tool such as bamboo/jenkins, to correctly report the result of the test run the results need to be in an xml format — more specifically junit xml. To generate the junit xml required, I’ve used another plugin cucumber-junit
To convert our JSON result file into junit xml, you just need to run something like this:
cat output/results.json | ./node_modules/.bin/cucumber-junit > output/report/results.xml
- Launch the browser
So, how do we start the test — where do we launch the browser? That’s all within the hooks file (support/hooks.js
)
So in the BeforeAll
hook, we’ll set up the connection to puppeteer and launch the browser
Set the Before hook to set the scope.page
Then from a step definitions we can refer to the scope object to get Puppeteer to interact with the browser
2. Capture Screenshots
Capturing screenshots is really useful, especially when you want to diagnose failures in your tests.
What I’ve setup, is to take a screenshot when a failure occurs and also at the end of each scenario using Puppeteer and then attach it to the cucumber step. Again, this is in the hooks file (support/hooks.js
). This time it’s the After
hook. So after each scenario has been run — a screenshot is to take: