Closed corneliutusnea closed 5 years ago
So, I can reproduce this quite easily. Just try to delete/expire a cookie that was never set from the server and it will crash the complete Cypress app.
Set-Cookie: Name=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax
Thank you for the reproducible example
Sent from my iPhone
On Feb 15, 2018, at 23:00, corneliutusnea notifications@github.com wrote:
So, I can reproduce this quite easily. Just try to delete/expire a cookie that was never set from the server and it will crash the complete Cypress app.
Set-Cookie: Name=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
I have this issue as well. @corneliutusnea did you find a workaround? It's making cypress unusable.
@lukemadera no, I didn't find a workaround. I gave up and moved to TestCafe that worked better for my needs.
Thanks for the prompt rely. @bahmutov I don't intend to give up that easily, but do need a fix - any progress on this?
We'll fix this in the next release.
Great, thanks Brian! Any ETA on when that will be?
Not sure yet - if the 3.0 is delayed any longer than this week we'll issue a patch release with these fixes.
Awesome thanks - so it seems either way it should be in by the end of the week!
Is the patch released? I'm running into the same problem
Having the same problem.
I looked into this issue and cannot reproduce. There is not enough information in the issue.
I tried recreating by setting cookies during a redirect which do not exist. This does not create the crash. To reproduce this we will need a full reproducible example either by specifying the exact cypress commands, server responses (including all headers), redirects, etc.
Please try to minimize to the bare minimum. For instance, this does not cause a crash:
// server side code
app.get("/redirect", (req, res) => {
res
.set({
"Set-Cookie": "aspAuth=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax"
})
.redirect("http://localhost:3501/fixtures/dom.html")
})
// cypress code
cy.visit("/redirect")
I tried various combinations related to setting cookies and their values and none of them cause the crash.
@darmalovan please post the steps to reproduce... I cannot guarantee I will look at this issue again for awhile.
If nobody posts reproducible steps this issue will not be fixed. Really... anyone...?
For me it was trigger via logout and that call was not strictly necessary so I just removed it so found a work around for now. Additionally, now I'm getting a cookie too large / can't clear cookies issue that is failing the tests sooner so I can't even get anywhere, so Cypress has been down / blocked for me completely. See https://github.com/cypress-io/cypress/issues/1547 @brian-mann how do I manually set cookies / NOT have Cypress automatically set them for me?
@lukemadera, @corneliutusnea, I had the same problem and figured a workaround:
cy.window().then((win) => { win.location = "/logout"; });
I am also having the same issue. Cypress 2.1.0 Chrome 66 OSX 10.12.6
Just run this test and it crash:
describe('crash issue https://github.com/cypress-io/cypress/issues/1321', function() {
it.only('go into create step2', function() {
cy.visit('https://www.surveymonkey.com') //working fine
cy.visit('https://www.surveymonkey.com/create/?sm=JyO9zQ7UD4cy1qYivEKDxbW5vSI_2BIVzBnqW7paZOcEU_3D') //crashing when trying to access a URL requiring login
})
})
Would really like this to be fixed. Attached a debug log here: https://gist.github.com/lujianlujian/aa2f4aa22c194c55c776d6cc1421bb5c
describe('My First Test', function() {
it('Visits the Kitchen Sink', function() {
cy.visit('https://www.paypal.com')
})
})
{ [Error: Failed to parse or set cookie named "X-PP-SILOVER".] name: undefined }
I get this error - any idea how to solve this ?
Cypress 2.1.0 Chrome 66 OSX 10.12.6
I am also having the same issue with the cy.request()
{ [Error: Failed to parse or set cookie named "xso".] }
I have used Charles, an HTTP monitor to check all network requests sending from my environment.
One interesting thing I found is when I use cy.request(https://xxx/api/order/campaigns/xxx)
to send a request, I can see that I have received the right response in Charles
dashboard, while the cypress console shows the error as below:
Error: CypressError: cy.request() failed trying to load:
https://xxx/api/order/campaigns/xxx
We attempted to make an http request to this URL but the request failed without a response.
We received this error at the network level:
> Failed to parse or set cookie named "xso".
-----------------------------------------------------------
The request we sent was:
Method: GET
URL: https://xxx/api/order/campaigns/xxx
-----------------------------------------------------------
Common situations why this would fail:
- you don't have internet access
- you forgot to run / boot your web server
- your web server isn't accessible
- you have weird network configuration settings on your computer
The stack trace for this error is:
undefined
Would really like this to be fixed. Thanks !
Cypress 2.1.0 (also crashed in Cypress 3.0.1) Chrome 66 OSX 10.12.6
As @sillpa-polasani and @lujianlujian describes, this crash can be easily reproduced by these cases:
describe('My First Test', function() {
it('Visits the Kitchen Sink', function() {
cy.visit('https://www.paypal.com')
})
})
describe('crash issue https://github.com/cypress-io/cypress/issues/1321', function() {
it.only('go into create step2', function() {
cy.visit('https://www.surveymonkey.com') //working fine
cy.visit('https://www.surveymonkey.com/create/?sm=JyO9zQ7UD4cy1qYivEKDxbW5vSI_2BIVzBnqW7paZOcEU_3D') //crashing when trying to access a URL requiring login
})
})
After adding some hard codes in setCookie
function incookies.js
, everything seems just back to normal, including that two reproduce cases.
path: /Cypress/3.0.1/Cypress.app/Contents/Resources/app/packages/server/lib/automation/cookies.js
(function() {
var COOKIE_PROPERTIES, Promise, _, cookies, extension, normalizeCookieProps, normalizeCookies;
_ = require("lodash");
Promise = require("bluebird");
moment = require('moment');
extension = require("@packages/extension");
COOKIE_PROPERTIES = "name value path domain secure httpOnly expiry".split(" ");
normalizeCookies = function(cookies, includeHostOnly) {
return _.map(cookies, function(c) {
return normalizeCookieProps(c, includeHostOnly);
});
};
normalizeCookieProps = function(props, includeHostOnly) {
var cookie;
if (!props) {
return props;
}
cookie = _.chain(props, COOKIE_PROPERTIES).pick(COOKIE_PROPERTIES).omitBy(_.isUndefined).value();
if (includeHostOnly) {
cookie.hostOnly = props.hostOnly;
}
switch (false) {
case props.expiry == null:
delete cookie.expiry;
cookie.expirationDate = props.expiry;
break;
case props.expirationDate == null:
delete cookie.expirationDate;
delete cookie.url;
cookie.expiry = props.expirationDate;
}
return cookie;
};
cookies = function(cyNamespace, cookieNamespace) {
var isNamespaced;
isNamespaced = function(cookie) {
var name;
if (!(name = cookie != null ? cookie.name : void 0)) {
return cookie;
}
return name.startsWith(cyNamespace) || name === cookieNamespace;
};
return {
getCookies: function(data, automate) {
var includeHostOnly;
includeHostOnly = data.includeHostOnly;
delete data.includeHostOnly;
return automate(data).then(function(cookies) {
return normalizeCookies(cookies, includeHostOnly);
}).then(function(cookies) {
return _.reject(cookies, isNamespaced);
});
},
getCookie: function(data, automate) {
return automate(data).then(function(cookie) {
if (isNamespaced(cookie)) {
throw new Error("Sorry, you cannot get a Cypress namespaced cookie.");
} else {
return cookie;
}
}).then(normalizeCookieProps);
},
setCookie: function(data, automate) {
var cookie;
if (isNamespaced(data)) {
throw new Error("Sorry, you cannot set a Cypress namespaced cookie.");
} else {
cookie = normalizeCookieProps(data);
cookie.url = extension.getCookieUrl(data);
if (data.hostOnly) {
cookie = _.omit(cookie, "domain");
}
/* hard code start */
var currentTime = moment();
var expires = data.expires;
var expiry = data.expiry;
if(( expiry && !expires) || (!expiry && expires)) {
return;
}
if(expires && moment(expires) < currentTime ) {
return;
}
/* hard code ends */
return automate(cookie).then(normalizeCookieProps);
}
},
clearCookie: function(data, automate) {
if (isNamespaced(data)) {
throw new Error("Sorry, you cannot clear a Cypress namespaced cookie.");
} else {
return automate(data).then(normalizeCookieProps);
}
},
clearCookies: function(data, automate) {
var clear;
cookies = _.reject(normalizeCookies(data), isNamespaced);
clear = function(cookie) {
return automate("clear:cookie", {
name: cookie.name
}).then(normalizeCookieProps);
};
return Promise.map(cookies, clear);
},
changeCookie: function(data) {
var c, msg;
c = normalizeCookieProps(data.cookie);
if (isNamespaced(c)) {
return;
}
msg = data.removed ? "Cookie Removed: '" + c.name + "'" : "Cookie Set: '" + c.name + "'";
return {
cookie: c,
message: msg,
removed: data.removed
};
}
};
};
cookies.normalizeCookies = normalizeCookies;
cookies.normalizeCookieProps = normalizeCookieProps;
module.exports = cookies;
}).call(this);
I strongly suspect this unexpected error is related to cookie expires time. But I didn't figure out the root cause.
@brian-mann Can you guys help to check for this issue agian?
Seems this is such a common usage scenario for Cypress request()
and visit()
, there must be lots of developers encounter the same confusion here.
Great appreciate!
I have spent several hours tonight reproducing this. I appreciate you providing a reproducible example - although many of our users mentioned having this problem we could not easily reproduce on our own.
Problem 1: I have yet to determine the exact root cause. Yes, cookies are failing to be set, but the actual reason why is much more complicated and is happening due to the way Cypress is handling visit resolution much earlier in the process.
Problem 2: I'm also wondering why those failed promises aren't being correctly handled / caught. It appears that all Promises are attached correctly and therefore the exception should be handled and sent back to the runner correctly. This error should not be crashing Cypress.
Thank you so much for putting all that time and effort in Brian! Sorry this is such a tricky issue.
@brian-mann did you see issue #1264? It might be the clue.
I'm also getting Failed to parse or set cookie
error when trying to preserve secured cookies during the tests.
We're aware of what the problem is. It's not a quick fix but it's an important one that's high up on our radar.
We are going to release 3.1
first and then circle back to this. It requires shifting around a bunch of things to fix.
I just landed in cypress.io and met the above error.
If i run it through Electron 59 , did not get this issue. Only faced it with "Chrome 67".
@debmalya nope, same issue in chrome 68
I've got the same problem :( Chrome 68
@HeyDaniyar I'd like to mention that I encountered the same problem, receiving "failed to parse or set ...". I used your two code snippets, but they failed due to the moment
library missing.
I monkey-patched them to look like this:
setCookie: function(data, automate) {
var cookie;
if (isNamespaced(data)) {
throw new Error("Sorry, you cannot set a Cypress namespaced cookie.");
} else {
cookie = normalizeCookieProps(data);
cookie.url = extension.getCookieUrl(data);
if (data.hostOnly) {
cookie = _.omit(cookie, "domain");
}
/* hard code start */
var currentTime = +new Date();
var expires = data.expires;
var expiry = data.expiry;
if(( expiry && !expires) || (!expiry && expires)) {
return;
}
if(expires && +new Date(expires) < currentTime ) {
return;
}
/* hard code ends */
return automate(cookie).then(normalizeCookieProps);
}
},
setJarCookies: function(jar, automationFn) {
var setCookie;
setCookie = function(cookie) {
var ex;
cookie.name = cookie.key;
if (cookie.name && cookie.name.startsWith("__cypress")) {
return;
}
switch (false) {
case cookie.maxAge == null:
cookie.expiry = moment().unix() + cookie.maxAge;
break;
case !(ex = cookie.expires):
cookie.expiry = moment(ex).unix();
}
return automationFn("set:cookie", cookie).then(function() {
return Cookies.normalizeCookieProps(cookie);
// when add catch funtion to the promise,
// the request function would return result normally.
// But it will still show the error in cypress node console
}).catch(function(err) {
console.log('**** Get Error in Set Coookie *****', err);
});
};
return Promise["try"](function() {
var store;
store = jar.toJSON();
return Promise.each(store.cookies, setCookie);
});
},
For those landing here after 3.1.0 was released, the location of the Cypress executable (Cypress.app) was changed and you can find the new location by running npx cypress verify
and it'll print the path :)
For me it's here: /Users/kdodds/Library/Caches/Cypress/3.1.0/Cypress.app
@Azeirah
You need to import themoment
package first at the beginning of the function, just like this:
// Contents/Resources/app/packages/server/lib/automation/cookie.js
(function() {
var COOKIE_PROPERTIES, Promise, _, cookies, extension, normalizeCookieProps, normalizeCookies;
_ = require("lodash");
Promise = require("bluebird");
moment = require('moment');
....
BTW, this solution is only tested in Cypress 3.0.1
, not sure it would still work in other versions.
Hi Brian, We at Kensho are running into this issue as well and would like to know if there is a quick workaround or an estimate on 3.1.1 will be released? Thanks
This is also an issue for me when trying to set cookies with empty content and expiry date of 1970...
I get Setting cookie failed
.
PS: I can't use cy.clearCookies
because the cookies are httpOnly
.
Does anyone have a workaround for this bug. It's a showstopper for my team right now. We are on the brink of abandoning cypress for this.
@cannibalcow you'd better abandon if you can, regular webdriver is much much better. It takes time on the beginning to setup things, but then it works way better and faster (and supports headless chrome).
Cypress is good only for something really small. It is good on the first step, but then it is much more painful to work with. You'll have lot's of showstoppers
@cannibalcow Have you ever tried my workaround? At least now it works for me.
@cannibalcow Have you ever tried my workaround? At least now it works for me.
Yeah we are using your workaround at the moment, but it's not a good long term solution.
I'm able to reproduce this as well. It just so happens it fails to parse on a Cookie with a expiration date in the past.
I can also confirm that this issue is stopping my team from getting our cypress test suite off the ground. I know a fix is in the works, but is there an ETA by chance?
I have this issue when having consecutive visit commands,
cy.visit('/pageA')
.doSomething()
.visit('/anotherPage')
and it's also a bad practice when implenting e2e tests, then I just change it to clicking UI items.
We're prioritizing this issue in this sprint. It's long overdue to be fixed.
We have made a lot of progress on this issue, and may have a fix out in the next day or two. We had to rewrite the visit resolving layer of Cypress, which will help more things than just this bug as well.
Hi @brian-mann, we are doing a POC on using Cypress for our apps. We are also running into this issue. What is the eta on releasing this fix? You mentioned 3 days ago "may have a fix out in the next day or two". Its a blocker for us.
I also ran into this issue, but encountered it when sending a POST cy.request to authenticate with our SSO provider - okta. Looks like someone else hit the same blocker as well: https://github.com/cypress-io/cypress/issues/1489#issuecomment-418871535
Hey @drewbrend, you can try using password grant type in okta if you are doing via cy.request. https://developer.okta.com/blog/2018/06/29/what-is-the-oauth2-password-grant
The code for this is done, but this has yet to be released. We'll update this issue and reference the changelog when it's released.
Interestingly, We are now getting this problem (or similar) with the upgrade to 3.1.1. Everything works in 3.1.0 for us. We are getting this error in a few scenarios.
~/Quorum/quorum-site on cypress-docs! ⌚ 11:33:02
$ npm run cypress ‹ruby-2.4.1›
> quorum-site@2.8.3 cypress /Users/jonathanmares/Quorum/quorum-site
> cypress open
GET /__/ 200 28.124 ms - -
GET /__cypress/runner/cypress_runner.css 200 52.233 ms - -
GET /__cypress/runner/cypress_runner.js 200 383.054 ms - -
GET /__cypress/runner/fonts/fontawesome-webfont.woff2?v=4.6.3 200 1.634 ms - 71896
GET /__cypress/iframes/integration/main/login_spec.js 200 14.349 ms - 733
GET /__cypress/tests?p=cypress/integration/main/login_spec.js-216 200 682.720 ms - -
GET /__cypress/tests?p=cypress/support/index.js-177 200 840.621 ms - -
{ [Error: Failed to parse or set cookie named "current_version".] name: undefined }
undefined
(quorum)
This is our index.js
file:
// cypress/support/index.js
// uncomment below to have Cypress log when Cookies change
Cypress.Cookies.debug(true)
// Make it possible to skip auth across tests
Cypress.Cookies.defaults({
whitelist: ["qsesid", "csrftoken"],
})
(interestingly, with our without the defaults, we still get the crash. Our login configuration is the following:
Cypress.Commands.add('loginByCSRF', ({csrfToken, username, password}) => {
cy.request({
method: 'POST',
url: '/login/',
failOnStatusCode: false, // dont fail so we can make assertions
form: true, // we are submitting a regular form body
body: {
username,
password,
},
headers: {
"X-CSRFTOKEN": csrfToken,
// django spells this referer - very odd
// this is required for Django to let this endpoint authenticate
"referer": Cypress.config().baseUrl
}
})
})
/**
* This function ("login") logs in to Quorum programmatically
* @name login
* @function
* @param {String} username - a username to login with
* @param {String} password - a password to log in with
* @param {Boolean} useCurrentSessionIfPossible - if qsesid and csrftoken are defined, don't log in again
* @param {Boolean} shouldVisitPath - Provide a way to skip visiting path if desired
*
* You might want to pass shouldVisitPath=false if you are refreshing the page in your beforeEach() block,
* in which case the initial visit is wasteful
*/
Cypress.Commands.add(
"login",
({
username = Cypress.config("TESTING_USER"),
password = Cypress.config("TESTING_PASSWORD"),
path = "/home/",
shouldVisitPath = true,
useCurrentSessionIfPossible = false,
} = {}) => {
if (useCurrentSessionIfPossible && cy.getCookie("qsesid").value && cy.getCookie("csrftoken").value) {
console.log("Already logged in, not logging in again")
return
}
// make a request to get a csrftoken
cy.request("/login")
.its("headers")
.then((headers) => {
const csrfToken = headers["set-cookie"][0].split(";")[0].replace("csrftoken=", "")
cy.loginByCSRF({ csrfToken, username, password }).then(() => {
shouldVisitPath && path && cy.visit(path)
})
})
})
here's the beginning of a test file that fails:
describe("Home page tests", function () {
before(function() {
// make sure we're logged in. Let beforeEach() handle visiting the home page
cy.login({
shouldVisitPath: false,
useCurrentSessionIfPossible: true // if auth cookies are available, don't bother re-logging in
})
})
beforeEach(function () {
// set up server to listen for requests
cy.server()
// alias requests to newperson so we can wait until they resolve
cy.route("GET", "/api/newperson/**").as("getNewPerson")
// before each test, go to the home page
cy.visit("/")
})
This time it doesn't crash, it just gives an error in the GUI:
@jennifer-shehane doesn't like I have permission to re-open the issue, should I make a separate issue for this?
We're aware of a regression with cookies in 3.1.1 here: https://github.com/cypress-io/cypress/issues/2724 not sure if this is related.
We're still getting this error in all versions after 3.1.0
, including latest 3.1.3
release
Is this a Feature or Bug?
Bug
Current behavior:
Sometimes when I go to my website using cy.visit(...) if the site returns a redirect and a clear cookie (e.g. logout) the Cypress crashes and logs:
Desired behavior:
How to reproduce:
Not sure, but these are the relevant headers my site returns when I navigate to it:
Test code: