Cypress 使用 Pinia Vue3 的操作

sla*_*ast 8 e2e-testing cypress vuejs3 pinia

我从这个视频中学习了一些 cypress:https://www.youtube.com/watch? v=03kG2rdJYtc 我对他在 29:33 说的:“程序化登录”很感兴趣,但他正在使用 vue2 和 Vuex。

我的项目是用Vite创建的,状态管理是Pinia。那么如何使用 pinia 操作进行编程登录呢?

例如,欢迎登录的用户应该看到仪表板:

describe('Welcome', () => {
  it('logged in user should visit dashboard', () => {
    // login
    cy.visit('/')
    cy.url().should('contain', '/dashboard')
  })
})
Run Code Online (Sandbox Code Playgroud)

还有我的用户商店:

export const useUserStore = defineStore({
  id: 'user',
  state: () => ({
    username: ref(useLocalStorage('username', null)),
  }),
  getters: {
    isLoggedIn: (state) => state.username !== null,
  },
  actions: {
    login(username, password) {
      return useAuthLoginService(username, password)
        .then((response) => {
          this.username = response.username
        })
        .catch((error) => {
          return Promise.reject(new Error(error))
        })
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

我如何调用logincypress 测试的操作?现在作为一种解决方法,我正在本地存储上编写如下内容:

localStorage.setItem('username', 'user')
Run Code Online (Sandbox Code Playgroud)

它工作正常,因为 userStore 从本地存储捕获此项目并像登录一样传递...但我不喜欢这个解决方案,看起来很脆弱,我想使用为登录用户所做的操作。

我尝试的另一件事是在窗口内添加应用程序变量,但它对我不起作用......不明白为什么......

main.js

视频显示了该代码:

const vue = new Vue({...})
if(window.Cypress){
  window.app = app
}
Run Code Online (Sandbox Code Playgroud)

就我而言,它是:

const app = createApp(App)
if(window.Cypress){
  window.app = app
}
Run Code Online (Sandbox Code Playgroud)

但在 cypress 测试中,window.app它是未定义的...我不知道如何使用它访问 userStore...就像它是 vuex 一样。

Fod*_*ody 8

以 Pinia 演示应用程序为例:

商店在 App.vue 中初始化。添加对新创建的商店的引用以供 Cypress 使用

export default defineComponent({
  components: { Layout, PiniaLogo },

  setup() {
    const user = useUserStore()
    const cart = useCartStore()
 
    if (window.Cypress) {
      window.store = {user, cart)   // test can see window.store
    }
    ...
Run Code Online (Sandbox Code Playgroud)

在测试中

let store;  

describe('Pinia demo with counters', () => {

  beforeEach(() => {
    cy.viewport(1000, 1000)
    cy.visit(`http://localhost:${PORT}`)
      .then(win => store = win.store)       // get app's store object 
  })

  it('works', () => {
    cy.wait(500) // wait for the JS to load
      .then(() => store.cart.addItem('Cypress test item'))  // invoke action
      .then(() => {
        const item1 = store.cart.items[0]                   // invoke getter
        cy.wrap(item1)
          .should('have.property', 'name', 'Cypress test item')  // passes
      })
Run Code Online (Sandbox Code Playgroud)

登录操作是异步的,因此返回承诺以允许 Cypress 等待。

// user.js

async login(user, password) {
  const userData = await apiLogin(user, password)

  this.$patch({
    name: user,
    ...userData,
  })
  return userData        // this returns a promise which can awaited
},
Run Code Online (Sandbox Code Playgroud)
// main.spec.js

describe('Pinia demo with counters', () => {
  beforeEach(() => {
    cy.viewport(1000, 1000)
    cy.visit(`http://localhost:${PORT}`).then(win => {
      store = win.store

      // default name in store before login
      cy.wrap(store.user.name).should('eq', 'Eduardo')

      // logging in
      store.user.login('ed', 'ed').then(() => {        // wait for API call
        cy.wrap(store.user.name).should('eq', 'ed')
      })
    })
  })
Run Code Online (Sandbox Code Playgroud)

或者,等待页面上的名称更改

// main.spec.js

cy.visit(`http://localhost:${PORT}`).then(win => {
  store = win.store

  // default name in store
  cy.wrap(store.user.name).should('eq', 'Eduardo')

  // logging on
  store.user.login('ed', 'ed')  
  cy.contains('Hello ed')              // waits for name on page to change
    .then(() => {          
      cy.wrap(store.user.name).should('eq', 'ed')
    })
})
Run Code Online (Sandbox Code Playgroud)

  • 该代码仅在测试期间有效 - 请参阅“if (window.Cypress)...” (5认同)