Cypress 使用 Pinia Vue3 的操作

发布于 2025-01-19 06:38:31 字数 1840 浏览 1 评论 0原文

我从这个视频中学习了一些柏树: https://wwww.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')
  })
})

和我的UserStore:

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))
        })
    },
  },
})

如何在Cypress测试中调用登录操作? 目前,作为一个解决方法,我在localstorage上写了这样的方法:

localStorage.setItem('username', 'user')

它可以正常工作,因为UserStore从LocalStorage捕获了此物品,并且像登录一样通过,但是我不喜欢这个解决方案,似乎脆弱了,我' D喜欢使用用于登录用户的操作。

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

main.js

视频显示该代码:

const vue = new Vue({...})
if(window.Cypress){
  window.app = app
}

在我的情况下。是:

const app = createApp(App)
if(window.Cypress){
  window.app = app
}

但是在柏树测试中,window.app它是未定义的...我不知道我将如何使用此问题访问USERSTORE ...就像Vuex一样。

I was learning some cypress from this video: https://www.youtube.com/watch?v=03kG2rdJYtc
I'm interested with he's saying at 29:33: "programatic login"
But he's using vue2 and Vuex.

My project is created with Vite and the state management is Pinia.
So how can I do a programatic login using the pinia action?

For example the welcome logged in user should see dashboard:

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

And my userStore:

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))
        })
    },
  },
})

How can I call the login action on the cypress test?
For now as a workaround I'm writing on a localstorage like:

localStorage.setItem('username', 'user')

And it works fine, because userStore catch this item from localstorage and passes like it's logged in... But I don't like this solution, seems fragile, and I'd like to use the action which is made for login users.

Another thing I tried is adding the app variable inside window but it doesn't work for me... don't understand why...

on main.js

The video shows that code:

const vue = new Vue({...})
if(window.Cypress){
  window.app = app
}

In my case it's:

const app = createApp(App)
if(window.Cypress){
  window.app = app
}

But in cypress tests the window.app it's undefined... I don't know how I would access to userStore using this... like it was vuex.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水晶透心 2025-01-26 06:38:31

以Pinia演示应用程序为例:

该商店在App.Vue中初始化。添加对新创建的商店的引用,以供柏树用于

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
    }
    ...

测试中,

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
      })

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

// 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
},
// 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')
      })
    })
  })

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

// 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')
    })
})

Using the Pinia demo app as an example:

The store is initialized in App.vue. Add a reference to the newly created store(s) for Cypress to use

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
    }
    ...

In the test

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
      })

The login action is asynchronous, so return the promise to allow Cypress to wait.

// 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
},
// 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')
      })
    })
  })

Alternatively, wait for the name to change on the page

// 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')
    })
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文