How to do e2e testing without cacheLocation="memory"?

Hello,

I’m setting up Playwright end-to-end tests for our React SPA that uses @auth0/auth0-react. I’d like to keep cacheLocation on the recommended default (“memory”) per your token storage guidance ( Token Storage - Auth0 Docs ), which explicitly warns:

If an attacker can achieve running JavaScript in the SPA using a cross-site scripting (XSS) attack, they can retrieve the tokens stored in local storage.

…and recommends in-memory storage as the most secure option. I want to honor that recommendation in our production build.

Yet, the examples I’m finding seem to rely on local storage for storing the token:

With cacheLocation=“memory”, the SDK has no tokens on a fresh page load, so it falls back to silent authentication via a hidden iframe to /authorize?prompt=none. In our test browser, this round-trip (~1–2s) loses the race against test assertions that immediately check for authenticated UI — the home dashboard renders empty before silent auth completes, and the test fails.

Could I get some proper guidance, please?

Hi @alex57,

Welcome to the Auth0 Community!

Your commitment to using cacheLocation="memory" is absolutely the recommended and most secure approach.

It’s crucial to understand that there are two distinct sessions at play. The first is the Application Session , which the Auth0 SDK stores in your application’s memory. As you’ve noted as well, this gets lost on every page refresh when using cacheLocation="memory". The Auth0 documentation explains this is expected behavior (Why is authentication lost after refreshing my SPA?).

The second is the persistent Auth0 Session , managed by a secure cookie on Auth0’s domain, which remembers the user’s login status with the authentication server itself. When your test starts on a fresh page, the Application Session is empty, so the SDK uses the persistent Auth0 Session to silently request new tokens. This ~1-2 second background process is what creates the race condition: your test script asserts for a logged-in UI before the SDK has finished establishing the new in-memory Application Session.

To resolve this, I recommend ensuring your SDK configuration is optimized for silent authentication reliability. The following settings are ideal for this, as useRefreshTokens can speed up token acquisition and useCookiesForTransactions helps prevent issues with browser privacy features.

const auth0Config = {
  useRefreshTokens: true,
  cacheLocation: 'memory',
  useCookiesForTransactions: true,
  sessionCheckExpiryDays: 1,
  cookieDomain: '.yourdomain.com' 
};

The most effective testing strategy involves logging in only once in a global setup task to establish the persistent Auth0 Session and reusing that authenticated browser state for all subsequent tests. With that in place, the critical change is to make your individual tests resilient to the silent authentication delay. Instead of asserting immediately, your test should wait for a UI element that confirms authentication is complete. For example, rather than checking for a dashboard element right away, instruct your test to wait for a specific welcome message like “Welcome, User!” or the main user avatar to become visible. Some testing frameworks have built-in web assertions such as toBeVisible() that can be used for such scenarios. This type of change allows the silent authentication process the time it needs to finish successfully before your test validates the outcome.

I hope this helps and if you have further inquiries please let me know!
Best regards,
Remus

Hi @remus.ivan , thank you kindly for your reply.

My concerns with this approach is that we would be changing app functionality specifically for testing, which is something I wanted to avoid. In particular, it appears that useCookiesForTransactions yields the auth0.xyz.is.authenticated cookie, which is not HttpOnly , and must be so since it’s managed by the javascript framework.

Though, in practice, using the aforementioned auth0 blog post, I’m already having to modify the react app for testing use cases already, and maybe just changing these two settings conditionally is less intrusive than having to change the auth provider code to bypass auth0 for testing (the approach in the blog post).

I’ll look into this some more. Thanks again for the info!