End-to-End Testing with Cypress and Auth0

Learn how to programmatically authenticate against Auth0 in your Cypress tests in a manner that adheres to both Cypress and Auth0 best practices…

Read more at:

1 Like

How did you like this post? Please share any comments or feedback with us on this thread :slight_smile:

Really great guide, got me running with auth0 authentication perfectly, but this could be an issue when adding more tests due to the api rate limit at auth0.

I have a conditional in the before() hook of my tests to check if I’m logged in by checking existence of an access-token. So posting to auth_url to login happens once during my tests.

But hitting /callback uses up the request callback too, so whats the recommended way to not use /callback at the start of every test?

Edit:
I did manage to stub the response that was taking up most of the API rate limit, it was running a GET request to /userinfo, I ran the get once and stored the response to be stubbed later. A guide on how to stub responses:

@bruno.krebs Great write up. That said, I’m looking for details on how to handle testing inviting users to my application through Cypress and Auth0. The workflow goes like this:

  1. As a privileged user, I invite someone to my application via their email
  2. The backend of my application sends them an invite
  3. The invite link goes to my landing page with the invitation key placed into sessionStorage
  4. The landing page redirects to my Auth0 provider, which of course I am bypassing with cy.request()

The only step I cannot automate is from step 2 to step 3. Is there a way to get the invitation key without causing security issues?

Thanks for the write-up! One question, though: my back-end server callback expects a code rather than an access_token. How can I get a code in the first request?

It would be nice if you included a description of how silent-auth would work in this flow. As soon as you try to use cy.visit('/another-page-in-my-app') it will cause a page refresh which will lose the access token we get in the cy.request callback (set in-memory) only. At that point, it will call auth0.checkSession() to see if there is an existing session with auth0 (doing the silent-auth flow). However, this will fail due to the face that we do not have a cookie set on the auth0 domain.

In the normal browser flow, right before auth0 login page redirects back to the SPA it will set a cookie auth0 on the domain with a value that matches the user session. Is there a way to obtain that session token and set it manually for using cy.setCookie?

Or perhaps there is a different way of doing this? Maybe using something like the offline flow?

1 Like

@michael agreed! This post was a great help and got me most of the way there, but I’m encountering the same issue. Any advice for programmatically authenticating using silent auth?

1 Like

I haven’t tried it yet, but it is possible to capture a user session cookie from your Auth0 domain and set it programatically on cypress. As long as the session doesn’t expire in a long time say 1 year or even longer (I would set it to like +10 years if possible), it should probably work.

I’m not sure there is another way of doing silent auth. Another solution would be to stub out Auth0 completely on cypress test runs.

It would be great if Auth0 provided such a library for cypress. However, it is a bit complex since it involves responses from the server as well.

Something like this: GitHub - jubos/fake-s3: A lightweight server clone of Amazon S3 that simulates most of the commands supported by S3 with minimal dependencies which can run locally and mimic Auth0 req/res

2 Likes

@bruno.krebs I would like to be able to implement a Cypress “login” command that exercises my callback with a code (i.e. authorization code) that would typically be acquired via OAuth exchange. Is there an Auth0 API endpoint that allows me to get a code that I can then use for my callback e.g. https://mydomain.com/callback?code=abcd1234?

2 Likes

If you have MFA enabled, how would you recommend getting past it for just the Cypress user?

When I run the test I get a 500 error “Authorization server not configured with default connection.”

2 Likes

Did you get it working? It seems silent authentication does not work with /oauth/token. Check session always returning login required exception.

1 Like

I’ve been unable to get past the “login_required” exception you mention. I’ve tried setting the auth0 session cookie manually, but maybe I’m not setting the correct cookie or value.

Not sure if this affects your tests, but there’s a bug with cypress v3.1.1 and above where cookies aren’t being set correctly: https://github.com/cypress-io/cypress/issues/3221

1 Like

I was able to fix this by changing my tenant settings (the Default Directory property, mentioned in the section Auth0 Setup & Configuration above). It was a little hard to find. On your dashboard, click on your account dropdown in the upper-right, then click “settings.” The property you want to change is under “API Authorization Settings.” Setting this to “Username-Password-Authentication” as mentioned in the article got me past the error.

1 Like

So how do you test a restricted page? This just times out:

 describe('Restricted page', () => {
  it('should render the page', () => {
    cy.login().then(() => {
      cy.visit('/restricted')
      cy.get('h1').contains('Restricted')
    })
  })
})
1 Like

With the new Auth0-spa-js package, I can not use cy.request() to get the authorization code from login API because the URL now has a random state.
Do you have a workaround solution for this issue?

3 Likes

Did you figure this out? I’m having the same issues, I can’t get this to work because it gives me an invalid token error. Saying the state does not match

1 Like

For now, this is the workaround solution of me.

  1. Disable chrome security in Cypress config.
  2. Login through the auth0 page (we will redirect to log-in page and log out due to the fact that I cannot generate the random state in the new auth0 package)

Note: If you’re not custom login page in auth0, use the classic page in Universal Login. I found that the new UI of Auth0 login page has a lot of security enhance that prevents us render auth0 in an iframe.


Then, Go to Auth0 → Tenant Setting → Advanced → Enable Clickjacking Protection to allow auth0 load in an iframe.
image

Ok, that all the step that I did to make it work. Hope this help you

2 Likes

Thanks a ot for sharing it with the rest of community @corruptedmonk!

I wish a solution like this post will be available for Auth0-spa-js package soon!

1 Like