Rewrite Cypress mount() Command to Provide a Default Store to all Components

Filip Hric
InstructorFilip Hric
Share this video with your friends

Social Share Links

Send Tweet

Every component test that uses Pinia needs to have Pinia imported and initialized. Instead of doing this separately for each test you can customize your cy.mount() command to automatically use a default store. You can further then customize it to use your own store in case you want to change its state.

Instructor: [0:00] In this component test, I actually have the same problem as I had in the previous example. [0:06] Since my loading component actually uses pinia to access some state, I need to import createPinia from the pinia package, then import my store, and then actually call the createPinia and pass it on to my store function.

[0:30] This is, of course, very lengthy if I need to do it for all of my components that use the state. Instead what I can do is to rewrite my mount command so that it will load the default store automatically.

[0:45] In order to do that, I'm going to jump over to my cypress folder. In the support folder, I have my component.ts file. When I scroll down, I can see that my mount command basically returns the mount function from cypress/vue package.

[1:05] Let's rewrite this slightly. Instead of just returning the function, let's make this custom command receive a couple of arguments. The first one will be, of course, the component itself, and then we will load some options, which by default will be empty.

[1:23] Inside here, I'm going to call my pinia function, as I did before, and I need to import that, so let's do import. Then we are going to import our store and call it with the createPinia initializer. As a final step, this function is going to return our mount function but with the component and options as well.

[2:04] When I now save my component file and then delete all this from my loading spec, I can see that the test is still running, and it's loading the state of our store.

[2:17] Let me actually put it back. I want my cy.mount function to actually receive some options so whenever I decide to pass my own state, it will be able to handle that.

[2:32] Let me go back to the component and I'm going to make changes to my command, so that if the options object will contain a store property, then I want to use that, but if it's undefined, it can use the default store.

[2:49] I'll save this, and now I'll go back to my test, and I'm going to save this use store into a constant called "store," and I will be passing it on to the cy.mount function.

[3:02] When I save my test, it still works. Now, I want to make sure that I can change the properties. Let's just these tractor, the connection error property, which our loading component uses.

[3:18] I'm going to use store-to-refs function to use it on my store. Now, I need to import that. Let's do this and inside my test, I'm going to change the connection error value to 1.

[3:37] As I save my test, I can now see that there's another element on my page rendering a message, "This is taking too long," which is a message that will appear for user, if they have a connection error.

[3:50] We can now write tests that will make sure that this message appears in this case. Now, the only thing left for us to do is to fix this TypeScript errors. Basically, we just want to make sure that the mount function is able to take our arguments.

[4:14] Component can just be any. Then, we'll have the options which are optional. I just want to make sure that it's going to be an options object. I'll use, "Record< string, any."

[4:33] This function is going to return chainable and any, which is go-to return type for Cypress chainable functions at the moment. All of the commands that can be chained are basically inside this chainable interface.