Cypress with Cucumber

Knoldus Blog Audio
Reading Time: 5 minutes

Hi folks,

In this blog, we will learn how to have an integrated testing behaviour-driven framework with cypress. We will see how we can integrate cucumber with cypress. So, let’s get started.

Why to integrate cucumber with cypress?

There are multiple tools to have a BDD framework but the most used BDD tool is cucumber. BDD is a branch of Test Driven Development (TDD). It uses human-readable descriptions of software user requirements as the basis for software tests.

BDD approach helps us to define the tests in common or shared vocabulary between stakeholders, domain experts, and of course, the engineers involved. A simple given, when and then vocabulary helps to make our test more readable. And due to this reason, even a non-technical person can get an idea of the testing that is being carried out.

Let me give you an example so that you can get an idea of why BDD is simple to understand.

I’ve written a test where we are navigating through a site, and we are searching its blog section to search for cypress’s blogs. The screenshot below shows the test script for the same scenario, written as a regular javascript test in cypress.

With just one glance, one may assert that it will be difficult for a non-technical person to understand the test script. However, if we convert this to BDD standards, it will look much simpler and very much readable. As depicted in the screenshot below.

The screenshot above is the corresponding BDD code for the test script mentioned earlier. As you can see, the line of code reduced drastically. And it is much readable now.

I hope, now we know why to opt BDD framework. Moving on, let’s see how we can achieve this in cypress.

Steps to integrate cucumber with Cypress

To integrate cucumber we would have to make use of an external cypress-cucumber plugin in our project. Please follow the following steps to install and integrate the plugin.

  • Install the cucumber plugin by running the following command
npm install --save-dev cypress-cucumber-preprocessor

This will fetch the latest version of this plugin that is present on the npm.

  • After installing the plugin, add this code snippet in the index.js file under the plugins folder.
const cucumber = require('cypress-cucumber-preprocessor').default

module.exports = (on, config) => {
  on('file:preprocessor', cucumber())
}

This will make this plugin recognizable to cypress.

Until now, we were writing test in a file with .js extension. But with the introduction of cucumber thing changes, according to the cucumber standards, we would have to use .feature file to write the test cases. But cypress only recognises .js files until now, a question arises here that how are we going to run the test that we have written in feature file with gherkins syntax.

  • What we have to do is, we would have explicitly tell cypress to run the .feature file extension as well. For this, we have to add this line mentioned below in our cypress.json file.
{
  "testFiles": "**/*.feature"
}

Please note that this will make cypress ignore the .js extension in your test runner. If you want both the extension to be recognized by the cypress, add the following in your cypress.json file instead of the one mentioned above.

{
    "testFiles": "**/*.{feature,js}"
} 
  • After that, we also have to add the following in the package.json file.
"cypress-cucumber-preprocessor": {
  "nonGlobalStepDefinitions": true
}

This will help cypress to convert the mocha test to a feature file having gherkins syntax.

  • And lastly, we need to add an extension to our IDE so that it can recognise the .feauture extension. In our case, we have used Visual Code Studio. you can install the plugin in it by
    • pess ctrl+P
    • type ‘ext install alexkrechik.cucumberautocomplete’
    • press enter

And the cucumber extension will get configured for our IDE.

Converting test script in Gherkins syntax

For cypress, we can write our test in Javascript only. However, since we are using cucumber with cypress, we need to convert the Java Script test to Gherkins. Gherkins consist mainly of four main keywords, ‘Given’, ‘When’, ‘And’ and ‘Then’. In cypress, we are going to write our test in Javascipt and then we will link these Javascript test to these Gherkins keywords as a step definition. For example. consider a scenario we are simply visiting a website.

To visit a website in cypress, we use the cy.visit() command. A corresponding Gherkin command of this can be defined with the ‘Given’ keyword. We are going to link our cy.visit() command to the Given keyword of Gherkins.

To understand better, please have a look at the Ghekinks and JavaScript code below.

        Given We visit knoldus Website

We have to link this Given command to javaScript test, so that cypress can understand it.

Given("We visit knoldus Website", function(){  
cy.visit("https://www.knoldus.com/home")
})

Please note that the description given in the feature file with the Given keyword should be the same when defining the step definition. The corresponding JavaScript code of Gherkins should always be defined in .js file. And this step definition .js file should be placed in the folder having the identical name as of the feature file.

For example, if we a file Test1.feature for writing our BDD cucumber test then, the corresponding step definition javaScript file should be placed under the folder having the name Test1 only. I hope I was able to clear it out.

Implementation

The approach has defined already in the ealier section. To understand better, let’s have a look at the code snippets.

import { Given,When,Then, And } from "cypress-cucumber-preprocessor/steps"; // have to import these, so that cypress can recognise cucumber keywords

Given("We visit knoldus Website", function(){ // we can make an anonymus function as well here, use "()=>" instead of function() 
cy.visit("https://www.knoldus.com/home")
})

When("We click on blogs and search for cypress",()=>{
    cy.contains("Blog").invoke("removeAttr","target").click({force: true}) // using {force: true} as the element is being overlapped by some other webElement
    // we have used here, .invoke, it enables cypress to use jquery functions and to remove attribute we used removeAttr() which is a jquery function.
    cy.wait(1000)
    cy.get("#tophead > div > a").click() // to click on search option
    cy.wait(1000)
    cy.get("input[placeholder='Search …']").type("cypress{enter}") // to search for 'cypress' and then pressing enter.
})

And("Open the blog Cypress-101",function(){
    cy.contains("Cypress – 101").click() // to click on the desired blog
})

Then("assert",()=>{
    cy.url().should("include","https://blog.knoldus.com/cypress-101/") // to assert that we succesfully move to the redirected url
})

The code above is the step defination for the feature file mentioned below.

Feature: Sample feature file for the demo

    Here, you can add some description for the feature file. Please note that before moving to the next statement, press enter and then tab button. 
    
    Scenario: Knoldus Website
        Given We visit knoldus Website
        When We click on blogs and search for cypress
        And Open the blog Cypress-101
        Then assert

For your refrence, this is the folder structure that I’ve used.

In this project, we have a BDD folder under the default integration folder. Inside the BDD folder, we have a sampleTest.feature file where we have defined our test as per the cucumber standards. As mentioned earlier, the corresponding step defination definition file is under the sampleTest folder. The name of the feature file and the name of the folder that contains the step definition javaScript file should always be the same.

That’s all folks. I hope you may have found this usefiul. Thanks!

Techub Template Refrence

Refrences


Knoldus-blog-footer-image

Written by 

Sparsh is a QA Consultant having experience of more than 1.5 years. He is familiar with the core concepts of manual and automation, Karate, Cypress, Gatling, Rest Assured and Selenium are the tools that Sparsh is familiar with. He is always eager to learn new and advanced concepts in order to upskill himself.

Leave a Reply