Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Cypress:从API获取令牌,然后保存在本地存储中,并在另一个API中使用';然后返回第二个API的响应主体_Javascript_Json_Automated Tests_Cypress - Fatal编程技术网

Javascript Cypress:从API获取令牌,然后保存在本地存储中,并在另一个API中使用';然后返回第二个API的响应主体

Javascript Cypress:从API获取令牌,然后保存在本地存储中,并在另一个API中使用';然后返回第二个API的响应主体,javascript,json,automated-tests,cypress,Javascript,Json,Automated Tests,Cypress,我有一个API(我们称之为getToken),用于在其响应体中生成令牌。然后我调用该令牌并将其存储在另一个API的头中(我们称之为returnBody)。对于getTokenAPI使用localStorage是有意义的,因为此令牌可用于多个API。但是,如果我需要返回/显示后续API的响应体,例如returnBody,我对使用localStorage有疑问。在API的函数/命令中,它记录响应主体。但是,当我通过测试文件调用它时,它会生成null。 示例代码如下: commands.js: 测试文

我有一个API(我们称之为getToken),用于在其响应体中生成令牌。然后我调用该令牌并将其存储在另一个API的头中(我们称之为returnBody)。对于getTokenAPI使用
localStorage
是有意义的,因为此令牌可用于多个API。但是,如果我需要返回/显示后续API的响应体,例如returnBody,我对使用
localStorage
有疑问。在API的函数/命令中,它记录响应主体。但是,当我通过测试文件调用它时,它会生成null。 示例代码如下:

commands.js:

测试文件:


returnBody命令的body返回JSON响应。但是,从测试文件返回的值显示为空。

您可能需要从
返回体任务返回响应体:

Cypress.Commands.add('returnBody',(url,token)=>{
返回cy.request({/*选项*/})
。然后(响应=>{
让body=JSON.stringify(response.body);
柏木原木(体);
返回正文;//添加此行
});
});

另一种选择是使用固定装置将令牌存储在cypress侧

fixture.json:

commands.js:

test.js

如中所述:“您不能从自定义命令返回第三方承诺,因为这会中断cypress命令之间的链接。这是因为.then方法不同。”

因此,只需将请求主体返回为:

Cypress.Commands.add('returnBody',(url,token)=>{
返回cy.request({/*选项*/})
.其(“机构”);
});
然后,在测试中,您可以执行以下操作:

it(“应该返回foo值”,()=>{
cy.returnBody(url,标记)。然后(返回的值=>{
cy.log(返回的_值);
expect(返回的_值).to.deep.equal(“foo值”);
})
})

我收到这个错误:CypressError:cy.then()失败,因为您混淆了异步和同步代码。@er123尝试将
cy.log()
替换为
Cypress.log()
我认为这与命令“log”无关。即使如此,我还是尝试了它,并得到了以下错误:CypressError:Cypress.log()只能用options对象调用。您的参数是:“null”。另外,很抱歉坦率地说,您的初始解决方案似乎是反模式的,其中一个返回整个cypress命令(cy.request),然后在内部,再次返回值(body)。感谢@javier brea,但这仍然在我的测试文件中返回空值:
cy.returnBody(url,tokenJSON.token)。然后((返回的_值)=>{cy.log(返回的_值)})
。抱歉@er123,你说得对,回复承诺不起作用。我在这里找到了解决办法。我编辑了这个示例,测试了它,现在它可以工作了。是的,我最初使用
cy.writeFile
尝试了这个方法,但是我的运行变得有点不稳定。我还必须将
watchForFileChanges
设置为
false
。虽然这是另一个很好的选择,但对于我的用例,我希望它运行得更快,并且这种方法可能会影响性能,因为我需要不断调用令牌,这将不断更新fixture文件,这是我在现阶段不太热衷于使用的另一层。
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)
        })
})
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)
            })
        })

    })
})
{"bearerToken":""
.
.
.}
cy.fixture('testData.json').as('testData')
.
.
.then(bearerToken => {
            this.testData.bearerToken = JSON.stringify(bearerToken)
            cy.log('Token generated: ' + bearerToken.token)
            }
        )
describe('Return value of 2nd API', ()=> {
    before(() => {
        cy.getToken() //Run this once to generate token for the entire test suite
    })

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

    })
})