Cross browser testing ensures a web application works consistently across different browsers, versions, and devices. Cucumber, a popular BDD (Behavior-Driven Development) tool, helps automate cross-browser tests using Gherkin syntax for readable test scenarios.
Overview
Why choose Cucumber for Cross-Browser Testing?
- Readable & Maintainable Tests: Uses natural language (Gherkin) for easy test creation.
- Seamless Integration: Works with Selenium, Appium, and cloud platforms like BrowserStack for broad browser coverage.
- Parallel Execution: Enables faster testing across multiple browsers.
- CI/CD Support: Easily integrates with Jenkins, GitHub Actions, and other CI/CD tools.
How to Perform Cross-Browser Testing with Cucumber
- Install Cypress: Set up Cypress for test automation.
- Create a Folder Structure: Organize feature files, step definitions, and test classes.
- Create Feature Files: Write test scenarios in Gherkin syntax.
- LoginTest.feature: Validates user login functionality across browsers.
- SearchTest.feature: Tests search functionality across different environments.
- Create Page Class: Implement reusable page objects for browser interactions.
- Create Test Class: Define test execution logic, integrating with Selenium or cloud-based platforms like BrowserStack Automate for real browser testing.
By integrating Cucumber with frameworks like Selenium, Cypress and cloud-based platforms like BrowserStack, teams can efficiently execute tests across multiple browsers, ensuring a seamless user experience for all.
Introduction to Cucumber and BDD
Cucumber is a testing tool that supports behavior-driven development (BDD). BDD bridges 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 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
Below are the steps to install 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 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" }
Introduction to 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
Here are some code examples of how to create Feature files:
LoginTest.feature
In the first test case, the test case is to login with the valid and invalid user
Write the below code under the LoginTest.feature file
Feature: I want to login into the site with valid and invalid data Background: Given I navigate to the Website @SmokeTest Scenario: Login as new sign up user with valid data : QA-135,QA-156 When I entered valid credential | email | validpassword | | qatubeupdate@yopmail.com | 12345 | When User click on sign in button Then Validate the title after login @SanityTest Scenario: Login with invalid data by entering invalid password : QA-56,QA-156 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
The second test case searches for a T-shirt. Write the below code under the SearchTest.feature file
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
Create loginPage.js class to cover login with valid/ invalid user scenario
Creating Methods for enterUrl,enterUserNamePassword,clickOnSignInButton and validateErrorMessage() to 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;
validateErrorMessage() method to verify the error message when the user enters an invalid username and password.
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;
Creating the validateSearchResult() method to enter the search result and creating the clickOnSearchButton() method to click on the search button
Create Test Class
Create loginTest.spec.js class to cover scenario login with valid / invalid user
Note: When making test class “Given”, “When” and “Then” mapping should be the same as done in irrespective feature file
import login from "../../Pages/LoginPage/loginPage"; // Scenario 1 : Login with Valid credential Given("I navigate to the Website", () => { cy.visit("http://automationpractice.com/"); }); When("I entered valid credential", (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 credential and Verify error messsage When("I entered invalid credential", (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); }); });
Conclusion
Executing the Cucumber framework on real browsers gives accurate results. Use BrowserStack Automate to run your Cypress tests on an extensive list of browsers and mobile devices, with support for CI and Local Testing.
BrowserStack allows you to test your apps and websites on the older and latest browser versions of IE, Chrome, Firefox, etc for accurate cross browser testing and helps detect bugs and test in real user conditions.