Wednesday, 20 March 2024

“Infinite redirection — iframe-request-id” issue with Azure AD SSO login issue in cypress

 Recently I chose Cypress as E2E testing tool after evaluating some other open-source tools for my web application project. All was good by theory until I started the test scripting and encountered the error “Infinite redirection — iframe-request-id” with Azure SSO login, it took me a day with a lot of reading to figure out the workable solution which I’ll explain down here.

In my case, the scenario was, that I had a test AD user for which MFA was disabled and needed to the scenario for user from login with Azure AD SSO to lending to my web application.

When I started with cy.visit(‘www.myapp.com’) for which Azure AD SSO was configured to auto rediect to the Microsoft https://login.microsoftonline.com page, ended up with mentioned error. What was actually happening here is, the https://login.microsoftonline.com url was getting suffixed with iframe-request-id indefinite times and url was getting too long. While searching through the Google I came to know the issue was even discussed in cypress github forum: https://github.com/cypress-io/cypress/issues/7619

I also got recommendations from my colleague or even google to bypass the login step by configuring the users for auto login but that was not solving my need neither I try it.

Surprisingly, reading more patiently I found the solution which was very easy and quick. The solution is to configure experimentalSessionAndOrigin and experimentalModifyObstructiveThirdPartyCode variables to true in your cypress.config.js file as

module.exports = defineConfig({
viewportWidth: 1920,
viewportHeight: 1080,
defaultCommandTimeout: 20000,
chromeWebSecurity: false,
fixturesFolder: false,
video: true,


e2e: {
projectId: "mywebapp",
hideXHRInCommandLog: true,

experimentalSessionAndOrigin: true,
experimentalModifyObstructiveThirdPartyCode : true,

setupNodeEvents,
specPattern: "**/*.feature",
excludeSpecPattern: ["*.js"],
},
integration:{

experimentalSessionAndOrigin: true,
experimentalModifyObstructiveThirdPartyCode : true,

specPattern:"**/*.spec.js",
projectId: "mywebapp",
}
});

and next step, do the setting to run your tests always in incognito mode so the cached ad token will not be picked and the test workflow will execute as expected.
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;
}

});

Here is the complete cypress.config.js file

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;
};



module.exports = defineConfig({
viewportWidth: 1920,
viewportHeight: 1080,
defaultCommandTimeout: 20000,
chromeWebSecurity: false,
fixturesFolder: false,
video: true,


e2e: {
projectId: "mywebapp",
hideXHRInCommandLog: true,
experimentalSessionAndOrigin: true,
experimentalModifyObstructiveThirdPartyCode : true,
setupNodeEvents,
specPattern: "**/*.feature",
excludeSpecPattern: ["*.js"],
},
integration:{
experimentalSessionAndOrigin: true,
experimentalModifyObstructiveThirdPartyCode : true,
specPattern:"**/*.spec.js",
projectId: "mywebapp",
}
});

and here is my test script:

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",);
}
});

Hope you enjoyed the content and it helped you if you are coming across the same issue, follow me for more like this, and please don’t forget to like it. Happy programming.

No comments:

Post a Comment