Before we start on E2E test writing using cypress, let’s know the cpress.
What is Cypress?
Cypress is a next-generation front-end testing tool built for modern web applications. In short, it enables any browser-based web application to write unit, integration, or end-to-end tests.
Cypress also has a companion product to record your test runs and make it available anywhere anytime with Cypress Cloud enterprise application.
Here in this article, we will learn to setup the E2E project for our web based application.
Installing Cypress
First we need to setup cypress and we can do it as explained on the link below based on your OS enviornment.
Seamless Cypress Installation Guide | Cypress Documentation
After you are done with installing, you will see a basic structure added in your designated location with some config files and a folder called ‘cypress/e2e’ under which we will be writing E2E tests.
From here, we will certain changes to organize our structure by following some best practices for our E2E test coverage.
- Run your tests always in incognito mode to avoid browser’s cached data and to do this, we need add the following setting in the ‘cypress.config.js’ file available in your base project location (where cypress folder is created). * if the file is not created then add it.
`const { defineConfig } = require("cypress");
const cucumber = require('cypress-cucumber-preprocessor').default
const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
const preprocessor = require("@badeball/cypress-cucumber-preprocessor");
const createEsbuildPlugin = require("@badeball/cypress-cucumber-preprocessor/esbuild");
const setupNodeEvents = async (on, config) => {
on("before:browser:launch", (browser = {}, launchOptions) => {
if (browser.family === 'chromium' && browser.name !== 'electron') {
launchOptions.args.push("--incognito");
return launchOptions;
}
if (browser.name === 'electron') {
launchOptions.preferences.incognito = true;
return launchOptions;
}
});
await preprocessor.addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin.default(config)],
}),
);
return config;
};
2. Add the below setting to avoid issues with Microsoft SSO login in the config file after the above code.
module.exports = defineConfig({
viewportWidth: 1920,
viewportHeight: 1080,
defaultCommandTimeout: 20000,
chromeWebSecurity: false,
fixturesFolder: false,
video: true,
e2e: {
projectId: "mywebapp",
hideXHRInCommandLog: true,
//to avoid "Infinite redirection - iframe-request-id" issue with Azure AD SSO login issue in cypress
experimentalSessionAndOrigin: true,
experimentalModifyObstructiveThirdPartyCode : true,
setupNodeEvents,
specPattern: "**/*.feature",
excludeSpecPattern: ["*.js"],
}
});
To know more about this go through my previous article here as: https://binodmahto.blogspot.com/2024/03/infinite-redirection-iframe-request-id.html
3. To avoid hardcoding any sensitive or common values required for tests, add an environment config file in the base folder (where cypress.config.js is there) as ‘cypress.env.json’.
{
"web_url": "https://mywebapp.com",
"username":"*****",
"password":"*****"
}
4. Add all your E2E test scenarios by creating *.feature file inside cypress/e2e/features. For example, I’m adding a file as home.feature with the below code.
Feature: Welcome User Test
@smoke
Scenario: verify if user is successfully able to login
Given User logs in through azure ad sso
Then User can view the welcome home page
Based on the above code, basically, I created a test scenario where a user will be able to log in to my web application with Microsoft SSO login and then be redirected to the welcome home page after successful login.
Note: What you mentioned in Given and Then is your test steps and the cypress will look for the exact match of these defined steps here in all the step definitions files in crpress/e2e/step_definitions folder by scanning through all *.cy.ts files here.
5. Add/create step definitions files. Based on above steps our test sceanrio has two steps as given and then so lets create fisrt step definition file for login as ssologinpage.cy.ts inside crpress/e2e/step_definitions folder with below code.
import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
Given("User logs in through azure ad sso", () => {
try{
cy.visit(Cypress.env('web_url'));
cy.origin('login.microsoftonline.com', () => {
cy.get('input[type="email"]').type(Cypress.env('username'));
cy.get('input[type="submit"]').click();
cy.get('input[type="password"]').type(Cypress.env('password'), {
log: false,
});
cy.get('input[type="submit"]').click();
cy.get('#idBtn_Back').click();
});
}
catch(exception){
throw new SyntaxError( "Failed to login",);
}
});
Above code define the script for login steps where SSO login will be performed using configure user credentials in cypress.env.json file.
Note: If your application uses your custom login form then change the code here accordingly.
6. Next add the step for Then steps for welcome home vaildation as homepage.cy.ts inside crpress/e2e/step_definitions folder with below code.
import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
Then("User can view the welcome home page", () => {
try{
//Validate Title
cy.get('.page-title').contains('Welcome User');
}
catch(exception)
{
throw new SyntaxError(
"Homepage details not displayed",
);
}
});
7. cypress.env.json file has been created as best practice to separate environment specific variables and to avoid repetitive common values hence it is must to add this file in .gitignore file to avoid any push for this file by any user.
As a result, your folder structure will look like this:
8. Now to run your tests, type the below command in your VS terminal window as
npx cypress open
The above command will open the Cypress tool, which help you to execute your tests.
Bonus
Automate this through the GitHub Action pipeline and integrate it with Cypress Cloud.
Before we start the pipeline you need to acquire Cypress cloud, please follow this link to acquire the Cypress record key.
Here are the steps we need to write in the pipeline based on the above cypress example mentioned in this article.
Step 1: Replace or de-tokenize the setting from cypress.env.json.
- name: Cypress env Settings Variable Substitution
uses: microsoft/variable-substitution@v1
with:
files: "**/cypress.env.json"
env:
web_url: ${{ secrets.WEBAPPLICATION_URL }}
username: ${{ secrets.AutomationTestUserName}}
password: ${{ secrets.AutomationTestUserPassword}}
Step 2: Install project dependencies.
- name: npm login & Install
shell: bash
run: |
npm install --legacy-peer-deps
working-directory: uitests
Step 3: Finally, run cypress tests with the cypress record key.
- name: Running E2E tests on Chrome
shell: bash
run: |
npx cypress run --record --key ${{ secrets.CypressRecordKey }}
working-directory: uitests
and with this pipeline execution, your results will be on the Cypress cloud dashboard.
Hope you enjoyed the content, follow me for more like this, and please don’t forget to like it. Happy programming.