Testing Web Apps with Cypress Creating Your First Test
Transcript from the "Creating Your First Test" Lesson
>> All right, let's go back in to that larger application. This is the Cypress-examples application that we have here. And like I said, let's kind of see where we're demoing today. And I'm gonna close the other Cypress runner at this point and go back over here. And I can go ahead, I have it running on localhost:3000.
[00:00:28] So let's just take a look at what we have to work with here. And then we'll begin writing some tests around it together. So this says it should be running at 3000. We have not one, not two, but six example applications to kind of give us the ability to try out different things like little toast notifications popping up, or ones that have login and off, so on and so forth.
[00:00:58] That's why there's that SQLite dependency. So it's not just all hard coded data. We have one that just has every kind of input field that you might ever want to deal with, so on and so forth. So we'll be kind of testing these applications. It doesn't matter what they're written in because Cypress doesn't care.
[00:01:20] You tell it to click a button, it's gonna click a button, it doesn't matter if it's just HTML or if you wrote it in jQuery or what have you. So we won't actually be working on any of these applications, they kind of exist for us to explore and play around with as we go through.
[00:01:39] So let's go over, we have this first file here, which is, let me to go back over to the cypress-examples, where we have just a describe block. One of the interesting things about Cypress versus Jest is, a lot of the unit testing frameworks will get angry with you if you have a test that has no assertions in it, right?
[00:02:06] And that seems reasonable, right? Like yeah, you made me run this test, but you didn't check anything that you probably made a boo-boo. But as we talked about with Cypress before, it is very likely that you might wanna have it go visit a page, and then you might wanna use the selector playground to figure out what that selector is.
[00:02:27] And then you might add another piece of code, and then you might wanna do the next thing and kind of build up that larger workflow, yeah.
>> I think you answered this just now but to clarify what we're essentially doing is we are telling the test framework that it's okay if we don't get a return value?
>> Is that right?
[00:03:24] And I have the thing you can copy and paste in the guides here. I just call it cyref, and that way, I can just put that at the top of any given file. Some of the selectors, I also just have shortcuts for because I don't enjoy typing that.
[00:03:38] Yeah, you can get it from the selector playground as well, but if you know what it is and you don't wanna type in any of that. Let's talk about selectors for a moment. There's kind of like a hierarchy of selectors and which ones are good and which ones are less good, right?
[00:04:00] Saying that you wanna get the first paragraph tag on the page is probably great right now and increasingly less good as time goes on, right? Even class names like a lot of modern frameworks are going to turn your very descriptive class names into hashes and garbage class names, right?
[00:04:27] This application is built, for instance, in Svelte, which the Tailwind classes go through, but any of the kind of bespoke ones get turned into unique identifiers so that code splitting works, right? The things that try to make the web more performant, right?. So relying on class names or relying on things that happened to be there for style purposes, is probably also a little bit problematic, because they might get changed by someone updating a design, right?
[00:04:50] So basically, yeah, just hoping that it's the fourth paragraph on the page, probably not great. Hoping that it has a class of purple border to find it, also probably not great because the purple will become blue, your tests will break, and you'll be sad. And I'm not gonna feel that bad.
[00:05:09] So moving up, IDs, right? If you're styling based on IDs, again, they could change cuz the style but IDs are if you're using them for the purposes of testing work, the general kind of recommendation is to use data attributes. So in HTML, you can do data dash whatever you want and equals something.
[00:05:33] And the idea being that no one is going to change a data-test when they're changing the style, right, or data-cypress or something like that. Like it says, hey, this identifier is on here because I'm using it to get a hook on that particular element when I'm writing my tests.
[00:05:52] So that is kind of a way to go about doing that as well. When we are writing our first test, the very first thing that we need to do is we need to tell Cypress where to go, right? It will poke any button or change any input that you want on a page, but it can't acquiesce what page it should go to to do that, right?
[00:06:24] So we do need to tell Cypress to visit a page. Just real quick, if we go into the cypress.json, you can see in this case, that I do have a baseUrl set, right? So I do not need to type in the fully qualified domain, but if you were to spin up Cypress for yourself and just type in /cats/whatever, right, it's not gonna necessarily work cuz you didn't configure that.
[00:06:51] So that is one thing that I did on your behalf in this case. So that's just kinda to point it out as we go through. So the very first thing to do is we need to go visit a page. Now we have describe, we have it blocks, we also have beforeEach.
[00:07:07] I want you to take a wild guess when beforeEach runs.
>> Runs before each test.
>> Runs before each test, perfect. So we've got beforeEach, and that will take a function of what we wanna do. So generally speaking, in a lot of cases, you want to visit probably in a given file, you're probably visiting the same page, the same part of your application.
[00:07:33] So beforeEach is a really good place to put that because it will go. Otherwise, you're gonna do it in every test, right? The other interesting part is you can nest these describe blocks, which we'll do a little bit later on. If you nest them, the beforeEach will happen in the order of nesting.
[00:07:52] So beforeEach, we'll do cy.visit. And we're gonna go visit that first application, which is ('/ jetsetter'), which we'll take a look at in a second. And it will now go every time and it will visit that page when this test suite runs, right? And we could say it should, right?
[00:08:16] We're gonna do the thing where we don't necessarily know what we wanna do just yet but like go fire up the page, pull it up in front of me with that selector playground and stuff along those lines. And then we'll kind of figure out what the first thing that we want to do is, right?
[00:08:33] Like, this could be ideally you're writing this test maybe before you start even working on the feature, right? Like, I have a bug that I need to fix next week, where if there's a hash in the URL, it doesn't render appropriately because it thinks it's a hash in the URL versus the identifier.
[00:08:50] So I might just start with a test where I put one of those links on the page and go visit it to make sure that it works correctly, right? But this case, we don't necessarily have a plan just yet, I mean we do but not that I've told you.
[00:09:04] So lets just get that kind of in place. We'll say that it should, and again, this should is just a pattern you don't necessarily, if you don't care that you're test read English, you can do whatever you want. So in this case, we'll do mpx cypress open, just like we did before And we'll give it a second and there is Cypress and is pulling up my entire file.
[00:09:34] Now if you really wanted to test me, you could go run all 29, it will take a while. Someone's like, yeah, I'm doing it. They pass, some of them are skipped but they pass. We'll go into this first-flight one, which is the file that we had open. As you add files, that list will automatically update.
[00:09:53] Everything is rocking and rolling. And you can see that the application pulls up, and like that test, technically passed. Again, in the absence of failure, it passes.