Cypress.io make async request in custom login command

Viewed 2060

I want to configure a custom login command in which I have to make a signIn call which returns a promise.

commands.js:

Cypress.Commands.add("login", () => {
  AuthLib.signIn(username, password).then((data) => {
    cy.setLocalStorage("accessToken", data.accessToken);
  });

AuthLib.signIn() returns a promise.

Then I want to use this command in an before block:

  before(() => {
    cy.login();
    cy.saveLocalStorage();
  });

I notice that the promise is not resolved. A 'hacky' fix would be to add cy.wait(4000) between login() and saveLocalStorage(). But that makes my test depend on the loading time of the auth server

I found this 'related' issue: Cypress.io How to handle async code where https://www.npmjs.com/package/cypress-promise is referred. But this library cannot be used in before or beforeEach

How can I await the promise returned from login() / make sure the promise from login() is resolved before doing cy.saveLocalStorage()?

Update

I added the examples of what works and does not work in : https://github.com/Nxtra/Cypress-Amplify-Auth-Example/blob/main/cypress/support/commands.js

A solution would be to start with cy.then():

Cypress.Commands.add("login", () => {
  cy.then(() => AuthLib.signIn(username, password)).then((data) => {
    cy.setLocalStorage("accessToken", data.accessToken);
  });
1 Answers

Make sure that you return that promise inside Cypress.Commands.add callback. It's a bit confusing to deal with promises in Cypress context, since a lot of async behavior is magically handled within cy. commands.

Cypress.Commands.add("login", () => {
  return AuthLib.signIn(username, password).then((data) => {
    cy.setLocalStorage("accessToken", data.accessToken);
  });
});

Other solution:

Cypress.Commands.add("login", () => {
  return AuthLib.signIn(username, password);
});

before(() => {
  cy.login();
  cy.setLocalStorage("accessToken", data.accessToken);
});
Related