Cypress 使用来自 Pinia Vue3 的动作
Cypress using actions from Pinia Vue3
我正在从这个视频中学习一些柏树: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')
})
})
还有我的 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 测试中调用 login
操作?
现在作为一种解决方法,我正在写一个本地存储,如:
localStorage.setItem('username', 'user')
它工作正常,因为 userStore 从 localstorage 捕获这个项目并像它登录一样传递...但我不喜欢这个解决方案,看起来很脆弱,我想使用所做的操作对于登录用户。
我尝试的另一件事是在 window 中添加 app 变量,但它对我不起作用...不明白为什么...
在 main.js
视频显示代码:
const vue = new Vue({...})
if(window.Cypress){
window.app = app
}
在我的例子中是:
const app = createApp(App)
if(window.Cypress){
window.app = app
}
但是在 cypress 测试中 window.app
它是未定义的...我不知道如何使用它访问 userStore...就像它是 vuex。
这可能取决于商店的设置方式。
在 Pinia 演示应用程序中,商店在 App.vue 中初始化,所以这是我添加 Cypress 使用的引用的地方
export default defineComponent({
components: { Layout, PiniaLogo },
setup() {
const user = useUserStore()
const cart = useCartStore()
if (window.Cypress) {
window.store = {user, cart)
}
...
然后在测试中(使用提供的main.spec.js
)
let store;
describe('Pinia demo with counters', () => {
beforeEach(() => {
cy.viewport(1000, 1000)
cy.visit(`http://localhost:${PORT}`).then(win => store = win.store)
})
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
})
登录操作是异步的,所以我想您可能需要return允许赛普拉斯等待的承诺。
// 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(() => {
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')
// loggin 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')
})
})
请注意,存储命令 运行 before 赛普拉斯命令在同一个块中,因此可能会在某些地方绊倒你。
我正在从这个视频中学习一些柏树: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')
})
})
还有我的 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 测试中调用 login
操作?
现在作为一种解决方法,我正在写一个本地存储,如:
localStorage.setItem('username', 'user')
它工作正常,因为 userStore 从 localstorage 捕获这个项目并像它登录一样传递...但我不喜欢这个解决方案,看起来很脆弱,我想使用所做的操作对于登录用户。
我尝试的另一件事是在 window 中添加 app 变量,但它对我不起作用...不明白为什么...
在 main.js
视频显示代码:
const vue = new Vue({...})
if(window.Cypress){
window.app = app
}
在我的例子中是:
const app = createApp(App)
if(window.Cypress){
window.app = app
}
但是在 cypress 测试中 window.app
它是未定义的...我不知道如何使用它访问 userStore...就像它是 vuex。
这可能取决于商店的设置方式。
在 Pinia 演示应用程序中,商店在 App.vue 中初始化,所以这是我添加 Cypress 使用的引用的地方
export default defineComponent({
components: { Layout, PiniaLogo },
setup() {
const user = useUserStore()
const cart = useCartStore()
if (window.Cypress) {
window.store = {user, cart)
}
...
然后在测试中(使用提供的main.spec.js
)
let store;
describe('Pinia demo with counters', () => {
beforeEach(() => {
cy.viewport(1000, 1000)
cy.visit(`http://localhost:${PORT}`).then(win => store = win.store)
})
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
})
登录操作是异步的,所以我想您可能需要return允许赛普拉斯等待的承诺。
// 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(() => {
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')
// loggin 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')
})
})
请注意,存储命令 运行 before 赛普拉斯命令在同一个块中,因此可能会在某些地方绊倒你。