Closed mikestock-nimble closed 1 year ago
@mikestock-nimble, thanks for logging this issue. Could you try enabling modifyObstructiveThirdPartyCode to see if that resolves your issue.
Hi @mschile
I forgot to mention I have the following config:
import { defineConfig } from 'cypress'
export default defineConfig({
defaultCommandTimeout: 10000,
pageLoadTimeout: 10000,
watchForFileChanges: false,
chromeWebSecurity: false,
experimentalModifyObstructiveThirdPartyCode: true,
reporter: 'cypress-multi-reporters',
reporterOptions: {
reporterEnabled: 'mochawesome',
mochawesomeReporterOptions: {
reportDir: 'cypress/reports/mocha',
quite: true,
overwrite: false,
html: false,
json: true,
},
},
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
},
})
I am really confused as to why it happens, because I checked the chrome that launched and it says it has cookies enabled, I'm not sure if it has something to do with cy.origin? Is there anything different about cy.origin and cookie permissions?
@mikestock-nimble, here is an example of Cypress using the boilerplate offered by Microsoft: https://github.com/cypress-io/cypress/issues/1342#issuecomment-1266065612
Does that work for you?
Hi @mschile
So I looked at that thread and it appears another user hit the same issue I did, I have also tried that solution in the thread posted by @AtofStryker and still no luck, it still thinks cookies are blocked even though my browser settings say otherwise
Thanks
@mikestock-nimble, do you have a project I could look at? I believe the cookie check is Microsoft checking a cookie on document.cookie
and not whether or not cookies are enabled in the browser config.
Hi @mschile I don't have one at at the moment that I can share, but I will investigate the document.cookie setting and do some reading around it
Thanks
Hey @mikestock-nimble. I actually ran into this issue yesterday. Weirdly enough, it only happened when I input the wrong user credentials. I will open an issue to track this as well, but can you verify you are inputing the correct username and password?
@AtofStryker
Hi
I am entering in the correct user name, it fails before I get the chance to enter in a password
Thanks
@AtofStryker I have the same issue and same cypress configuration. I will wait for the fix.
I am able to reproduce this issue only when I put in the wrong password when following pretty close with our proposed AAD guide
Facing the same issue here! I'm able to go a bit further using Electron instead of Chrome . Maybe Chrome is actually blocking the cookies?
Environment: Cypress 12.3.0 (using the zip download), Windows 11, Chrome v108, Electron v106.
Edit 1: I was able to work-around the cookies issue using:
cy.window().then((win) => win.location.href='https://myapp.domain.io');
instead of cy.visit('https://myapp.domain.io')
But still, the authentication doesn't work and I can see a failing request in console:
(fetch)POST 400 https://login.microsoftonline.com/f86596e1-77d4-48b1-8gh4-3gb0cc7fa8f1/oauth2/v2.0/token
{
"error": "invalid_request",
"error_description": "AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests"
}
Edit 2: So according to this StackOverflow post this could be related to a missing Origin header. Indeed! I checked the request on the Network tab, the Origin header was missing. Why? Because while trying to debug the initial issue (Chrome blocking cookies) I disabled the chromeWebSecurity 🤦🏻♂️
Now it seems to work (in Electron only), but I still need to use: cy.window().then((win) => win.location.href='https://myapp.domain.io');
Edit: 3 Microsoft uses this helper utility to check whether cookies are enabled or not:
I put some debugging logic and it returns false, however navigator.cookieEnabled
returns true.
And this weird behavior only occurs in Chrome, Electron works fine.
@AtofStryker is there any update on this?
@guzmanoj no updates yet, but hoping to investigate this hopefully this week
@guzmanoj no updates yet, but hoping to investigate this hopefully this week
I could help with some debugging and also willing to provide more details :)
@guzmanoj we would very much appreciate that! My guess is that there is a bit of a race condition between the cookie helper check and when Cypress sets the cookie. For cy.origin
, we have to patch document.cookie
in order to get the cookies established correctly. But this sometimes can happen async, which might lead to a race condition. However, for this case it should be happening synchronously. Do you know which file the Microsoft CookiesHelper
utility lives in? It might be good to see if the cookie is actually being written to suggest cookies are enabled for Microsoft's utility. And compare that to what is actually in document.cookie
.
@AtofStryker
Sure. The utility itself lives injs/Core/BrowserControl.js
around line 761.
Then there's a function called isRedirectNeeded()
in charge of performing the redirect (document.location = serverData.urlNoCookies
) based on cookies enabled flag is located injs/LoginPage/PaginatedLoginPage.js
this function is being called on window load event according to line 28 of the PaginatedLoginPage.js
Would be interesting to put a break-point somewhere here and see if the patch is actually working in this scenario.
@guzmanoj thank you for pointing me in the right direction! So I spent some time digging today and I think there is a bug in our cookie patch:
So to check if cookies are enabled, Microsoft sets a cookie called CkTst
that is set to a value and then checks if that cookie is truthy/available.
Immediately after checking if that cookie exists (which it does), the cookie is then removed. But the way this cookie is removed is by setting the value to ""
and setting the expiry time to a value in the past from now (in this case, a date from 1980). So the cookie is set, and then immediately removed, which has the delete effect.
We are not checking the expiry time of the cookie before setting it, which means the cookie is being set in the jar when it isn't supposed to be:
To test this theory, I added a naive patch to the cookie patch to remove a cookie in the jar if its past expiry (if exists) and do not set it. This seems to fix the issue with the only know way I have to test it, which is putting in a wrong password.
https://user-images.githubusercontent.com/3980464/214143070-a42db19c-1115-4100-9ae0-0e5b2d343eaa.mp4
https://user-images.githubusercontent.com/3980464/214143091-8f1cb22b-8bf1-4476-bb54-0cc2e2655e78.mp4
I'm going to route this issue over to the e2e team as I think we can come up with a fix for this.
@guzmanoj thank you for pointing me in the right direction! So I spent some time digging today and I think there is a bug in our cookie patch:
So to check if cookies are enabled, Microsoft sets a cookie called
CkTst
that is set to a value and then checks if that cookie is truthy/available.Immediately after checking if that cookie exists (which it does), the cookie is then removed. But the way this cookie is removed is by setting the value to
""
and setting the expiry time to a value in the past from now (in this case, a date from 1980). So the cookie is set, and then immediately removed, which has the delete effect.We are not checking the expiry time of the cookie before setting it, which means the cookie is being set in the jar when it isn't supposed to be:
To test this theory, I added a naive patch to the cookie patch to remove a cookie in the jar if its past expiry (if exists) and do not set it. This seems to fix the issue with the only know way I have to test it, which is putting in a wrong password.
Before adding the naive patch
azure-not-working-660.mp4
After adding the naive patch
azure-working-660.mp4 I'm going to route this issue over to the e2e team as I think we can come up with a fix for this.
Awesome work! That definitely looks like the right solution!
Definitely cool stuff @AtofStryker Looking forward to give it a shot on a real environment. Thank you!
possibly related to #25194
@AtofStryker is it possible that you publish here the new cypress_cross_origin_runner.js
? I believe that your naive patch should live there after compiling all the sources, if so I could just simply replace that file on my local cypress installation 😃
Or what about zipping the entire resources\app\packages\runner\dist
just to be sure?
Can this be related to :https://github.com/cypress-io/cypress/issues/25605
If so, I would also like to test the patch
@guzmanoj I am going to work on getting a binary you can try that you can install through npm. I will update when it's available. What OS are you on again?
Can this be related to :#25605
If so, I would also like to test the patch
@reshadatavid It is possible. I should be able to investigate that issue today
@guzmanoj @mikestock-nimble you should be able to see the binaries for this patch here for each OS. Let me know how it goes!
@AtofStryker Still not working on my end unfortunately.
I completely removed all of the old Cypress stuff and installed it again from the link you provided.
Also, the package.json of the installed Cypress in my project's node_modules indicates that I'm really using your patch. This is also true for my project's package.json (see images)
So I was doing some extra debugging... and here comes the potentially dummy question: Can we make sure that the code you introduced is actually doing its magic? My initial thought was that it could be part of the cypress_cross_origin_runner.js
because I noticed that this file is being loaded for the origin login.microsoftonline.com, but maybe the document.cookie
monkey-patching happens at an early stage... if so, could it be possible to sneak around (e.g. which files should I look at?)
@guzmanoj Interesting. So that document.cookie
monkey patch should be happening on the loaded resource from login.microsoftonline.com
since we inject cypress and our patches into the top of the HTML for the file that loads subsequent resources.
This puts us back in the spot of being able to reproduce this issue since I no longer can on my end. Would you be able to possibly invite me to a production repository, even if it's private?
The other option is for you to to try and debug this locally with the cypress develop
branch, which might be a bit of a challenge if you are on windows (assuming from the binary download). You could try it though by forking cypress and running yarn
in the root directory, which may take some time to complete. Once that is done, you can make these changes to try and debug the cross-origin injection easier, followed by yarn cypress:open
to start the test running in global mode and pointing it to your project. You could be able to debug the same files with this that I showed above, hopefully 😅 .
would anyone be willing to try this with 12.7.0
with chromeWebSecurity
set to true
(yes actually turning it on 😅 )?
I am going to close this issue due to inactivity. If this is still happening, please comment on this issue or open another issue.
@AtofStryker I had a similar issue when I try to login via Azure AD, the API call to get the token fails (error 400) after redirecting from login.domain.com to myapp.domain.net but then it got fixed when I set chromeWebSecurity
to true
as you suggested. If you could kindly share information on why this is happening when chromeWebSecurity
is set to false
because our other tests requires that to be set to false
. Thanks
@vinkms I think the main reason the 400 was happening was due to a missing origin header. What is your use case for requiring chromeWebSecurity
to be turned off?
@AtofStryker it's for some tests that involves a separate application embedded in an iframe. Thanks for the explanation.
@vinkms of course! I wonder if you may be able to get around it by adding the expected origin header in a cy.intercept
?
Hello guys, i still have the same problem. Current behavior:
When using the cy.origin('login.microsoftonline.com') or even cy.visit command in Cypress, a window pops up indicating that cookies are blocked, preventing further interaction with the Microsoft login page.
Desired behavior:
When a user is logged in using the website's authentication system, they should have the option to connect via Microsoft to access additional features on the website. This option should be presented clearly and should initiate the Microsoft authentication flow seamlessly, allowing the user to authenticate with their Microsoft account and access the additional features without any issues.
Test code to reproduce:
//commands.js
Cypress.Commands.add('microsoftLogin', () =>
{
cy.origin('login.microsoftonline.com', () => {
cy.get('input[type="email"]').type(Cypress.env("MICROSOFT_USERNAME"))
cy.get('input[type="submit"]').click()
cy.get('input[type="password"]').type(Cypress.env("MICROSOFT_PASSWORD"), {
log: false,
})
cy.get('input[type="submit"]').click()
})
})
//cypress.config.js
experimentalModifyObstructiveThirdPartyCode: true
Cypress Version: 13.7.3
Node version: v20.12.1
Operating System: Windows 11
@laztwo Question are you in incognito mode when running the test. The latest update of Chrome I noticed sets the incognito mode to disable third-party cookies. When this setting is turned off the test run through fine. However, with Cypress is frames you actually page so the top level or base url you have set might have cookies that block this;. IE
I been running into the same problem and this seems too look like the framing that is done with Cypress is causing the issue with Active Directory. I have turned on Chrome Websecurity I have also tried setting other options. The only way I have found around it has been to add specific sites allowed for the third party cookies. But Framing AD is not the way to go in this test from what I cant tell. It might be better off if you update the browser with a token.
Hello @iepoch thank you for your answer. i have updated chrome and cypress to the last version and in my tests i don't use incognito mode, u checked if in cypress chrome browser i have third-party cookies disabled but it wasn't. I already set experimentalModifyObstructiveThirdPartyCode to true and i tried chromeWebSecurity on true and false but i get the same result : cookies blocked... I don't know if i should open a new github issue or not because am new to github issue platform and i see that this ticket is still closed
@
Hello @iepoch thank you for your answer. i have updated chrome and cypress to the last version and in my tests i don't use incognito mode, u checked if in cypress chrome browser i have third-party cookies disabled but it wasn't. I already set experimentalModifyObstructiveThirdPartyCode to true and i tried chromeWebSecurity on true and false but i get the same result : cookies blocked... I don't know if i should open a new github issue or not because am new to github issue platform and i see that this ticket is still closed
You could open a new ticket but I noticed your going to cy.origin('login.microsoftonline.com') Your base URL must redirect you to Login.microsoftonline.com correct? I am assuming it does. This was the only way I was able to redirect without being in a constant loop. Try going to a site within the function but make sure your beforeEach has a site first. Its odd but I have seen this before because when routing to a origin it can not be the first site you visit it can not be the top level.
I have the same setup but had to do a work around like BaseUrl: google.com
My Test Function:
beforeEach(() => {
cy.visit('/spa/signin');
});
it('Valid Azure Active Directory User Signin', () => {
cy.loginToAAD(`${AD_URL}${siteDomain}`, 'test@test.com');
});
My Helper Function:
export const loginViaAAD = (site: string, email: string, password: string) => {
cy.visit(site); // This is the redirect site that will redirect to login.microsoftonline.com
cy.origin(
'login.microsoftonline.com',
{
args: {
email, password,
},
},
({ email, password }) => {
cy.get('input[type="email"]').type(email, {
log: false,
});
cy.get('input[type="submit"]').click();
cy.get('input[type="password"]').type(password, {
log: false,
});
cy.get('input[type="submit"]').click();
cy.get('input[type="submit"]').click();
},
);
Also add this to Launch Options in Cypress Config This helps with if your on a network and your already signed into AD
setupNodeEvents (on, config) {
on('before:browser:launch', (browser={
name: '',
family: 'chromium',
channel: '',
displayName: '',
version: '',
majorVersion: '',
path: '',
isHeaded: true,
isHeadless: false,
}, launchOptions) => {
if (browser.family === 'chromium') {
launchOptions.args.push('--auth-server-allowlist=_');
}
return launchOptions;
});
Current behavior
Hi,
I've been using Puppeteer to login using Azure AD as Cypress was not able to load the page to perform the login
I have now upgraded to cypress 12 and I am able to load the screen and type in the user name, the problem is microsoft azure AD is saying cookies are disabled on the chrome browser that Cypress launched
It means that I can't complete the login as it breaks after the username is entered
Desired behavior
I would like to use Cypress to login via Azure AD, I assume the only issue here is the browser that is launched by Cypress has cookies disabled, so I need to know how to enable them if possible for Cypress
Test code to reproduce
Cypress Version
12.1.0
Node version
v16.19.0
Operating System
Windows 10 Enterprise
Debug Logs
No response
Other
No response