Implement login command and access vuex store

2020-07-13 11:21发布

I have a login process where after sending a request to the server and getting a response, I do this:

 this.$auth.setToken(response.data.token);
 this.$store.dispatch("setLoggedUser", {
     username: this.form.username
 });

Now I'd like to emulate this behavior when testing with cypress, so i don't need to actually login each time I run a test.

So I've created a command:

Cypress.Commands.add("login", () => {
  cy
    .request({
      method: "POST",
      url: "http://localhost:8081/api/v1/login",
      body: {},
      headers: {
        Authorization: "Basic " + btoa("administrator:12345678")
      }
    })
    .then(resp => {
      window.localStorage.setItem("aq-username", "administrator");
    });

});

But I don't know how to emulate the "setLoggedUser" actions, any idea?

2条回答
Deceive 欺骗
2楼-- · 2020-07-13 11:38
  • Step 1: Inside main.js provide the store to Cypress:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

if (window.Cypress) {
  // Add `store` to the window object only when testing with Cypress
  window.store = store
}
  • Step 2: Inside cypress/support/commands.js add a new command:
Cypress.Commands.add('login', function() {
  cy.visit('/login') // Load the app in order `cy.window` to work
  cy.window().then(window => { // .then() to make cypress wait until window is available
    cy.wrap(window.store).as('store') // alias the store (can be accessed like this.store)
    cy.request({
      method: 'POST',
      url: 'https://my-app/api/auth/login',
      body: {
        email: 'user@gmail.com',
        password: 'passowrd'
      }
    }).then(res => {
      // You can access store here
      console.log(this.store)
    })
  })
})
  • Step 4: Inside cypress/integration create a new test
describe('Test', () => {
  beforeEach(function() {
    cy.login() // we run our custom command
  })

  it('passes', function() { // pass function to keep 'this' context
    cy.visit('/')
    // we have access to this.store in our test
    cy.wrap(this.store.state.user).should('be.an', 'object')
  })
})
查看更多
Emotional °昔
3楼-- · 2020-07-13 11:40

In your app code where you create the vuex store, you can conditionally expose it to Cypress:

const store = new Vuex.Store({...})

// Cypress automatically sets window.Cypress by default
if (window.Cypress) {
  window.__store__ = store
}

then in your Cypress test code:

cy.visit()
// wait for the store to initialize
cy.window().should('have.property', '__store__')

cy.window().then( win => {
  win.__store__.dispatch('myaction')
})

You can add that as another custom command, but ensure you have visited your app first since that vuex store won't exist otherwise.

查看更多
登录 后发表回答