Nextjs-auth0: Expose the CookieHelper for testing with Cypress

Created on 11 Mar 2021  路  5Comments  路  Source: auth0/nextjs-auth0

Describe the problem you'd like to have solved

For codebases that use auth0/react and cypress, it has been previously recommended by both companies to use a POST endpoint to get an access token programmatically then set the localStorage with the output of the body from the POST endpoint.

We'd like to continue testing in a similar way here, but now need to know how to encrypt a cookie, which we can then set.

Please refer to https://github.com/NeonLaw/codebase/blob/a2009879cf2bfaed5241f5a2a9789fb36b6c5bbf/web/cypress/support/commands.js#L29-L40, which contains code that was working with @auth0/react but cannot work with this library as cookies are encrypted.

I tried out https://github.com/sir-dunxalot/cypress-nextjs-auth0, which is great, but uses a different encryption mechanism, (@hapi/iron instead of the jose library) and therefore cannot work out-of-the-box with this library.

Describe the ideal solution

It would be nice to be able to write a custom command like this:

Cypress.Commands.add('login', ({ username, password }) => {
  cy.log(`Logging in as ${username}`);
  const clientId = Cypress.env('AUTH0_CLIENT_ID');
  const audience = Cypress.env('AUTH0_AUDIENCE');
  const scope = Cypress.env('AUTH0_SCOPE');

  const options = {
    body: {
      audience: audience,
      client_id: clientId,
      client_secret: Cypress.env('AUTH0_CLIENT_SECRET'),
      grant_type: 'http://auth0.com/oauth/grant-type/password-realm',
      password,
      realm: 'Username-Password-Authentication',
      scope,
      username,
    },
    headers: {
      'Content-Type': 'application/json',
    },
    method: 'POST',
    url: Cypress.env('API_URL')
  };

  cy.request(options).then(({ body }) => {
    const { access_token } = body;

    const cookieStore = new CookieStore({
       secret: Cypress.env('AUTH0_SECRET');
     });

     const encryptedCookie = cookieStore.encrypt(access_token);

     cy.setCookie('appSession', encryptedCookie);
  });
});

Alternatives and current work-arounds

Right now, I'd have to monkey/patch or copy too much code into my Cypress tests or update the other library above to get this to work. It'd be nice if there was a first-class way to programmatically encrypt cookies for testing. This could work with more libraries than just Cypress.

Additional information, if any

I'll try my best to clarify anything that's unclear here. Thanks!

enhancement

Most helpful comment

Hi @shicholas - thanks for raising this

We're looking into adding better support for end to end testing, but we need to be careful that features we add can't be abused in production.

In the meantime - I've created a PR to update https://github.com/sir-dunxalot/cypress-nextjs-auth0 - which should give you an idea for how to implement this yourself, regardless of if it get's merged or not.

Also, have a look at our sample app for options on stubbing the client side code.

All 5 comments

We have encountered the same issue. Would love first class support for this or a reasonable workaround.

Hi @shicholas - thanks for raising this

We're looking into adding better support for end to end testing, but we need to be careful that features we add can't be abused in production.

In the meantime - I've created a PR to update https://github.com/sir-dunxalot/cypress-nextjs-auth0 - which should give you an idea for how to implement this yourself, regardless of if it get's merged or not.

Also, have a look at our sample app for options on stubbing the client side code.

Closing this - but we do have something in our backlog to explore this further

Hi @adamjmcgrath - thanks for the provided example and PR, but is there any way that I could use my /api/auth/callback endpoint instead?

The reason for this is that I have some additional logic included in afterCallback that I wouldn't want to skip when handling the login.

Hi @HannuPousi - since your cypress tests run in the browser I'm not sure how you'd do this. You'd have to find some creative solution to this. Perhaps something like exporting your afterCallback function from a separate module, and call it with the session payload from a cypress task in your login command https://github.com/sir-dunxalot/cypress-nextjs-auth0/blob/c1bb2ae2d0fd9281140d285926b5dcfeaffdd670/src/commands/login.js#L44

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jkjustjoshing picture jkjustjoshing  路  4Comments

pasenidis picture pasenidis  路  4Comments

nodabladam picture nodabladam  路  7Comments

jvorcak picture jvorcak  路  4Comments

shansmith01 picture shansmith01  路  4Comments