6 votes

Cyprès : Réutilisation du jeton d'authentification sur plusieurs tests d'API

J'ai une API Rest qui génère un jeton. Ce jeton de session est utilisé dans plusieurs API REST comme autorisation. Jeton de porteur . J'ai utilisé ceci comme référence : https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/logging-in__jwt/cypress/integration/spec.js

Cependant, dans cet exemple, la fonction permettant de générer le jeton est intégrée au test. J'ai essayé de créer une commande personnalisée qui devrait être stockée localement mais elle n'est pas prise en compte par le test. Notez qu'aucune valeur de retour n'est incluse dans la commande personnalisée.

Mon code ci-dessous sous support/commandes.js :

let identity
Cypress.Commands.add('postToken', () => {
    cy.request({
        method: 'POST',
        url: Cypress.env('api_identity_url'), //get from cypress.env.json
        form: true, //sets to application/x-www-form-urlencoded
        body: {
            grant_type: 'client_credentials',
            scope: 'xero_all-apis'
        },
        auth: {
            username: Cypress.env('api_identity_username'),
            password: Cypress.env('api_identity_password')
        }
    })
        .its('body')
        .then((response) => {
            identity = response
            window.localStorage.setItem('identity', JSON.stringify(identity))
            cy.log(identity.access_token)
        })
})

Mon test :

context('Check token details', () => {
  it('Check token', () => {
      cy.postToken()
      const bToken = window.localStorage.getItem('identity')
      cy.log(bToken)
  })
})

Lorsque je lance le test, le journal indique null pour "identité". Cependant, il affiche la valeur actuelle dans la commande personnalisée où j'ai placé cy.log(identity.access_token) J'ai essayé d'utiliser cy.writeFile mais je ne pense pas que ce soit une méthode propre. Il doit y avoir un moyen de faire passer les données entre les fonctions et les différentes classes.

Exemple de format JSON :

{
  "token": "<this is the value I would like to use for other API's authorisation bearer token>",
  "expires_in": 1200,
  "token_type": "Bearer"
}

7voto

Javier Brea Points 171

Vous pouvez utiliser le cypress-localstorage-commandes pour faire persister localStorage entre les tests.

En support/commands.js :

import "cypress-localstorage-commands";

Cypress.Commands.add('postToken', () => {
  cy.request({
    method: 'POST',
    url: Cypress.env('api_identity_url'), //get from cypress.env.json
    form: true, //sets to application/x-www-form-urlencoded
    body: {
      grant_type: 'client_credentials',
      scope: 'xero_all-apis'
    },
    auth: {
      username: Cypress.env('api_identity_username'),
      password: Cypress.env('api_identity_password')
    }
  })
  .its('body')
  .then(identity => {
    cy.setLocalStorage("identity_token", identity.token);
  });
});

Dans vos tests :

describe("postToken", ()=> {
  before(() => {
    cy.postToken();
    cy.saveLocalStorage();
  });

  beforeEach(() => {
    cy.restoreLocalStorage();
  });

  it("should exist identity in localStorage", () => {
    cy.getLocalStorage("identity_token").should("exist");
    cy.getLocalStorage("identity_token").then(token => {
      console.log("Identity token", token);
    });
  });

  it("should still exist identity in localStorage", () => {
    cy.getLocalStorage("identity_token").should("exist");
    cy.getLocalStorage("identity_token").then(token => {
      console.log("Identity token", token);
    });
  });
});

0voto

jiri.hofman Points 118

Merci Javier de m'avoir montré le cypress-localstorage-commands paquet. J'ai commencé à l'utiliser. Avant cela, j'obtenais le jeton de connexion comme ceci.

describe('Record audit', () => {
    let token = null;

    before(() => {
        cy.login().then((responseToken) => { // or postToken() in your case
            token = responseToken;
        });
    });

    it('I can use the token here', () => {
        cy.log(token);
    });
});

La seule différence est que mon login renvoie le jeton. Cela devrait ressembler à ceci dans votre code

// commands.js

.then((response) => {
    identity = response
    window.localStorage.setItem('identity', JSON.stringify(identity))
    cy.log(identity.access_token)
    return identity.access_token
})

-1voto

Ornella Luna Points 1

J'ai utilisé ce code dans commmand.js

var headers_login = new Headers()
headers_login.append('Content-Type', 'application/json')

Cypress.Commands.add('get_token', (username, password)=>{
var token = ""
cy.request({
    method: 'POST',
    url: Cypress.env("api") + "users/getToken",
    failOnStatusCode: false,
    json: true,
    form: true,
    body: {username: username, password: password},
    headers: headers_login
 }).then((json) => {
    //cy.setLocalStorage('token', json.body.response.data.token)   
    token = json.body.response.data.token
    return token;
 }) }) 

Ensuite, dans votre test, ajoutez ce code

describe('test', ()=>{
 before(()=>{
    cy.get_token('username', 'password').then(youToken => {
        cy.visit('/', {
             onBeforeLoad: function (window) {
                window.localStorage.setItem('token', youToken);
             }
         })
     }) 
     cy.close_welcome()        
 })
 it('test 001', ()=>{
       // contain test 
 })})
afterEach(()=>{cy.clearLocalStorage('token')})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X