Make sure to set maz-http-header-size like below since the AD token size is large
set NODE_OPTIONS=--max-http-header-size=120000&& npx cypress open
References:
Make sure to set maz-http-header-size like below since the AD token size is large
set NODE_OPTIONS=--max-http-header-size=120000&& npx cypress open
References:
// 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 }); | |
}; |
@WvdE Awesome, great you figured it out!
Hello,
I am also very interested in this. I am completelly new in cypress and I have this first challenge before being able to really learn cypress.
If you have the possibility to do a line by line how to, a small video or something I would really appreciate it.
Here is where I am currently (I am on windows). I have:
How do I set the debugging port? How could I debut the puppeteer script? I have try with debugger, with console.log, ... but I didn't see anything in the console. I have also tried to hardcode the port 9222 by using setDebuggingPortMyService(9222); it open a chome but I have the following message:
Failed to fetch browser webSocket url from http://localhost:9222/json/version: connect ECONNREFUSED 127.0.0.1:9222
You said that you needed to configure some stuffs how did you setup this?
Thank you
@VGBenjamin Thank you for your comment and idea to do a video. I do have a YouTube channel and do have a plan for this video soon. Meanwhile, there are a few other videos on Cypress if you are interested.
Will update here once the video is done (but not too soon though)
Ok thank you. If you already have the possibility to tell me how to configure it in this post even without the video I would really appreciate it because we need to be able to authenticate to be able to test our project. Without that we are stuck.
REgards,
@rahulpnath Thanks for this Gist. Most of the time it works, when running tests in GUI mode using:
npx cypress open --env username=MyUsername,password=MySecretPass
.
I still have a problem with clearing cookies. It seems like the cookies for the login.microsoftonline.com domain are not cleared. I tried to search for a solution in puppeteer to clear the cookies, but did not find anything yet. Do you know how to do this?
Another problem I am facing is running the test using cypress run.
My situation:
cypress run --browser chrome --headless
npm run testchromeheadless --env username=MyUsername,password=MySecretPass
It seems like there is a problem with passing these Environment variables in a command in combination with aadLogin.js.
I get the following error on the 'await page.type(emailSelector, username);' line of code in aadLogin.js:
CypressError: cy.task('aadLogin') failed with the following error:
text is not iterable
Because this error occurred during a 'before all' hook we are skipping the remaining tests in the current suite: 'My spec'
at http://localhost:65173/__cypress/runner/cypress_runner.js:153886:19
at tryCatcher (http://localhost:65173/__cypress/runner/cypress_runner.js:10161:23)
at Promise._settlePromiseFromHandler (http://localhost:65173/__cypress/runner/cypress_runner.js:8096:31)
at Promise._settlePromise (http://localhost:65173/__cypress/runner/cypress_runner.js:8153:18)
at Promise._settlePromise0 (http://localhost:65173/__cypress/runner/cypress_runner.js:8198:10)
at Promise._settlePromises (http://localhost:65173/__cypress/runner/cypress_runner.js:8274:18)
at _drainQueueStep (http://localhost:65173/__cypress/runner/cypress_runner.js:4868:12)
at _drainQueue (http://localhost:65173/__cypress/runner/cypress_runner.js:4861:9)
at Async.../../node_modules/bluebird/js/release/async.js.Async._drainQueues (http://localhost:65173/__cypress/runner/cypress_runner.js:4877:5)
at Async.drainQueues (http://localhost:65173/__cypress/runner/cypress_runner.js:4747:14)
From Your Spec Code:
at Context.eval (http://localhost:65173/__cypress/tests?p=cypress\integration\Project\myspec.spec.js:18:8)
From Node.js Internals:
TypeError: text is not iterable
at Keyboard.type (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\Input.js:112:28)
at Keyboard.<anonymous> (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\helper.js:95:27)
at ElementHandle.type (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\JSHandle.js:307:35)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async DOMWorld.type (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\DOMWorld.js:292:9)
at async aadLogin (C:\Cypress\ProjectTest\cypress\plugins\aadLogin.js:44:5)
-- ASYNC --
at ElementHandle.<anonymous> (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\helper.js:94:19)
at DOMWorld.type (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\DOMWorld.js:292:22)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async aadLogin (C:\Cypress\ProjectTest\cypress\plugins\aadLogin.js:44:5)
-- ASYNC --
at Frame.<anonymous> (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\helper.js:94:19)
at Page.type (C:\Cypress\ProjectTest\node_modules\puppeteer\lib\Page.js:793:33)
at aadLogin (C:\Cypress\ProjectTest\cypress\plugins\aadLogin.js:44:16)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
Does anyone know how I can fix this issue?
@MelvBa Did you check this to clear cookies with Puppeteer
Hi Rahul! we use Auth0 with AAD login for our application..Your solution works very well..Thanks for that :) We have 2 factor auth implemented into our application now...Is there a way to solve that using puppeteer?
@archanarachuri Glad, it helped. I have not played around much with 2FA and tests. For the account I used, we had 2FA turned off (but I am not sure if that is a good practice)
Here are a few links that came up on a google search and looked promising -
Test automation approach for Two-factor authentication
Automated API Testing Strategy for Services using SMS-based Two-Factor Authentication
Do let know in case you find a way - I am interested
Thanks Rahul! Sure I'll let you know
This worked great for me! I like that it doesn't save anything to a file and instead just uses the same browser.
BTW - I used puppeteer-core instead of puppeteer and it worked great!
https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteer-vs-puppeteer-core
Thanks, @TonyHernandezAtMS for posting it back here!
Hello guys,
can someone help me out here.
Did we try this code with a different browser other than for edge like electron .
What parameters are we required to pass to make this run on electronI get the following error message when trying to run through electron.
I referred to another piece of code template in the following url and now its working for me using electron and chrome browser as well
Thank you very much @rahulpnath for sharing this article
https://gist.github.com/csuzw/845b589549b61d3a5fe18e49592e166f
Glad it helped and thank you for the comment @Coding-Means-Always-Learning
Thank you @rahulpnath sharing this.
I tried with the above code you have added at the beginning here, but I am facing plugin file error like below
I have file index.js placed properly as mentioned.
is this something issue with my code, Please help me.
@Lakshmana-HN Hard to tell what the issue is here seeing this error. Looks like there is an error with the plugins file from the message. Were you able to figure it out?
No, didn't find any solution for this, is it because of the some puppeteer or cypress version difference. I have "puppeteer": "^8.0.0", and "cypress": "3.4.1",
Hi @rahulpnath !
First of all thank you for this code! It really helped as a starting point in authentication that I try to do using cypress. However I have a problem with logging into different azure ad accounts. It seems like it remebers my own account and whenever I visit website (I tried clearing cookies and localstorage; also used incognito mode) and try to log in into different test account it always redirects me to my url and I see that my account is logged in. Any help in tackling this issue would be great :)
@oskoczypiec Glad it helps. I didn't come across this issue though. Did you try in a different browser? Usually incognito does the trick for me and with these automated tests since it does not have anything saved to the browser state it works fine.
@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
@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
- Open the application and click on the login button which will redirect to identity server api
- Again click on login on the redirected site then it redirects to login.Microsoftonline.com and asks for credentials.
- 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
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?
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 });
}
});
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
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?
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.
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.
@rahulpnath Rahul!! I figured it out, I didn't have the env settings set correctly, so that's why it probably tweeked out the way that it did. Thank you for check in/helping me out!