Cookies, sessionStorage, and localStorage

A practical introduction to browser storage and its impact on testing.

Updated:

Contents

Many web defects originate in how an application stores or reads browser data. A user appears to have logged out but remains authenticated; a new tab behaves differently; an old error returns after a refresh; a filter remembers an outdated state; or a token survives longer than expected. Cookies, sessionStorage, and localStorage often explain these behaviors.

Browser storage directly affects sessions, authentication, tab behavior, state recovery, and test reproducibility. Without understanding where data lives, QA can mistake expected behavior for a defect or overlook a real problem.

How they differ

The basic distinctions are:

  • →Cookies often support sessions, authentication, and server communication. They can be sent to the server automatically.
  • →sessionStorage is scoped to a particular tab and page session.
  • →localStorage persists across reloads and even browser sessions.

For QA, understanding the practical consequences matters more than memorizing these definitions.

Cookies commonly affect login, logout, remember-me features, server sessions, CSRF protection, and behavior across tabs. sessionStorage often holds temporary client state: drafts, intermediate steps, and UI state within the current tab. localStorage commonly holds longer-lived data: tokens, interface settings, language preferences, feature flags, local caches, and client preferences.

These uses introduce real risks.

Cookies: more than small pieces of browser data

Cookies matter especially because they often relate to a server session. Product behavior may depend on which cookies are set, their flags, when they expire, and the circumstances in which they are returned to the server, as well as on the UI and JavaScript.

QA should understand that:

  • →A cookie can be session-based or persistent
  • →A cookie with HttpOnly is inaccessible to JavaScript
  • →A cookie with Secure is sent only over HTTPS
  • →The SameSite policy can substantially affect login, redirects, embedded flows, and integrations
  • →The server may expect a cookie automatically, even when the UI gives no visible indication

A common trap is assuming that a user who appears to have logged out is fully signed out. Logout may succeed visually while a cookie remains uncleared or the client enters an inconsistent intermediate state.

sessionStorage: state within one tab

sessionStorage is often underestimated. Its tab scope is precisely what makes it useful: the same application can hold different sessionStorage state in two tabs.

This matters in scenarios involving:

  • →Multistep forms
  • →Drafts
  • →Temporary filters
  • →Wizard or onboarding state
  • →Data that should not survive closing a tab

When an application stores important state in sessionStorage, check:

  • →What happens after a refresh
  • →What happens when a new tab opens
  • →Whether state transfers somewhere it should not
  • →Whether back and forward navigation disrupt the flow
  • →Whether temporary state is cleared after the flow completes or is canceled

A common defect is that the user has reached a new state in one tab while another retains an outdated intermediate client context.

localStorage: convenient, with hidden risks

localStorage survives reloads and new browser sessions, so teams often use it for anything that seems useful to retain. That persistence also makes it a frequent source of subtle defects.

Typical problems include:

  • →Old state affects a new scenario
  • →Users receive stale data after a release
  • →Logout appears successful, but sensitive data remains in storage
  • →A new account inherits data left by the previous user
  • →A local feature flag or cache makes a defect difficult to reproduce
  • →Behavior differs between a clean environment and a real user's browser because of localStorage

QA should therefore treat localStorage as part of product state, beyond an incidental technical detail.

What commonly fails in practice

Typical storage defects include:

  • →Tokens or user data remain in the browser after logout
  • →A new tab receives unexpected state
  • →A refresh unexpectedly preserves data that should disappear
  • →Data from the previous user remains after another user logs in
  • →An application depends on localStorage but handles clearing it poorly
  • →Cookies fail to be set because of Secure, SameSite, CORS, or environment configuration
  • →sessionStorage behaves differently in popups, redirects, or interactions with an opener
  • →The UI and backend disagree about whether a session is active

Users often experience these as an unreliable website. For QA, they form a specific class of defects.

What QA should check

If authentication, user state, or complex navigation matters to the product, regularly check:

  • →What remains in cookies and storage after login
  • →What is cleared after logout
  • →What happens after a refresh
  • →How two tabs running the same flow behave
  • →What another user sees in the same browser after the previous user
  • →Whether localStorage contains sensitive data that should not be there
  • →Whether functionality depends too heavily on stale or accumulated storage
  • →Whether the application behaves consistently in a clean session and after prolonged use

These checks are particularly useful for login, shopping carts, filters, onboarding, checkout, feature flags, and offline-like behavior.

Practical example

Consider a logout flow.

A user clicks Log out and is redirected to the login page. Everything looks correct, but QA should also check:

  • →Whether the session cookie was removed
  • →Whether an access token remains in localStorage
  • →Whether a user profile or role remains in client storage
  • →What happens after a refresh
  • →What happens after pressing Back
  • →Whether an old tab still exposes private data
  • →Whether logging in as another user retrieves the previous user's data

These checks often reveal how reliably the product manages client state.

Key takeaways for QA

  • →Cookies, sessionStorage, and localStorage serve different purposes and affect different types of scenarios.
  • →Cookies often relate to server sessions and authentication flows.
  • →sessionStorage is scoped to a tab and is useful for temporary state.
  • →localStorage supports persistent state but can introduce hidden defects and leak client context between sessions or users.
  • →Good QA checks both the UI and the state actually left in the browser after a scenario.

Further reading