Cross Browser Testing Using Cypress, Cucumber and BrowserStack

KailashPathak
10 min readSep 12, 2022

--

This blog was originally published at https://www.browserstack.com/guide/cross-browser-testing-using-cucumber

By Kailash Pathak

What is Cross Browser Testing?

Cross Browser Testing is functional testing that makes sure that your web application works as expected on different platforms and browsers

We certainly want to ensure that all web components in the site should render smoothly across all targeted platforms and browser versions.

We can do testing across multiple platforms with different browsers manually and in automated ways.

Cross Browser Automation Testing using BrowserStack and Cucumber

Here we are using Cypress with Cucumber and for running the test case across the different browsers we are using BrowserStack

What is BrowserStack

BrowserStack is the testing platform, to test the websites and mobile applications. We can test a web application in multiple browsers and mobile applications on most mobile devices.

In a real scenario, it’s very difficult to test an application on different platforms using multiple browsers, with varied versions.

What Is Cucumber and BDD?

Cucumber is a testing tool that supports behavior-driven development (BDD).

BDD aqueduct the space between business stakeholders and the technical team through a common platform and communication among the team becomes more transparent.

Gherkin language is used to write the test cases in a very simple format and can also be read and modified by a non-technical user.

In BDD, “Given-When-Then” is the suggestive approach for writing test cases.

Here is an example for better understanding:

Given user has entered valid credentials

When a user clicks on the sign-in button

Then validate the content on the home page after login

Installing Cucumber

Step 1: To install cucumber run this command

run > npm install — save-dev cypress-cucumber-preprocessor

Once installed, Cucumber devDependency in package.json can be seen as below

Step 2: Add below code snippet in cypress > plugins > index.js

const cucumber = require("cypress-cucumber-preprocessor").default;
module.exports = (on, config) => {
on("file:preprocessor", cucumber());
};

Step 3: Add the below code snippet in package.json

"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
}

Step 4: Add the below line in cypress.json

{
"testFiles": "**/*.feature"
}

What is Cypress

Cypress framework is a JavaScript-based end-to-end testing framework built on top of Mocha. it uses a BDD/TDD assertion library and a browser to pair with any JavaScript testing framework.

We can use Cypress for End-to-end tests, Integration tests, and Unit tests.

Installing Cypress

Cypress installation steps

Step 1: Create a folder and Generate package.json

  • Create a project, here naming it as cypress_cucumber_updated
  • Use the npm init command to create a package.json file

Step 2: Install Cypress

To install Cypress, still, in the project folder, run > npm install cypress –save-dev

Once installed, Cypress version 9.7.0 is reflected as seen below

Create a Folder Structure

Create Folders structure for Test Cases

Step 1: Create folder “BrowserStack” Integration → BrowserStack. Under BrowserStack create further two folders with the names Tests and Pages

Step 2

Create two subfolders Under Tests and Page i.e Pages -> LoginPage ,SearchPage and Tests- > LoginTest,SearchTest

Step 3

Now Create Feature files (LoginTest.feature,SearchTest.feature)

Create Feature files

LoginTest.feature

In the first test case, we want to login with the valid and invalid user

Write the below code under the LoginTest.feature file attached below

Feature: I want to login into the site with valid and invalid data and search T-shirt
Background:
Given I navigate to the Website
Scenario: Login as new sign up user with valid data
When I entered valid credential
| email | validpassword |
| qatubeupdate@yopmail.com | 12345 |
When User click on sign in button
Then Validate the title after login
Scenario: Login as new sign up user with invalid data
When I entered invalid credential
| email | invalidpassword |
| qatubeupdate@yopmail.com | 123456 |
When User click on sign in button
Then Error message should display
| errormessage |
| Authentication failed |

SearchTest.feature

In the second test case, we want to search for a T-shirt

Write the below code under the SearchTest.feature file attached below

Feature: I want to login into the site with valid and invalid data and search T-shirt
Background:
Given I navigate to the Website
Scenario: Login as new sign up user with valid data
When I entered valid credential
| email | validpassword |
| qatubeupdate@yopmail.com | 12345 |
When User click on sign in button
Scenario: Search T-shirts from the site
When I entered the search criteria
| serachtext |
| T-shirts |
And Click on serach button
Then Validate the T-shirt name
| tshirtName |
| Faded Short Sleeve T-shirts |

Create Page Class

We have created our feature file above now we need to create our page classes

Create loginPage.js class to cover login with valid/ invalid user scenario

Here we created Methods for enterUrl,enterUserNamePassword,clickOnSignInButton and validateErrorMessage() and we have exported the login object.

We will use these methods in our page class

/// <reference types ="cypress"/>
class LoginPage {
enterURL() {
cy.visit("http://automationpractice.com/");
}
enterUserNamePassword(username, password) {
cy.contains("Sign in").click();
cy.get("#email").clear();
cy.get("#email").type(username);
cy.get("#passwd").clear();
cy.get("#passwd").type(password);
return this;
}
searchItem(searchItem, searchresult) {
cy.get("#searchbox").type(searchItem);
cy.get('[name="submit_search"]').click();
cy.contains(searchresult);
return this;
}
clickOnSignInButton() {
return cy.get("#SubmitLogin").click();
}
verifyPageTitle() {
return cy.title().should("eq", "My account - My Store");
}
validateErrorMessage(errorMessage) {
return cy.contains(errorMessage);
}
}
const login = new LoginPage();
export default login;

In line #4 we have created the enterUrl() method to enter the site URL, In line #7 we have created the enterUserNamePassword() method to enter the username and password on the login screen

In line #15 we have created clickOnSignInButton() method to click on Sign-in btton ,In line #18 we have created verifyPageTitle() method to verify page title after login

In the line #21, we have created the validateErrorMessage() method to verify the error message when the user enters an invalid username and password,

In line #26 we are creating the object of login (*After this we need not create the object in the test class) and in #27 We are just exporting the object.

Create a searchPage.js class to search the product (T-shirt)

/// <reference types ="cypress"/>
class SearchPage {
validateSearchResult(searchResult) {
return cy.contains(searchResult);
}
clickOnSearchbutton() {
return cy.get('[name="submit_search"]').click();
}
}
const search = new SearchPage();
export default search;

In line #4 we have created the validateSearchResult() method to enter the search result and In line #7 we have created the clickOnSearchButton() method to click on the search button

In line #11 we are creating the object of the homepage (*After this, we need not create the object in the test class)

Create Test Class

We have already created methods in our page class now we will use these methods in our Test class. Create loginTest.spec.js class to cover scenario login with valid/ invalid user

**NOTE: We have to make sure when we make our test class “Given”, “When” and “Then” mapping should be the same as we have given irrespective feature file

import login from "../../Pages/LoginPage/loginPage";
// Scenario 1 : Login with Valid crediential
Given("I navigate to the Website", () => {
cy.visit("http://automationpractice.com/");
});
When("I entered valid crediential", (datatable) => {
datatable.hashes().forEach((element) => {
login.enterUserNamePassword(element.email, element.validpassword);
});
});
When("User click on sign in button", () => {
login.clickOnSignInButton();
});
Then("Validate the title after login", () => {
login.verifyPageTitle();
});
// Scenario 2 : Login with Invalid crediential and Verify error messsage
When("I entered invalid crediential", (datatable) => {
datatable.hashes().forEach((element) => {
login.enterUserNamePassword(element.email, element.invalidpassword);
});
});
When("User click on sign in button", () => {
login.clickOnSignInButton();
});
Then("Error message should display", (datatable) => {
datatable.hashes().forEach((element) => {
login.validateErrorMessage(element.errormessage);
});
});

Create searchTest.spec.js class to search the product

import login from "../../Pages/LoginPage/loginPage";
import search from "../../Pages/SearchPage/searchPage";
// Scenario 1 : Login with Valid crediential
Given("I navigate to the Website", () => {
cy.visit("http://automationpractice.com/");
});
When("I entered valid crediential", (datatable) => {
datatable.hashes().forEach((element) => {
login.enterUserNamePassword(element.email, element.validpassword);
});
});
When("User click on sign in button", () => {
login.clickOnSignInButton();
});
// Scenario 2 : Do Search
When("I entered the search criteria", (datatable) => {
datatable.hashes().forEach((element) => {
cy.get("#searchbox").type(element.serachtext);
});
});
And("Click on serach button", () => {
search.clickOnSearchbutton();
});
Then("Validate the T-shirt name", (datatable) => {
datatable.hashes().forEach((element) => {
search.validateSearchResult(element.tshirtName);
});
});

Step Up BrowserStack

We have created feature files for test cases and also created our page and test class. Now next step is to run test cases in BrowserStack. But before that, we have to set up BrowserStack. Here are few steps

Step 1 Install the CLI

Install the BrowserStack using the Cypress CLI command via npm.

browserStack — Cypress CLI is a command-line tool that is used to enable communication between Cypress and BrowserStack

Run the command in the terminal

npm install -g browserstack-cypress-cli

We can see CLI is installed

Step 2 Generate browserstack.json

Under the root folder configures the browsers that we want to run the tests. Use the init command to generate the browserstack.json file, or alternatively create one from scratch.

Use the below command

browserstack-cypress init

In generated browserstack.json file pass the below information Fill in the auth, browsers, and run_settings values in the browserstack.json file to be able to run your tests

In auth, we will pass our BrowserStack ACCESS Key (See Below)

In the browsers Section line #6, we just add the Browser on which we want to execute our Cucumber test cases and in run_setting we will give the cypress config file path and other settings.

In line #22 parallels: 2 mean our test case parallelly run in TWO browsers

{
"auth": {
"username": "",
"access_key": ""
},
"browsers": [
{
"browser": "chrome",
"os": "Windows 10",
"versions": ["latest"]
},
{
"browser": "firefox",
"os": "OS X Mojave",
"versions": ["latest"]
}
],
"run_settings": {
"cypress_config_file": "./cypress.json",
"project_name": "Cypress Cucumber",
"build_name": "Cypress Cucumber Test",
"parallels": "2"
},
"connection_settings": {
"local": false,
"local_identifier": null,
"local_mode": null,
"local_config_file": null
},
"disable_usage_reporting": false
}

Step 3 Very Important step

To run the Cucumber test case in BrowserStack we have to do the below setting in the browserstack.json file otherwise cucumber test case will not run and throw an error

  • cypress-cucumber-preprocessor dependency in run_settings
  • Have to set “nonGlobalStepDefinitions“ : true
{
"auth": {
"username": "",
"access_key": ""
},
"browsers": [
{
"browser": "chrome",
"os": "Windows 10",
"versions": ["latest"]
},
{
"browser": "firefox",
"os": "OS X Mojave",
"versions": ["latest"]
}
],
"run_settings": {
"cypress_config_file": "./cypress.json",
"project_name": "Cypress Cucumber",
"build_name": "Cypress Cucumber Test",
"parallels": "2",
"npm_dependencies": {
"cypress-cucumber-preprocessor": "⁴.3.1"
},
"headless": true,
"package_config_options": {
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
}
}
},
"connection_settings": {
"local": false,
"local_identifier": null,
"local_mode": null,
"local_config_file": null
},
"disable_usage_reporting": false
}

Run Test Class In Cross-Browser

We have two test cases one for login and the other for searching the product. Let’s run the test case

In package.json we have the command to run Cucumber Test cases in BrowserStack

npm run cy:browserstack

Run the command in the terminal.

The test case starts running in the terminal also in BrowserStack. Open the Dashboard of BrowserStack and we can see test cases are running their

Report

In terminal

In the below screenshot we can see One test case is failing for the Firefox browser

In BrowserStack

In the below screenshot we can see both the test cases are running in two different browser

BrowserStack/Tests/LoginTest.feature

BrowserStack/Tests/SearchTest.feature

Failed Test Case

In case of the test case is fail in BrowserStack captured the Screenshots with log

☕️ Happy testing! ☕️

For more blogs please follow the below link

https://qaautomationlabs.com/blog/

--

--

KailashPathak
KailashPathak

Written by KailashPathak

Author of book "Web Automation Testing Using Playwright", is a certified PMI-ACP®, ITIL®, PRINCE2 Practitioner®, ISTQB, professional.

No responses yet