Home > Net >  Returning a value from a cypress command / request
Returning a value from a cypress command / request

Time:08-21

I would like to return an access token from a cypress request, I am doing this in commands as it will be used frequently, the current code is using cy.wrap but this feels very cumbersome for something so simple.

Cypress.Commands.add(
  'getToken',
  (email: string, password: string) => {
    cy.request('POST', `/token`, {
      email,
      password,
    }).then(({ body }) => cy.wrap(body.access_token));
  }
);

When this is used I have to do the following:

Cypress.Commands.add(
  'createCustomAudience',
  (queries: string[]) => {
    cy.getToken('email', 'password').then((token) => {
      cy.request({
        method: 'POST',
        url: `/audiences/custom`,
        body: {
          queries,
        },
        auth: { bearer: token },
      })
        .then(({ body }) => cy.wrap(body))
        .then((body) => cy.log(body as unknown as string));
    });
  }
);

Just to log the body I have to call .then twice and wrap it again and then double coerce!

This code works but surely there is a nicer was to do this, more async/await style - or maybe there is a way to just use plain JS/TS to do this?

I am using Cypress v10.6.0.

CodePudding user response:

You will have to return the chain of Cypress commands that yields the value you want to use.

Also, you can use .its() to get the access_token.

Cypress.Commands.add(
  'getToken',
  (email: string, password: string) => {
    return cy.request('POST', `/token`, {
      email,
      password,
    }).its('body.access_token');
  }
);

CodePudding user response:

You don't need a cy.wrap(), or a return in the Cypress command, or type casting.

You do need custom declarations for the commands, and it's easiest to put them in cypress/support/index.d.ts

/// <reference types="cypress" />

declare namespace Cypress {
  interface Chainable {
    getToken(email: string, password: string): Chainable<string>
    createCustomAudience(queries: string[]): Chainable<string>
  }
}

Make sure there's an entry in tsconfig.json include to find it:

{
  "compilerOptions": {
    ...
  },
  "include": [
    "**/*.cy.{js,ts,jsx,tsx}",   // this catches your custom index.d.ts
    ...
  ]
}

Test

Cypress.Commands.add('getToken', (email, password) => {

  cy.request('POST', '/token', {      // command result is automatically returned 
    email,
    password,
  })
  .then(response => response.body.access_token)  // modifies the result 
})

Cypress.Commands.add('createCustomAudience', (queries) => {
  cy.getToken('email', 'password').then((token) => {
    cy.request({
      method: 'POST',
      url: `/audiences/custom`,
      body: {
        queries,
      },
      auth: { bearer: token },
    })
    .then(response => response.body)   // type is known from index.d.ts
  });
})
  • Related