Cross Browser Testing Using Cypress, Cucumber and BrowserStack
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