cypresscross-domainauth0cypress-custom-commands

Cypress Issues Integrating Auth0 with cy.origin and cy.session


I am currently facing a persistent issue while testing my application with Cypress, particularly when attempting to handle login through Auth0. To work around cross-origin issues, I followed the documentation and used cy.origin and cy.session, but have not been able to overcome the problem. :(

The error I got:

CypressError: Timed out retrying after 4000ms: The command was expected to run against origin https://xxxxxxxx.auth0.com but the application is at origin https://xxxxxxxxx-app-web.vercel.app. This commonly happens when you have either not navigated to the expected origin or have navigated away unexpectedly. Using cy.origin() to wrap the commands run on https://xxxxxxxxxx-app-web.vercel.app will likely fix this issue. cy.origin('https://xxxxxxxxx-app-web.vercel.app', () => { <commands targeting https://xxxxxxxxxxx-app-web.vercel.app go here> })

The setup in cy.session means the second argument being passed which aims directly to the cy.origin part.

Despite going through Auth0 and Cypress documentation, I haven't been able to find a solution, I'm quite new to cypress and automation

enter image description here

For reference, here's my commands.js configuration:

const baseUrl = Cypress.config('baseUrl')

Cypress.Commands.add('loginSession', (email, password) => {
  cy.session(([email, password]), () => {
    cy.visit(baseUrl); 

    cy.origin(Cypress.env('CYPRESS_AUTH0_USER'), 
      {args: [email, password]},
      ([email, password]) => {
        cy.get('#username').type(email); 
        cy.get('#password').type(password); 
        cy.get('button[data-action-button-primary="true"]').click(); 
      }
    );
    cy.url().should('include', Cypress.config('baseUrl'));
  })
});

My test:

describe('Main E2E Flow', () => {
  beforeEach(() => {
    cy.loginSession(Cypress.env('CYPRESS_EMAIL'), Cypress.env('CYPRESS_PASSWORD'));
  });

  it('Checks for Create Profile button for unauthenticated users', () => {
    cy.contains('Create a Profile').should('exist');
  });
});

Any assistance or suggestions on how to correctly configure the cy.origin and cy.session for Auth0 authentication in Cypress would be greatly appreciated.


Solution

  • It looks like the wrong domain (the app domain) is used as the URL parameter for the cy.origin() command.

    Since the controls accessed inside cy.origin() are auth-ish, they are probably served from the auth domain.

    cy.origin('https://xxxxxxxx.auth0.com',     // point at the domain where callback
                                                // code is working
      {args: [email, password]},
      ([email, password]) => {
        cy.get('#username').type(email); 
        cy.get('#password').type(password); 
        cy.get('button[data-action-button-primary="true"]').click(); 
      }
    )
    

    That's the first step to try. I've also seen mention that the code that navigates to the auth domain should also be inside the cy.origin() callback when there is a redirect involved

    Ref: cy-origin-and-immediate-redirect

    cy.origin('https://xxxxxxxx.auth0.com', {args: [email, password]}, ([email, password]) => {
    
        cy.visit('https://xxxxxxxxx-app-web.vercel.app')  // redirects to auth
    
        cy.get('#username').type(email); 
        cy.get('#password').type(password); 
        cy.get('button[data-action-button-primary="true"]').click(); 
      }
    )
    

    Not related, but you can also try putting the cy.url() check as a validation step for cy.session()

    Cypress.Commands.add('loginSession', (email, password) => {
      cy.session(([email, password]), () => {
        cy.visit(baseUrl); 
    
        cy.origin(Cypress.env('CYPRESS_AUTH0_USER'), // check is actually the auth URL
          {args: [email, password]},
          ([email, password]) => {
            cy.get('#username').type(email); 
            cy.get('#password').type(password); 
            cy.get('button[data-action-button-primary="true"]').click(); 
          }
        )
      },
      {
        validate() {
          // expect auth has returned to baseUrl (valid login only)
          cy.url().should('include', Cypress.config('baseUrl'))
        },
      })
    })