SeleniumHQ / selenium-google-code-issue-archive

Archive, please see main selenium repo
https://github.com/seleniumhq/selenium
345 stars 195 forks source link

[SafariDriver] SafariDriver seems to have problem dealing with cookies in JSON format #5503

Closed lukeis closed 8 years ago

lukeis commented 8 years ago

Originally reported on Google Code with ID 5503

What steps will reproduce the problem?
1. With SafariDriver, add a cookie whose value is JSON formatted.
2. Do something that uses the JSON cookie OR just dump back out the cookie value with
SafariDriver.

What is the expected output? What do you see instead?

Cookie is set correctly. Cookie is set, but we only get partial value. The value is
not a complete/valid JSON object. 

Selenium version: 2.28
OS: Windows 7 64-bit, with 32-bit JRE
Browser: Safari
Browser version: 5.1

Please provide any additional information below. A sample reduced test
case, or a public URL that demonstrates the problem will intrigue our merry
band of Open Source developers far more than nothing at all: they'll be far
more likely to look at your problem if you make it easy for them!

Comparing to Firefox and IE, the same cookie, same code will generate the correct JSON
in those browsers.

I also performed a browser/client side test in Safari, adding the JSON valued cookie
using document.cookie from Safari's error/javascript console and then dumped back the
value to console and URL decoded it. It was complete/valid JSON as expected, so it
doesn't appear to be a Safari browser limitation.

As an example, doing something like:

driver.manage().addCookie(new org.openqa.selenium.Cookie("test", "{\"tagName\":
 {\"label\": \"tagLabel\", \"tagId\": \"1\"}}", www.somesite.com, "/",
null));

then dumping back cookie

System.out.println(driver.manage().getCookieNamed("test"));

returns something like this:

test={"tagName": {"label": "tagLabel"; path=/

(above code executed via Beanshell, would get similar using pure Java)

Because the cookie value is missing data and not valid JSON, whatever is reading/using
that cookie will just fail and not work. Could be exception or as if cookie didn't
exist, but I don't know, didn't look into the web app from server side, just noticed
that it did nothing on client side and found this issue by dumping out the cookie to
verify if it was set or not.

Reported by mangaroo on 2013-04-16 07:09:50

lukeis commented 8 years ago

Reported by barancev on 2013-04-16 15:07:10

lukeis commented 8 years ago
I did some additional exploration, and there is a partial workaround for now: setting
cookie via native javascript.

But either it doesn't work as well as WebDriver's addCookie method (more native) or
I'm not using the optimal javascript code to set it (using document.cookie with example
from W3C site)

http://www.w3schools.com/js/js_cookies.asp

Here's an example:

String cookieScript = "var doSetCookie = function setCookie(c_name,value,exdays){ var
exdate=new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value=escape(value)
+ ((exdays==null) ? \"\" : \"; expires=\"+exdate.toUTCString()); document.cookie=c_name
+ \"=\" + c_value; }; doSetCookie(\"tagName\",\"{\\\"\"+arguments[0]+\"\\\": {\\\"tagLabel\\\":
\\\"\"+arguments[1]+\"\\\", \\\"tagId\\\": \\\"\"+arguments[2]+\"\\\"}}\",1);";

((JavascriptExecutor) driver).executeScript(cookieScript, testTagName, testLabelName,
testTagId);

I am able to get back the cookie with driver.manage().getCookieNamed() while on same
page where cookie is set, but it seems cookie is lost on navigating to another page,
and also, I don't see the cookie in Safari Web Inspector (looking at the cookie resources
section). So the cookie doesn't seem to fully persist correctly with this workaround,
but it does appear to set the cookie properly to some extent as I can read it back,
and part of the web app code that checks the cookie executes properly as expected (but
another part didn't work).

So this workaround may kind of work in some situations.

Reported by mangaroo on 2013-04-16 21:14:58

lukeis commented 8 years ago
Hope we can up the priority of fixing this bug in list of SafariDriver related issues
(for next fix, release, etc.). While there is workaround, it's not optimal, so a real
fix would be greatly appreciated. :)

Reported by mangaroo on 2013-06-14 01:06:49

lukeis commented 8 years ago
Thanks to a colleague today, I noticed that there is similar issue with Safari browser
itself (Safari 5 Windows and Safari 6 Mac, I think just Safari in general). We have
a feature where on an admin config page, user can set a cookie via clicking a button
to then use for manual testing. That doesn't take effect on Safari but works fine on
other browsers. However, just like this issue, executing the javascript workaround
code snippet (in Safari error/javascript console followed by page refresh), it does
take effect to some extent (seems on current page only). I didn't notice this before
since I focused on automation side of using the cookie rather than just manual testing.

Doing some online search, I see some similar JSON related problems with Safari, but
I didn't seem to find any filed OpenRadar bug/issue regarding Safari and JSON (cookies
or not).

http://stackoverflow.com/questions/19359326/json-parse-fails-in-safari-when-a-string-value-contains-a-comma

http://www.linkedin.com/groups/JSONstringify-doesnt-seem-work-in-100943.S.208455154

https://forum.foxycart.com/discussion/1490/x&page=1

So this may not be SafariDriver/extension specific but rather Safari specific issue.
I'll file an Apple bug & OpenRadar if I can get more info first on the bug.

What a pain Safari is...

Reported by mangaroo on 2014-01-15 00:34:44

lukeis commented 8 years ago
There are a few things that come to mind.  Make sure that your route for the cookie
is the root of the site.  If it is not the root of the site it would not be read by
a more strict browser.  You may also want to make sure what you are storing the cookie
has everything escaped or replaced as needed.  There may be certain characters that
are not allowed in cookies.  There is also a length limitation on cookies as well.
 I hope this helps.

Reported by charley.george on 2014-01-15 00:59:02

lukeis commented 8 years ago
We can close this bug. It's actually not a (SafariDriver) bug, but rather how the JSON
is dealt with that can result in this bug. 

I originally constructed the JSON as string escaping as needed (guess there was some
issues there still that I didn't notice and for which Safari didn't throw any complaints,
just not work when cookie read back, but for which works fine on all other browsers).
We later had to support some additional functionality that expanded the JSON object/format,
so it would have been ugly to build as a string. I built the JSON as a Java JSONObject
then called toString() to get it back as a string to add/create the cookie. Using this
approach, Safari works fine. But I never knew nor checked back on that, still resorting
to the workaround code I posted earlier since I thought the bug still existed (not
knowing the root cause). That is until coworker discovered related bug and me following
up on things.

So based on this, for all those dealing with JSON cookies in Selenium, best to construct
the JSON object from your language's JSON library then convert to string rather than
build as raw strings or else you might miss something and encounter this on Safari.
And/or run the string output through URL encode/decode (or escape/unescape) as needed
to also avoid this.

Thanks Charley, will keep your suggestions in mind for the future.

Reported by mangaroo on 2014-01-15 23:26:16

lukeis commented 8 years ago

Reported by jmleyba on 2014-01-16 02:40:02

lukeis commented 8 years ago

Reported by luke.semerau on 2015-09-17 18:17:08