赛普拉斯:从API获取令牌,然后保存在本地存储中,并在另一个API的标头中使用,然后返回第二个API的响应主体 [英] Cypress: Get token from API then save in local storage and use in another API's header then return the response body of the 2nd API

查看:131
本文介绍了赛普拉斯:从API获取令牌,然后保存在本地存储中,并在另一个API的标头中使用,然后返回第二个API的响应主体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个API(我们将其称为 getToken )可以在其响应主体中生成令牌.然后,我调用该令牌并将其存储在另一个API的标头中(我们将其称为 returnBody ).为 getToken API使用localStorage是有意义的,因为此令牌可重复用于多个API.但是,如果要返回/显示后续API的响应正文(例如 returnBody ),我会怀疑是否使用localStorage.在API的功能/命令内部,它记录响应主体.但是,当我通过测试文件调用它时,它会生成 null . 下面的示例代码:

I have an API (let's call it getToken) to generate a token in its response body. I then call that token and store in the header of another API (let's call it returnBody). It makes sense to use localStorage for the getToken API as this token is re-usable for multiple API's. However, I am having doubts using localStorage if I need to return / display the response body of the succeeding API's such as returnBody. Inside the API's function/command, it logs the response body. However, when I call it via the test file, it generates null. Sample code below:

commands.js:

commands.js:

Cypress.Commands.add('getToken', () => { //API to generate token
    cy.request({
        method: 'POST',
        url: 'https://someAPItoGenerateToken',
        form: true, //sets to application/x-www-form-urlencoded
        body: {
            grant_type: 'credentials',
            scope: 'all-apis'
        },
        auth: {
            username: Cypress.env('api_username'),
            password: Cypress.env('api_password')
        }
    })
        .its('body')
        .then(bearerToken => {
            cy.setLocalStorage('bearerToken', JSON.stringify(bearerToken))
            cy.log('Token generated: ' + bearerToken.token)
            }
        )
})

Cypress.Commands.add('returnBody', (url, token) => { //API to return some values
    return cy.request({
        method: 'GET',
        url: url,
        auth: {
            bearer: token
        }
    })
        .then((response) => {
            // Stringify JSON the body.
            let body = JSON.stringify(response.body)
            cy.log(body)
        })
})

测试文件:

test file:

describe('Return value of 2nd API', ()=> {
    before(() => {
        cy.getToken() //Run this once to generate token for the entire test suite
        cy.saveLocalStorage()
    })

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

    it('Return value of 2nd API', () => {
        cy.getLocalStorage('bearerToken').should('exist')
        cy.getLocalStorage('bearerToken').then(bearerToken => {
            const tokenJSON = JSON.parse(bearerToken)
            const url = 'https://someAPItoReturnJSONbody'
            cy.returnBody(url, tokenJSON.token).then((returned_value) => {
                cy.log(returned_value)
            })
        })

    })
})

returnBody命令中的

body 返回JSON响应.但是,测试文件中的 returned_value 显示为空.

body from the returnBody command returns the JSON response. However, returned_value from the test file displays null.

推荐答案

此问题:您无法从自定义命令返回第三方承诺,因为这会中断cypress命令之间的链接.这是因为.then方法不相同."

As commented in this issue: "You cannot return a 3rd party promise from a custom command because this breaks the chaining between cypress commands. This is because the .then methods are not the same."

因此,只需将请求正文返回为:

So, simply return the request body as:

Cypress.Commands.add('returnBody', (url, token) => {
  return cy.request({ /* options */ })
    .its("body");
});

然后,在您的测试中,您可以执行以下操作:

Then, in your test you can do:

it("should return foo value", () => {
  cy.returnBody(url, token).then(returned_value => {
    cy.log(returned_value);
    expect(returned_value).to.deep.equal("foo-value");
  })
})

这篇关于赛普拉斯:从API获取令牌,然后保存在本地存储中,并在另一个API的标头中使用,然后返回第二个API的响应主体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆