在 Cypress 中设置本地存储

新手上路,请多包涵

对于我们的一个应用程序,我需要设置本地存储以绕过登录页面过程。

我有以下函数将返回我需要设置的 accessToken。此功能在节点中运行时有效。

 async function getAccessToken(email, pwd) {
    const form = {email: email, password: pwd};
    let config = {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        }
    };
    const accessToken = await axios.post(`${process.env.API_URL}/loginWithToken`, qs.stringify(form), config);
    console.log(accessToken.data.accessToken);
    return accessToken.data.accessToken
}

我正在尝试创建一个将设置本地存储的 cypress 命令,然后访问该应用程序。运行时,我收到一个错误,提示我从一个命令返回了一个 promise,同时还在该 promise 中调用了一个或多个 cy 命令。

 Cypress.Commands.add("logInAs", async(Useremail, Userpwd, TMURL) => {
    var accessToken = cy.task('getAccessToken', {email: Useremail, pwd: Userpwd
    }).then(Visit =>{
        window.localStorage.setItem("accessToken", accessToken);
        window.localStorage.setItem("refreshToken", accessToken);
        cy.visit(`${process.env.TM_API_URL}/`+TMURL+``);
    });
});

我还尝试了以下 cypress 命令

require('dotenv').config();

Cypress.Commands.add('logInAs3', (Useremail, Userpwd, TMURL) => {
        cy.request({
            method: 'POST',
            url: `${process.env.API_URL}/loginWithToken`,
            body: {
                user: {
                    email: Useremail,
                    password: Userpwd,
                }
            }
        })
            .then((resp) => {
                window.localStorage.setItem('accessToken', resp.body.data.data.accessToken);
                window.localStorage.setItem('refreshToken', resp.body.data.data.accessToken);
                cy.visit(`${process.env.TM_API_URL}/`+TMURL+``, {failOnStatusCode: false})
            })
    });

但是我收到以下错误。为了获取访问令牌,我需要发布到的 URL 与基本 URL 是不同的域。所以在帖子中使用 base 对我来说不起作用。

cy.request() 必须提供一个完全限定的 url - 一个以 ‘http’ 开头的。默认情况下,cy.request() 将使用当前窗口的原点或 cypress.json 中的“baseUrl”。这些值都不存在。

原文由 TestRaptor 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 744
2 个回答

试试这个:

cypress.json

 {
  "env": {
    "EXTERNAL_API": "https://jsonplaceholder.typicode.com/todos/1"
  }
}

support/commands.js

 Cypress.Commands.add('logInAs3', (Useremail, Userpwd, TMURL) => {
  cy.request({
    method: 'POST',
    url: `${Cypress.env('EXTERNAL_API')}/loginWithToken`,
    body: {
      user: {
        email: Useremail,
        password: Userpwd,
      }
    }
  })
    .its('body')
    .then((body) => {
      window.localStorage.setItem('accessToken', body.data.data.accessToken);
      window.localStorage.setItem('refreshToken', body.data.data.accessToken);
    })
});

在你的测试中

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

it('check localStorage token', () => {
  cy.visit()
  expect(localStorage.getItem('accessToken')).not.null
  expect(localStorage.getItem('refreshToken')).not.null
})

原文由 Danny 发布,翻译遵循 CC BY-SA 4.0 许可协议

根据@Danny 的回答,您可以使用 cypress-localstorage-commands 包来保留 localStorage 并为块中的所有测试重用相同的用户会话:

cypress.json

 {
  "env": {
    "EXTERNAL_API": "https://jsonplaceholder.typicode.com/"
  }
}

support/commands.js

 import "cypress-localstorage-commands";

Cypress.Commands.add('logInAs', (UserEmail, UserPwd) => {
  cy.request({
    method: 'POST',
    url: `${Cypress.env('EXTERNAL_API')}/loginWithToken`,
    body: {
      user: {
        email: UserEmail,
        password: UserPwd,
      }
    }
  })
    .its('body')
    .then((body) => {
      cy.setLocalStorage("accessToken", body.data.accessToken);
      cy.setLocalStorage("refreshToken", body.data.refreshToken);
    });
});

在你的测试中:

 describe("when user FOO is logged in", ()=> {
  before(() => {
    cy.logInAs("foo@foo.com", "fooPassword");
    cy.saveLocalStorage();
  });

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

  it('should exist accessToken in localStorage', () => {
    cy.getLocalStorage("accessToken").should("exist");
  });

  it('should exist refreshToken in localStorage', () => {
    cy.getLocalStorage("refreshToken").should("exist");
  });
});

原文由 Javier Brea 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题