Skip to content

Instantly share code, notes, and snippets.

@rahulpnath
Last active April 27, 2022 15:16
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save rahulpnath/4362ff2226ea36e056784f92c0d64434 to your computer and use it in GitHub Desktop.
Cypress Azure AD Login
// In cypress/plugins folder
const puppeteer = require('puppeteer');
module.exports = {
debuggingPort: '',
setDebuggingPortMyService(port) {
[, debuggingPort] = port;
return null;
},
async aadLogin(options = {}) {
const username = options.username;
const password = options.password;
const appUrl = options.appUrl;
const emailSelector = "[name='loginfmt']";
const passwordSelector = '[name=passwd]';
const submitButtonSelector = 'input[type=submit]';
const browser = await puppeteer.connect({
browserURL: `http://localhost:${debuggingPort}`,
});
const page = await browser.newPage();
await page.goto(appUrl);
await page.waitForNavigation();
if (page.url().startsWith(appUrl)) {
// already logged in
page.close();
return {};
}
await page.waitForSelector(emailSelector);
await page.type(emailSelector, username);
await page.keyboard.press('Enter');
await page.waitForNavigation();
await page.waitForSelector(passwordSelector);
await page.focus(passwordSelector);
await page.waitFor(1000);
await page.type(passwordSelector, password);
await page.click(submitButtonSelector);
await page.waitForNavigation();
await page.waitForSelector(submitButtonSelector);
await page.click(submitButtonSelector);
await page.waitForNavigation();
await page.waitFor(2000);
await page.close();
return {};
},
};
// In cypress/plugins folder
const { setDebuggingPortMyService, aadLogin } = require('./aadLogin');
module.exports = (on, config) => {
// // `on` is used to hook into various events Cypress emits
// // `config` is the resolved Cypress config
on('before:browser:launch', (browser = {}, args) => {
const existing = args.args.find(arg => arg.slice(0, 23) === '--remote-debugging-port');
// Here you will need to persist the port to your plugins, whatever they may be
setDebuggingPortMyService(existing.split('='));
return args;
});
on('task', { aadLogin });
};
@devsrihari4
Copy link

@rahulpnath, I am new to Cypress and I am trying to log into my application. Below are the steps manually to log in but I am unable to automate with Cypress.

These are manual steps to login

  1. Open the application and click on the login button which will redirect to identity server api
  2. Again click on login on the redirected site then it redirects to login.Microsoftonline.com and asks for credentials.
  3. Once credentials are verified it redirects to my application.

@Coding-Means-Always-Learning

@rahulpnath, I am new to Cypress and I am trying to log into my application. Below are the steps manually to log in but I am unable to automate with Cypress.

These are manual steps to login

  1. Open the application and click on the login button which will redirect to identity server api
  2. Again click on login on the redirected site then it redirects to login.Microsoftonline.com and asks for credentials.
  3. Once credentials are verified it redirects to my application.

Hi @devsrihari4,
I guess this should be possible by using puppeteer code suggested previously.

You need to identify which is the important cookie that will let the application know its the same user trying to login in again

You may want to do Step 1, 2 and 3 using puppeteer browser and once you are in the application you can return the cookies to cypress and save it and use it to login into the application

@appdirectorsantosh
Copy link

Thanks @rahulpnath for share this. I am could run with chrome from UI and headless both.
Its failing with electron.

Cannot read property 'split' of undefined
TypeError: Cannot read property 'split' of undefined

Was any able to run this in electron?

@manoj-mukherjee-maersk
Copy link

I am having after successfully get cookie when I set that in cypress. Again Azure AD login screen opening in cypress test runner. Any idea what need to do? I able to see cookie is set but Why Azure AD again running.

cookies.forEach((cookie) => {
      if (cookie) {
        cy.setCookie(cookie.name, cookie.value, {
          domain: cookie.domain,
          expiry: cookie.expires,
          httpOnly: cookie.httpOnly,
          path: cookie.path,
          secure: false,
          sameSite: "lax",
        });
        Cypress.Cookies.defaults({ preserve: cookieName });
      }
    });

@Coding-Means-Always-Learning

I am having after successfully get cookie when I set that in cypress. Again Azure AD login screen opening in cypress test runner. Any idea what need to do? I able to see cookie is set but Why Azure AD again running.

cookies.forEach((cookie) => {
      if (cookie) {
        cy.setCookie(cookie.name, cookie.value, {
          domain: cookie.domain,
          expiry: cookie.expires,
          httpOnly: cookie.httpOnly,
          path: cookie.path,
          secure: false,
          sameSite: "lax",
        });
        Cypress.Cookies.defaults({ preserve: cookieName });
      }
    });

Hello @manoj-mukherjee-maersk ,
I did have the same challenge. I overcome this by not accessing / visiting the same url which takes to Azure AD login screen.
Once you have saved the cookies that you get from the plugin code , In my cypress test I visit the homepage url which is different to the base url of the application and since the cookies are saved cypress happily navigates to home page of the application

@manoj-mukherjee-maersk
Copy link

Hi @Coding-Means-Always-Learning I tried to visit -> cy.visit("/dashboard"). In puppeteer login page tried to visit root of the app "/". My Every page are Auth protected. What did I am wrong here?

@manoj-mukherjee-maersk
Copy link

FYI: able to solve the issue by using only puppeteer.connect and debuggingport. Earlier when using puppeteer.launch its open another browser and from that cookies are set which cause again azure sso login. Not able to figure out why cypress remove when cookies from another browser instance.

@MelvBa
Copy link

MelvBa commented Apr 26, 2022

According to the cypress changelog of V9.6.0 they have now implemented an experimental command which should allow us to easier test applications with for example Azure AD login screen. Look at the experimental command cy.origin(). Maybe this one solves a lot of the problems we had to work around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment