There is no official gherkin
support available for Cypress, but there are nice libraries that add support for using feature files when testing with Cypress. Among them, we’re using cypress-cucumber-preprocessor
in our project for automation testing.
To get started in Cypress with cucumber preprocessor, follow these simple steps:
Installation
npm install --save-dev cypress-cucumber-preprocessor
Cypress Configuration
Add it to your plugins cypress/plugins/index.js
:
const cucumber = require('cypress-cucumber-preprocessor').default
module.exports = (on, config) => {
on('file:preprocessor', cucumber())
}
Add support for feature files to your Cypress configuration cypress.json
{
"testFiles": "**/*.feature"
}
Pre-processor Configuration
It lets you define the path to a folder containing step definitions required for your tests.
Where to define? 🤔
You can use cosmiconfig which helps to search for and loading configuration for your program. Or you can configure simply by adding this to your package.json
.
{
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
}
}
Available Configurations
OPTION | DEFAULT | DESCRIPTION |
---|---|---|
commonPath |
cypress/integration/common when nonGlobalStepDefinitions is truecypress/support/step_definitions when nonGlobalStepDefinitions is false${nonGlobalStepBaseDir}/common when nonGlobalStepBaseDir is defined |
define the path to a folder containing all common step definitions of your tests. |
nonGlobalStepDefinitions |
false |
If true use the Cypress Cucumber Preprocessor Style pattern for placing step definitions files. |
nonGlobalStepBaseDir |
undefined |
If defined and nonGlobalStepDefinitions is also true then step definition searches for folders with the features name will start from the directory provided here. |
stepDefinitions |
cypress/integration when nonGlobalStepDefinitions is truecypress/support/step_definitions when nonGlobalStepDefinitions is false |
Path to the folder containing our step definitions. |
Organize Tests
Single feature files
After adding .feature
support in cypress configuration, you can add feature files in cypress/integration/
You can easily integrate Background
, Scenario Outlines
, DataTables
within a feature file.
Bundled feature files
When running Cypress tests in the headless mode, the execution time can get pretty bloated, this happens because by default Cypress will relaunch the browser between every feature file. The cypress-cucumber-preprocessor gives you the option to bundle all feature files before running the tests, therefore reducing the execution time.
You can take advantage of this by creating .features
files. You choose to have only one in the root of the directory cypress/integrations
or per directory.
Adding support for .features
files to your Cypress configuration
cypress.json
{
"testFiles": "**/*.{feature,features}"
}
Step Definitions
The steps in the .feature
file look for their implementation inside a directory configured from preprocessor configuration. Step definitions files are by default in: cypress/support/step_definitions
. If you want to put them somewhere else please use cosmiconfig
format. For example, add to your package.json
.
{
"cypress-cucumber-preprocessor": {
"step_definitions": "cypress/support/step_definitions/"
}
}
An example of some step definitions done in the cypress way is as follows:
import { Given, Then } from "cypress-cucumber-preprocessor/steps";
const url = 'https://google.com'
Given('I open Google page', () => {
cy.visit(url)
})
Then(`I see {string} in the title`, (title) => {
cy.title().should('include', title)
})
Before and After hooks
The cypress-cucumber-preprocessor supports both Mocha’s before/beforeEach/after/afterEach
hooks and Cucumber’s Before
and After
hooks.
The cucumber hooks implementation fully supports tagging as described in the cucumberJs
documentation. So they can be conditionally selected based on the tags applied to the Scenario. This is not possible with Mocha hooks.
Example:
const { Before, After, Given, Then }
= require("cypress-cucumber-preprocessor/steps");
// this will get called before each scenario
Before(() => {
beforeCounter += 1;
beforeWithTagCounter = 0;
});
// this will only get called before scenarios tagged with @foo
Before({ tags: "@foo" }, () => {
beforeWithTagCounter += 1;
});
Given("My Step Definition", () => {
// ...test code here
})
Note: to avoid confusion with the similarly named Mocha
before
andafter
hooks, the Cucumber hooks are not exported onto the global scope. So they need explicit importing as shown above.
Smart Tagging
Start your tests without setting any tags and then put a @focus on the scenario (or scenarios) you want to focus on while developing or bug fixing.
Feature: Smart Tagging
As a cucumber cypress plugin which handles Tags
I want to allow people to select tests to run if focused
So they can work more efficiently and have a shorter feedback loop
Scenario: This scenario should not run if @focus is on another scenario
Then this unfocused scenario should not run
@focus
Scenario: This scenario is focused and should run
Then this focused scenario should run
@this-tag-affects-nothing
Scenario: This scenario should also not run
Then this unfocused scenario should not run
@focus
Scenario: This scenario is also focused and also should run
Then this focused scenario should run
Run tests
Run your Cypress Launcher the way you would usually do.
yarn run cypress open
Then click on a .feature
file on the list of specs, and see the magic happening!
- Running tagged tests
./node_modules/.bin/cypress-tags run -e TAGS='not @foo and (@bar or @zap)'
- Limiting to a subset of feature files
./node_modules/.bin/cypress-tags run -e GLOB='cypress/integration/**/*.feature'
You can also configure these from cypress configuration env
property with TAGS
sub-property.
{
"env": {
"TAGS": "not @ignore"
},
//rest of configuration options
"baseUrl": "yourBaseUrl",
"ignoreTestFiles": "*.js"
//etc
}
What's next
Cool! 😎 I’m sure this will get you started with cypress running your test in the Gherkin theme. Throughout the series, I've discussed E2E testing with Cypress, but in the next part of the series, we will be comparing cypress with other e2e testing frameworks. Till then, bye-bye, sayonara
Top comments (5)
Have they figured out a way to switch between multiple browser tabs yet?
There are a ton of e2e scenarios which involve switching between browser tabs, such as SSO, 2FA, checking emails, checking external links, etc.
Cypress does not and may never have multi-tab support for various reasons. Multiple tabs work against the way Cypress automates your application and they are inherently flaky and inconsistent - even if we did find a way to support them. You can look here to look at what Cypress has to say about it. Luckily there are lots of easy and safe workarounds that enable you to test the behavior of your application. This repo contains some examples for links opening new tabs.
Working with multiple tabs is flaky and inconsistent?
I don't think that is true.
Selenium can do that without any issue.
Browser tabs are browser tabs, they don't appear and disappear in a random way.
Even if your anchor element has the correct attributes, simply checking the existence and values of those attributes does not make up for the lack of an actual test.
That's just my opinion.
I noticed that all your articles are about Cypress.
Do you work for them or have they offered you any incentive to write positive things about them?
I think it's important that you should mention that.
If you're using Cypress as a test framework and you've managed to navigate to multiple tabs -- then the tests would surely go flaky and inconsistent because of Cypress architecture. I would highly recommend frameworks like
Nightwatch
,CodeceptJS
,Behat
,Behave
which works together with selenium if you want to test multiple tabs web UI interactions.P.S. I'm a QA developer and like to write about the tools I'm familiar with. 😊
Happy Coding!
To get around navigating to another page based on a clicked link, use:
cy.get(selectors.productNameTitle)
.invoke('attr', 'href')
.then((href) => cy.visit(href));
Cypress has said they will never support multi-tab testing but do have some workarounds listed here: github.com/cypress-io/cypress-exam...