
Testing React Applications, v2 Configuring Cypress Exercise
This course is no longer being maintained. We recommend the testing section of the Intermediate React course instead. We now recommend you take the Intermediate React, v5 course.
Transcript from the "Configuring Cypress Exercise" Lesson
[00:00:00]
>> Kent C. Dodds: Cool. So let me intro you to the Cypress installation in the main app. And then we can, I can set you free on the exercise. So, we're actually gonna be doing a login thing again. This is intentional, like the fact that your unit test, your integration test, and your end to end tests are all actually the exact same thing.
[00:00:28] It's intentional, if I'm gonna have an end to end task on all this and it covers all the same stuff, I'd probably just have the end to end test honestly. And then we don't have any edge cases really in the unit test that we're covering. So it's, there's no point.
[00:00:43] But the reason that I did it for the workshop is so that you're really familiar with how this thing works and so you don't have to learn more domain specific stuff. So you can see how it works in a real world application, a real world setup without having to learn a lot of domain specific stuff.
[00:00:58] Okay, so if you pop open your package.json, you'll see a bunch of scripts here, lots of these are just kinda workshop specific things. The one that we're going to be working with is the test :ete. And that's gonna open up your development server and it'll open up Cypress.
[00:01:19] So this application is a fair amount more complicated than that calculator. Now, we have to open both the, start up the server. And the client server, and so we're doing a fair bit more stuff. And that's generally the idea behind end-to-end, is that you have to have more things set up and ready to go, just like you would in your development process anyway.
[00:01:44] So often setting up end-to-end test doesn't take much more than setting up a new developer for their development environment. But anyway, you can go ahead and in the root directory of the repository, run npm run test:e2e, and this should pop open everything for you. But started our server.
[00:02:07] Started up Cypress, and you should have a couple of tests in here. You can check out the post one later. I have that one kind of as an example something that's not the login and registration. Yeah, so for us, we're going to look at the registration. I'll just demo that for you, or I'll show you the test and then I'll let you go on the exercise for registration.
[00:02:33] But yeah, you can click run all test just to see what things look like.
>> Kent C. Dodds: And, so this is one of the reasons I don't do Cypress for everything, because it like sometimes takes a really long time to start. There we go.
>> Kent C. Dodds: [SOUND] So that's gonna find and like yeah I just, I love this.
[00:03:02] I can go and see okay, let's just click right here. And that's what it looks like at that point in time. We're on this page and that's what its doing, you can click and see what the down looks like. I'm seeing Peter shake his heads like all those hours wasted with Selenium.
[00:03:20] Okay, so there are couple of things am just gonna show you right here in Cyprus that we're doing that. I think it is an important aspect of testing, here, actually maybe I'll show you the test instead. Go to Cyprus>e2e>post. So we have tests already for the login and registration.
[00:03:45] And so, often in end to end test what I'll see is on every single test is testing login or registration and login. Because you wanna have a fresh new user for checking out or adding items to your cart and checking out. And then you wanna fresh new user for going to the settings and updating your settings and saving that.
[00:04:07] And so you wind up testing the registration login over and over and over again. So with cyprus, because your tests are actually running in the same context as your application, you can do a fair amount more. And, so this post actually we have a custom command that we use in this post for login as new user.
[00:04:29] If we check out our support and then the commands here, we'll see we have login as a new user, uses a create new user API. And here, we're actually using the same generate login form that you were using in your other test, cuz this is all running in the browser.
[00:04:48] It's bundled out with, actually, it's not WebPack, it's Browserify, fun fact. But we get a user form, and then we create a test user. We post directly to the endpoint for the register. So we're like, this is the browser firing this request as part of our test. And we return that user object.
[00:05:13] And so then when that happens, we set that item in local storage, and we return the user. And so we've already tested the whole process of login registration, we're confident about that. And so because of that, we can take this shortcut. And this. This is actually something you can do with a redux, your redux store.
[00:05:31] You could, because your tests are running in the same context as your application. When Cypress is running, you can expose your redux store to Cypress, as a global variable, and Cypress can initialize your redux store to a certain state. And you can start off from there. And so at that point, it ceases to become a full end to end test and starts to become a much more focused, still sort of end to end test, because it's hitting your server.
[00:05:58] In addition, the Cypress folks really want me to mention that Cypress can be used for integration and unit test as well. So you can mark out the server, it has a really powerful capability to run that. We're not doing that here, cuz I'm pretty happy with Jest, but you can really do that it's very powerful.
[00:06:16] And you can also, we could render a react component in our test to the document and then interact with it just using Cypress. So if that sounds interesting to you, there's a lot of resources to figure that out. Okay, so let's take a look at the register. And here we describe our authentication list view registration, I guess.
[00:06:46] But before each, you're gonna log out. You can look at the custom command for logouts right here. We take Cypress, or we get the window and for its local storage, we're going to invoke remove item. Let me come back to why it looks so funny in a second.
[00:07:03] And then after you've successfully made sure that you've logged out, then we'll visit to the homepage. And then because we're using Cypress test utils, we have some really nice selectors for this. So we'll get the registration link, we'll click on it. Then we'll get the username field, we'll fill out the username.
[00:07:20] We generated a random form. Same for the password, then we'll click on the submit button. And then we'll assert that we were directed to the homepage. That assert route is just this thing. Kinda feel like that should be built in, to be honest, but it is what it is.
[00:07:37] And then we'll verify that the user's display name is there. We could also verify the logout button is there too. But this is similar to what your exercise will be. And it just gives you kind of an idea of what this experience is like. So before I push you off on that, I mentioned that I would talk about why this looks so funny.
[00:07:59] Why isn't it just window.localstorage.removeitemtoken? So the reason that it's not just like regular old JavaScript in using these Cypress APIs, is because in the world of like humans interacting with that web applications. The human side of the interaction is nothing but synchronous. Everything happens one after the other.
[00:08:28] You can't have a user clicking on two buttons at the same time. You can't fire two quick events or anything like that. And so in Cypress actually, every single one of these commands. Probably a better example is here, every one of these commands is actually like all of this code is running synchronously, right?
[00:08:47] So there's no like async wait or anything going on here. And so what you're doing is, think of it like this. You're writing down instructions on a piece of paper, and then you're handing that piece of paper to Cy. I kind of wanna call this variable user. So Cy is like your user.
[00:09:04] You say here Cy, could you do these things for me? And Cy looks at it, and it does them one at a time. And by default, it's gonna say, I'm gonna keep trying to do this for four seconds, and if I can't do it anymore, then I'm gonna say, okay, the test broke.
[00:09:20] And you can change that timeout. So that's basically the idea behind Cypress's queueing system, and that's why some of the APIs are kind of weird. Some of the assertions are like, just the fact that all of these happens, all these code executes synchronously, but it's actually queueing up the queueing system, makes some of the APIs a little less ergonomic.
[00:09:44] But if you're familiar with Chai, the test in the library from that is commonly use with Mocha, then some of these will look kind of familiar to you. And you can check out the docs. Like I said, Cypress is very well documented. Okay, any questions before we launch off into the exercise?
[00:10:08]
>> Kent C. Dodds: Okay, cool. So your excercise will live right in here. Login.todo. And I give you some instructions here on what you're supposed to do. In your case you are gonna have to create a new user. But you don't wanna have it log in, so just create new user, and yeah, and then go through the log in.