Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cookie persistence, also fix some tests that are broken in modern browsers #192

Conversation

Mr0grog
Copy link
Contributor

@Mr0grog Mr0grog commented Jan 11, 2024

This fixes a bug where any levels that were saved in cookies were not loaded correctly. It also fixes a bunch of tests that were broken only in live/modern browsers and not in Node.js or PhantomJS (what you get when you run npm test). To see these failures, you would have had to start a server with grunt integration-test and then opened the Jasmine test runner from the server that starts in a real browser.

The cookie issue is that we were reading the value starting from the beginning of the cookie’s key-pair, so instead of reading a value like "INFO", we’d read loglevel="INFO", which is obviously not a valid level.

This also fixes a number of other test failures when running tests in an actual browser, but all of them were problems with the tests rather than actual bugs in the library like the above cookie issue. Fixing the cookie issue also revealed some other bugs in the test, so this was a bit of an iterative process.

Another thing I did with the tests here was change the describeIf/itIf helpers to mark tests that don’t get run as skipped rather than hiding them from test output entirely, so it’s at least a little more obvious that some things are not getting tested.

This makes it a bit more obvious when tests were not run in a given
environment, and therefore which behaviors might need more manual
testing.
This test suite was failing in environments that actually had
persistence (depending what order tests were run in). Note that it does
not fail on PhantomJS, and to see failures under the current tooling,
you must run `grunt integration-test` and then view the tests in a real
browser.
The test code for Node vs. browsers got out of sync at some point
when/after support for naming loggers with Symbols was added. Since
PhantomJS does not support symbols, the test was silently succeeding
when run via `npm test` but failing in actual browsers on
`grunt integration-test` (which clearly hasn't been used recently).

This:
- Fixes the test.
- Makes it a separate test so it can clearly be marked as skipped in
  environments where it is not run.
- Makes the test implementation match its Node.js-based counterpart and
  adds a comment indicating that any changes made to one should be made
  to the other.
Two tests in the cookies + localstorage suite were handling async
operations incorrectly (I think this is a change in Jasmine v2, and I
missed these in pimterry#190 because these tests don't run from the command
line). This fixes them, which resolves one test failure. The other is
still failing because of an actual bug in the library.
It turns out loading logger levels from cookies has been broken
(probably for a long time!), but since the tests that run from
`npm test` don't actually test cookies, this was never caught (those
tests use PhantomJS, which does not allow access to cookies from
`document.cookie`, so these tests were skipped). When running tests by
running `grunt integration-test` and then opening the tests in an
actual browser, you can see this test is failing.

The cause is that the cookie value is read starting from beginning of
the whole key-value pair, rather than the start of the cookie, so we'd
read in a value like `"loglevel=INFO"` instead of just `"INFO"`.

Incidentally, fixing this causes *other* tests to fail (uhoh), which I
will address in the next commit.
The `clearStoredLevels()` helper did not work correctly for named
loggers -- it looked for cookie names like `loglevel:whatever` instead
of `loglevel:%3Awhatever` (cookie names and values are URL-encoded).

This also fixes another test that started failing after an earlier fix,
I think because of timing/ordering issues. Explicitly clearing storage
before the test fixed the issue (the test was implicitly expecting
nothing to be stored).
Comment on lines -161 to +166
var location = cookie.indexOf(
encodeURIComponent(storageKey) + "=");
var cookieName = encodeURIComponent(storageKey);
var location = cookie.indexOf(cookieName + "=");
if (location !== -1) {
storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
storedLevel = /^([^;]+)/.exec(
cookie.slice(location + cookieName.length + 1)
)[1];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual bugfix. The rest is just cleaning up bad test code.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this makes sense. Any idea why this worked in phantomjs though?

I imagine in practice we haven't noticed this because modern browsers all support local storage, and have for a long time, so the cookie fallback logic isn't really used much nowadays.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this makes sense. Any idea why this worked in phantomjs though?

It didn't! One of the reasons I switched to showing the tests as skipped was to verify for myself that none of the cookie tests run in PhantomJS. It turns out document.cookie is just always empty and cannot be set, which causes all the cookie-related and persistence-related tests to be skipped.

Comment on lines -161 to +166
var location = cookie.indexOf(
encodeURIComponent(storageKey) + "=");
var cookieName = encodeURIComponent(storageKey);
var location = cookie.indexOf(cookieName + "=");
if (location !== -1) {
storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
storedLevel = /^([^;]+)/.exec(
cookie.slice(location + cookieName.length + 1)
)[1];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this makes sense. Any idea why this worked in phantomjs though?

I imagine in practice we haven't noticed this because modern browsers all support local storage, and have for a long time, so the cookie fallback logic isn't really used much nowadays.

@pimterry pimterry merged commit 45c5600 into pimterry:master Jan 11, 2024
@Mr0grog Mr0grog deleted the we-are-good-at-baking-cookies-but-not-very-good-at-eating-them branch January 11, 2024 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants