Cypress (Web Testing Framework) Crash Course - 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody thank you for coming back to the channel in this video we are going to cover cypress js and cyprus js is a javascript testing framework that allows us to test our web applications and i've been recently using cypress and i have really been favoring it over other testing frameworks and let me quickly tell you the reasons why so the first reason is that it's super super easy to set up and we're going to see how easy it is to set up in a moment another thing is that it's really really fast so it's actually a lot faster to execute your tests over other testing frameworks another thing that's really important to me is that it's super super easy to debug one problem with tests is you can't really visualize the changes and so it actually gets really hard to debug and figure out exactly why your tests are failing with cyprus you actually get this really amazing gui that basically showcases exactly what is going on and what is being tested so if anything goes wrong in the process you can quickly catch it and see what it is and that's what i really really love about cyprus and i know that's what you guys are also going to like about cyprus and the last thing is you can write all kinds of tests you can write unit tests you can write integration tests and you can write e to e tests with cyprus so you don't really have to mix and match different testing frameworks another thing that i didn't mention here is that it really doesn't depend what you build your application in so you can build your application in react or nux or vue or angular or next or just plain html javascript and css and you can still test that with cypress whereas before if you build your app in react you would probably have to use something like react testing library if you build your application with knux and vue you would use some sort of tailored view testing library but with cypress it really doesn't matter what framework you use as long as it is a web application you can go ahead and easily test it and that is really really terrific so we're going to cover type uh cypress and uh to do that we're gonna actually test a bunch of uh websites that i have already pre-built so if you want to follow along please go to my github repo at heartblade 7 cypress crash course and go ahead and clone this repo inside of your local machine over here we have two projects and these are basically the projects that we are going to test so this is just a basic react project project one and we're just going to basically test it out we're going to write a bunch of tests using cypress so there is no cypress test here we're going to go ahead and add that a little bit later and then once we're done with project one we move on to project two which contains a client and a server and this is just basically a way that we can test http requests so we're gonna cover that as well and don't worry if you are ever lost i have a final version that contains all of the cypress tests for project one and project two so if you want to go ahead and follow along please feel free to clone this repo you do not have to understand anything that is going on i built this with react and express but if you don't know react and express totally fine all you really have to understand uh is html and basically the dom model that's really all you have to understand so uh completely fine if you do not understand the code and we're not really going to be diving into the code that much we're just going to be testing out our application all right so that is super super exciting and i can't wait to see you in the next sections let's get right into it and add cypress to an existing project now to do that what you're gonna need to do is again clone my repo and we're going to be starting with project one that contains just a simple react application again no need to know any react really all we need to do is know just some of the dom elements and i'm going to cover them throughout this crash course so basically clone this repo and then open it up in any ide that you want so i have it over here open in vs code i just cd into project one and i have my simple react app up and running now the first thing that you're going to have to do and let me just quickly zoom in here the first thing that you have to do is install all of the dependencies so just do a mpm install or a yarn install whatever you want to choose i suggest just sticking with npm because that's what that's what i'm going to be using throughout the crash course now if you want to choose yarn just make sure that you are consistent if you want to use npm make sure that you're always consistent with npm so do an npm install and what that's going to do is just install all of the necessary dependencies so you should see a node modules folder appear i'm not going to do it because it takes a long time to do so i'm not going to go ahead and do it i already did that and then what you're going to want to do is just do an npm start to start your application and what this is going to do is going to start our application on localhost 3000 so if we went to localhost 3000 and let me just quickly zoom in here you can see our application now initially all you see is this so you see this like weird side navigation and then you see this whole empty screen but if you click on the side nav you can see here that okay we have this first part over here so this little dashboard and you can add habits so this triggers a modal and you can add whatever habit and you can toggle habits uh similarly with accomplishments you can basically add some sort of accomplishment submit an accomplishment we have this kind of mock asynchronous request and there we go we have a go back page and then over here we just have a bunch of elements and i'll talk about exactly why i have this page uh basically it's it's it's uh used so we can actually learn how we can query for specific elements when we are testing for them and essentially what we're going to be doing is we're going to be testing this particular application so in the elements we're going to learn how we can query for specific elements and then for the habit and accomplishment we're going to be testing a bunch of things for instance we're going to be testing hey once i click this a modal appears another thing is once i click this and then i press uh or add some sort of habit and then i say save changes well that actually renders some sort of card right over here with this text we're also going to be testing that when i click on a card the icon changes and that is pretty much it for this section and then over here we're going to be basically testing that uh you have to input all of the values and if you don't you get this error so that's something that we're going to test and we're going to test hey if you put in all of the necessary errors and you click submit and we get this loading state and this is going to stimulate asynchronicity and then over here we're going to basically test that we get to this landing or this this this completion page and then we're also going to be testing that hey when i press go back it goes back to this page that everything is empty and unchecked so we're just going to be testing a bunch of things and this is just going to get us used to cypress and once you learn these things you can really easily start testing your own applications so now let's actually go ahead and install cypress inside of our app so to do that what are we going to do well let's open up our terminal so let's leave this open right here our running instance open up another terminal and all we're going to do is npm install cyprus very very easily so we're going to go ahead and install cypress this is also a command that takes a little bit of time but all you really have to do is just npm install cypress i believe i already installed it so i'm just going to quickly cancel it and just to double check you should have cypress installed as a dependency right over here this is the version that i'm using if you are using a later version don't worry i'm sure the content hasn't changed dramatically and if it has maybe i'll uh i'll post another video and deprecate this one okay cool so install it for sure go through the whole process i'm just skipping it just for for time's sake now let's actually open up a cypress instance and when i open up a cypress instance what i want you to do is just keep watch look at all of the directories over here so we have our node modules we have public we have source and then we have a bunch of different files so if we want to open up a cypress instance what we do after installing it is mpx cypress open and i want you again to keep watch right over here look at these dependencies so hopefully this doesn't take too too long okay so it seems like okay it triggers this little gui right over here so this is the gui that i was actually talking about so it is loading up but now if i go back here let's just give it some time so it seems like it's doing something okay okay so that took some time but eventually we got something like this so you can go ahead and just say okay got it and you can see here that we have a bunch of different tests so these are just a bunch of tests and if we want to actually execute and visualize any of these tests what we do is we basically click on whatever test that we want to execute so we go ahead let's say we want to execute this one actions.spec.js well we would go here and we can see all of the tests you can see here that it actually goes to this link right over here hopefully this is uh hopefully this is let me zoom in a little bit maybe that will be better there we go okay so that's better uh let's actually zoom in one more so you can see here what's happening is that it's going to this website this actual website this is a real website so you can see here that this is actual uh website and what it's doing is it's basically going to this website and then it's performing all of these different actions so let's actually go ahead and let's re-execute this test to re-execute this test what we do is we just retry and you can see you can see that the gui that is basically taking place and as you can see here step by step it's showing us what is being done and this is what i absolutely love about cypress and what's great about it is that you can actually go ahead and click on each event and you can see basically a snapshot of that specific event so let's go over here let's actually scroll up a little bit you can basically again see a snapshot of all of the events you can see here we're focusing on a specific dom element here we're blurring it let's just continuously click you can see here we're clearing here we're submitting we're clicking so we can actually take a look at exactly what's going on and you can see here that everything thus far is passing and this is what i absolutely love about cypress is this gui now you can see here that there's a bunch of other tests and all these tests are actually tests that are in separate files so you can see here you can actually go and click on this test and now it's going to execute a separate separate lists of tests and you can see here these are some cypress request tests so this is absolutely terrific and these are a bunch of example tests that cypress gave us right off the bat now where are they coming from well when we did and let me just quickly close this seems like it creates a new instance every time so when we did np or npx cypress open what he did is create a bunch of uh files inside of this cypress directory and that's why i told you to watch this so you can see here it created a cypress directory and this cypress directory has four other directories fixtures which we will talk about don't worry but for now we're not going to worry about there's also plugins and support we'll also talk about those but for now i want you to focus on integration and integration is basically where all of our tests are going to live and you can see here inside of integrations we have an examples directory so if we open this we can actually see all of the tests all of these tests are these tests over here and these are just a bunch of examples that we can use so we can actually go ahead and take a look at these tests if we're ever stuck or if we want to look at them as reference so you can see here we have a bunch of different tests and basically these tests are performing those actions that we actually end up seeing on the screen so you can see here that we're telling basically this test to visit this url over here so before each test and we'll talk about this a little bit later we're visiting this url and then what we're doing is we're i don't know we're doing a bunch of actions we're getting a specific element and then we're typing fake at email.com and then we are doing some sort of assertion we're saying that hey this should actually work so once i type this it should have value of fake email.com so this assertion works and if this doesn't make any sense to you don't worry we're going to cover all that in great great detail but again if i click on this test again you can see here fake email.com it was very very quick but you can see that that assertion actually ended up passing all right so that is terrific that's pretty much what we want uh but we obviously don't want to run all of these examples right over here this is something that we probably want to ignore this is just for us to use for reference so we can either delete the examples or we can just ignore them and that's what i actually suggest doing is just ignore them so we can still have them for reference now to basically configure everything that we really need cyprus has this cypress.json file and so in here we can basically add a bunch of different configurations that we want so one thing that i want is i want to ignore some test files and i really want to ignore all of the test files that are inside of this examples directory to do that what we are going to do is just say ignore test files and then we're going to say hey we want you to ignore all of the files that are inside of the examples directory so anything inside of the examples directory we want you to go ahead and ignore it now another thing that i want to do is i want to specify a base url so over here if you remember we actually have to visit a specific url to test it now we can actually specify the url every single time in here or we can specify a base url now the url that we are going to be using is simply localhost 3000 so let's actually go ahead and copy that let's get rid of this slash accomplishments let's just copy localhost 3000 and let's just specify here a base url of localhost 3 000. all right so another thing that you can do is also manipulate the view viewport width viewport width and you can give this a specific number reason why this is failing is because it has to be a comma so you can say that the viewport width let's say we want it to be 1920 and the uh viewport height height we can say that hey we want this to be um 1880. so now if we go ahead and save this uh it should actually reflect inside of the gui okay so that is terrific and that is really really simple this is what i mean about cypress and how easy it is to actually set up a cypress project so that is pretty much it and what you also can do is you can specify a different url for different environments so if you're in your local environment you can specify this as your base url but if you are in staging or development or or well i guess you probably won't be testing in production but if you're in staging or you're in development then you can actually specify a different base url and i'll i'll let you kind of explore how to do that because it's kind of out of the scope of this crash course all right so we set up we basically set up our cypress testing framework inside of our application in the next section we're going to start learning about how we can actually uh get specific elements because that's really what we need to do in order to test our uh our application we first need to well get this element and then click on it and then get this input element and then type in it and then get this save button and then click on it and then you know if we want to test something further then we have to get this card click on it and then basically test things so we have to consistently be able to get certain html elements and that's going to be such a huge part of every testing framework that you use so in the next section we're going to learn about how to do that all right in this section we are going to learn about how we can locate or select for specific elements now like i said in order to perform any specific action and thus to test a certain flow we need to perform some actions on specific elements again for instance we're gonna have to press the add button now the only way that we're going to do that is if we can somehow find this add button in the testing framework that we are using and that is essentially what we are going to be learning how to do in this section and this is a very very important section and this is why i have this elements section over here and basically this is just a bunch of different buttons but we are actually going to select for each button in a different way and so we're gonna learn exactly how we can select four different elements in different ways so that we can have different variations if we need to now over here we're using a bunch of buttons but the rules that apply will actually apply for any sort of element that we want to select for or locate now what we're going to be doing is we're going to be using three very popular cypress methods we're going to be using these methods to locate specific elements and most notably we're probably just going to be using these two but i will also introduce this one so as you can see here and this is why we have this kind of division we have get and this is a separate cypress method that we can use to locate elements so we're going to be locating these elements with the get command over here we have contains again another separate method that we're going to be using to locate elements and then we have the find command now if you ever want to learn more about these elements please feel free go to the cypress documentation and you can see here all of the different commands that you can run and there's no way i'm going to cover every single one i'm going to try to cover the basis of cypress and then later on what you can do is you can start reading the documentation and fine-tuning your tests the way that you need to so let's actually begin with get and over here i'm basically at that get command and what this is doing is basically getting one or more dom elements by a selector so what this is going to do is it's going to get one or more so it's basically any sort of selector or any sort of criteria that a dom element is met it is going to get that for us so let's actually go ahead and well let's actually try to recreate this now if you go back here you can see here that hey there's no cypress files that are found and that's because we decided to ignore all of the test files inside of the examples directory and that's why we're getting this error so what we're gonna have to do is go to the integration and we're gonna have to add a new test file now you can add this in a separate directory so you can have a folder but this has to of course be in the integration directory so you can have another folder such as we have over here with examples or you can just put the test in the root integration directory and that's what i'm going to do for now but later on for organization you might want to have different directories especially if you have a lot of tests so let's actually create a test so you can see here that the general format of the test is the name of the test dot spec dot js and this is very very important because cyprus is going to see the dot spec dot js and it's going to interpret it as a cypress test so the naming is very very important and again it has to be inside the integration directory so let's create a test and we're going to call this locators because we're well locating elements so locators dot spec dot js and as soon as i do this if i go back over here you can see that it is happy if i click on it however well there's really no tests that are running and you get this kind of error saying hey well there's no tests that were found which is completely valid all right so let's actually go ahead and let's create our first test now the first thing that i want to do is i want to tell vs code that hey this is a cypress file and the best way to do that is to add this line at the very top so slash slash slash and then reference type cypress and this basically tells vs code that hey this is a typescript or a cypress file and it basically helps us with a kind of auto completion which is pretty important dated all right so now that we have created our test file let's actually go ahead and write our first tests now before we do that we have to talk about how tests are typically organized tests are typically organized inside of a test file inside of blocks and we can have multiple blocks inside of a test but essentially all tests inside of a block are related to one another in some way now if you go back to this example you can see that the block here is called context so you can see here that the block is called context and you can see here that it spans basically the whole test file and typically we really just have one block but we could have multiple but you and you can also see here that inside of the block we have multiple tests so over here we have it this basically symbolizes the test and this right here is the message of the test and so this is a test that we have inside of this block and over here we have another test over here we have another test and so on and so on so we need to have a block and inside of that block we're going to have our tests now you can call this block context but while i like to do and this is really really popular i like to call this block describe now you can't call this block whatever it is that you want this is really going to be dependent on the framework that you're using it just so happens that in cyprus you can either call it context or describe so this is going to take in two things so you can see here it's going to take in a title that is a string and then basically a function that is going to configure all of our tests now the title is going to basically contain a description of all the tests that are going to be inside of our block now i'm going to call this locators because this is just a bunch of tests that are going to locate specific elements now the second param is going to be an arrow function or whatever function that you choose and then inside of this arrow function we're gonna have all of our tests all right so that is terrific so at least we learned that now the next thing that i want to basically teach you is that hey for each test we have to go to this page localhost 3000 slash elements and we have to do that for each test because we're testing all of the buttons inside of this page now to do that we can use a predefined hook called before each so you can see here we have before all or before each before all runs once before all of the tests before each runs every single time before each test and that's what we want so we can say before each test what we want you to do is we want you to visit localhost 3000 slash elements now how do we do that well to do that we are going to use y which stands for cyprus and cyprus is going to basically interpret this as well some sort of cypress command and then what we're going to do is we're going to do dot and you can see here that we get a bunch of auto completion then we're gonna say dot visit and then we are going to visit well slash uh elements so slash elements is what we called it so slash elements now how is it gonna know well this is localhost 3000 elements well the only way that this is going to know that is if you go to cypress.json we've specified that the base url is localhost 3000 and so what it's going to do is basically append localhost 3000 slash elements all right so before each test we're going to run this and then we're going to run our tests now to run our test we're going to use the keyword it and then similarly we're going to have a string and then the configuration so the string is going to define what the test is doing so let's say locating elements with the get command so with the get command that's what we're going to be doing and then over here we're going to have the function so we're going to have a function and this is going to execute a specific test so now if we actually save this and go back to our test runner and we click on locators.spec.js it's going to spin up an instant and you can see that it actually goes to this page so it actually goes to this page now if we were to change this to like slash whatever you can see that it goes to well slash whatever which is just the home page in this case but no we want to go back to slash elements all right cool so now let's actually go about and let's start getting our elements and let's actually start very simply we want to get all the buttons so that is very very simple and this is a way of getting by tag name so let me just quickly inspect this what i'm going to do i'm going to do this a lot throughout the crash course so i'm going to quickly zoom in and you can see here that there's a multiple different tag elements throughout our application so you can see here we have a lot of divs we also have some anchor tags we also have um let's see here we have some h2s we have some whatever so we have a bunch of different elements here and let's say we want to get a specific element or all of the elements by a tag name well let's say we want to get this button right over here if we click on it you can see well this it has a tag name of button so let's actually go ahead and let's get that specific button all right so to do that what we are going to do is s y dot get because that's the command that we're using and then in here we're going to specify well the tag name and you can see here that there's a bunch of different tags that we can basically use but what we want to use is a button so if we save this and we go back to our running instant you can see that everything has worked this basically ran automatically once we saved our test and changed it and now you can see here that it got all the buttons and you can see here the number of buttons that i got because the get gets all of the elements that match some sort of specification that we put over here so basically in this page it saw 14 buttons one two three four five six seven times two fourteen and if you hover over it you can see that it actually got them all and you can see basically uh this is what i love about cypress you can really visualize all of your tests you can see here that it got all of these buttons in this command okay cool so that is terrific now we can obviously do this with other html elements for instance we can do we can do hey i want you to get all of the h3 tags similarly you can see here that now we got all of the h3 tags and we can also say hey we want to get all of the h2 tags now you can see here that it got one h2 tag which is really really cool okay so that is one way that we can actually get elements now let's actually comment this so we're getting all of the elements by tag name so we're getting all of the elements by tag name now this is probably not the best way of getting elements and you can probably see the reason why typically we don't want to get all of the elements typically we want to get one element and getting it by a tag name typically results in more than one and if it does still result in one our our applications consistently changing so we may have just one button uh with that page at the moment but then we might later on have more than one button and you know what that's not that's not a great way to test our application it's not a way great way to actually select four elements so what is another way well we can actually um maybe we can select for the class name so you can see here let's go to this button this is just a regular button and it has well elements button but the button right next to it has another class of elements button and then let me open this up some more but then it also has another class button with class so well this is a class and we can actually query for this specific class now let's actually go about doing that now how do we do that well let's now get all elements by the class name so we will do that with psi dot get and then instead of just flat out saying the class name well we were going to say the class name but to specify that this is not a tag and what we're going to do is we're going to specify dot button with class so now if we were to save this you can see here that cool so now we have two elements so we have basically these two elements specify this get command and this makes sense you can see here that take this has a button with class and similarly this one also has button with a class but no other one has that exact same class btn with class all right cool now let's say what we want to do is we really don't want to get the element by just one class we want to make sure that hey all of the elements match or basically the element the button that we want basically matches the description that we specified here so let's say we want to get this one over here and we want to make sure that hey we want to get all the buttons that have a class of elements button button with class and then more button classes so we want to get this button and it has to match this exactly so it can't it can't have more it can't have less i want we want to match it exactly well we can do that very very easily with cypress with attributes so essentially here what we can do is let's say get all elements elements with specific class specific class or specific class is so here we can just do psi dot get and then inside of this string we can specify an attribute so essentially what we're saying is hey we want to get an html tag with the following attribute and how do we specify attributes well we put them inside of these square brackets and the attribute that we want is well class and then in here we're going to say that the class is equal to well elements btn btn with class and then more btn classes so more btn classes so you can say here that hey we want to get the html element that has a class that is exactly equal to this so now if we go back to our test runner you can see that we get that one exact class which is cool now we can do the exact same thing for this one over here so let's say we want to get that other one so let's actually go ahead and copy this so we can say that hey we want to get the input element that has this exact same class so if i say that you can see that hey we get it and that's that's because even though this contains the exact same stuff it has elements button button with class it is not exactly that and that's basically how we can really really specify exactly what we want with attributes now we can also get elements by id so let's actually go about doing that and that's very very easy and we can actually do it through attributes so we can do let's see here get all elements by id so we can do it with attributes so we can say hey that this is going to have an id that is equal to let's actually go ahead and see what this id is so the id is button with id so we can go ahead and save that so we can definitely do it this way this is completely valid and you can see that this works but we can also do it another way kind of a similar way that we've done it over here so we can basically say that hey we want an id by specifying hashtag which is well a symbol for id and then the id itself and again you can see that it works perfectly fine all right cool so now let's actually look at different attributes that we can select for we can literally select for any attribute that we want so for instance even if the attribute is something like type submit it's not a class or an id it's a type or it could even be a placeholder or could be whatever it is that we want we can select for it using this syntax over here so let's go here and let's get all elements and we're getting all elements because again the get method gets all the elements so get all elements by tag name or sorry we're going to get all the elements by by a specific attribute and this is the type attribute so sy dot get and then over here we're going to say that hey we want all the elements that are type equal to submit so let's go ahead and let's save that and very quickly you can see here that we have two but ignoring this section over here we can see that hey we get this one right over here which is terrific i hope this is large enough uh let's try to zoom in a little bit more or i'm not sure if this is let's actually zoom out maybe if you maybe zooming out actually makes it a little bit bigger okay cool all right this is cool okay so that makes sense i hope it does i hope it does make sense now there's a another few ways that we probably want to query our elements now let's say we want to query our elements with a combination of different things so not just uh so not just uh with you know a specific attribute or a specific id well we can actually go ahead and do that we can actually combine different attributes so we can say that hey we want to get all the buttons with this id and with this attribute and we can actually very easily do that with uh cyprus so let's actually go about doing that right now so what we want to do is let's say we want to get all of the buttons with a specific class okay so we want to get all of the buttons with a specific class and let's say this class is uh elements button and this should literally give us all of the buttons because all of the buttons have elements button class as well as well the other buttons so how do we do this well let's go ahead and let's do that so let's say get all elements by tag name because we were getting them by the button tag name so and class so to do this what we're going to do is we're going to do sy dot get and then we're going to specify the tag and then we're also going to specify the class very easily we can just do that with dot and then we can just say elements elements b t n all right cool so very easily you can see that we get everything again because every single button has a tag name of button of course as well as that class because that's what's giving it these styles all right cool cool cool now we can do this with multiple other things for instance we can also get uh our let's see here get all elements by tag name and class and id so we can do sy dot get so we can say button dot and then this is the class itself so elements btn and then let's say the id so over here we can just append a hashtag and then we can say btn with id so that was one of the ids for one of the buttons so again you can see here that now we have or only selecting this specific button all right cool cool and very cool all right and then let's actually do one that's a little more complicated that kind of involves these attributes so you can see here now let's say i get all elements by tag name and class and some sort of type attribute and yeah so we're going to say we want to basically get the tag name the class and we want to make sure that the type is equal to submit so similar to this one over here and let's change that to get all right so very easily sy dot get and now we can say that hey the tag name is a button the class is going to be elements btn and then the type is going to be type of submit if we go ahead and save this you can see here that we have two that actually follow this which is well it's pretty interesting but see if we actually went ahead and um which one follows this actually so this is the third one the third one in the contains if we actually click on this you can see that type is submit so it's working as we intended now let's actually talk about the absolute best way and the best practice of selecting elements uh the reason why the this way is is not that great is because these class names can change for instance we can change this class name we can change the id we can change the type it could potentially change it might not be likely but it's very possible that this ends up changing and like one great example is that if we're selecting by button we could add another button we could remove a button we could change it to an anchor tag and so these tests are not really resilient and the best way to actually make them resilient is by giving them some sort of unique identifier that is specific for the tests only so they're really not going to change throughout our application because these unique identifiers are specific to the test only and that can be done by basically appending data so you can basically append any sort of attribute that you want into whatever element so you can see here a button with test id if we go here you can see here that we have a button that has a class but it also has this other attribute data slash psi standing for cyprus and this can be well your unique identifier and you can again append this to whatever element that you want and typically if you want to append any sort of kind of unique attributes it would have this format data slash and then whatever it is that you want to call it for instance in a react testing library it's called data slash test id and the react testing library actually specifically queries for an attribute that looks like this now what's great about cypress is you can call this whatever it is that you want and then you can basically query for it in this way so you can do get all elements get all elements by tag or actually no not by tag name get all elements with specific data test id and so now what we can do is we can do just psi dot get and we can say that hey we want to get all the elements that have this specific attribute sy data is equal to what do we call it here we called it btn id 1. so now if we save this uh this fails for some reason and that's because well i have to fix the quotes of course so now if i save this you can see that it passes nope still fails which is strange okay what am i doing here no it's sorry the attribute is data slash psi not psi data so data slash psi again if i save this now it works perfectly fine but this is actually kind of good because you can see what happens is if it can't find the selector what it does is it retries it and then it ends up actually failing because everything here is actually an assertion even getting elements is an assertion and if you end up failing anything it actually ends up failing that specific assertion and thus ends up failing that test which is really cool and that's ultimately kind of what we want so now we can go ahead and we can fix this and you can see here perfect so this is terrific now one thing that i want to note is that this can kind of get a little bit ugly for instance here this can kind of get a little bit ugly this this kind of syntax you know don't you probably wish there was some sort of like psy dot get by test id or psy dot get by class or side get by type this can get uh pretty unattractive and the way that we can actually create and inject commands inside of cypress commands that we typically use throughout our application is inside of this supports over here and inside of the uh commands.js you can basically have a bunch of different commands that we are going to use throughout our application and you can see here that this is how the comment structure is so we have cypress dot command and then dot add and then the name of the command and then basically essentially what we are going to be doing inside of that command so let's actually go about uh creating some methods that are going to make our application just a lot prettier okay cool so let's do that right now so let's say we're going to do it for for this one right over here so we're going to do it for this one so we're going to go and we're going to create a new command so we're going to do cypress cyprus and then we're going to do commands and we're going to add a command and then over here we're going to specify the name of the command so we're going to say get by test id and then we're going to have an arrow function and in here is basically whatever that we pass in so inside of this parameter is whatever we pass into that command so whatever we want to pass into it so over here we can just say test id and so now what we can basically do is we can do psi dot get and then in here so this is how it would typically look like so remember it's going to be uh the data slash psi is equal to whatever id that we specified in here so what we want to do is we want to basically inject this test id into here so to do that we can use template literals so let's use template literals and then we can just say test id so now we can go ahead and save this now in here what we can do so in here what we can do is instead of doing this long kind of ugly command now we can do a psi get by test id and then we can just pass in the test id so let's go ahead and save this and it works it works completely fine at the end of the day it basically executes the same thing and now we can have basically nicer syntax this is just something that i wanted to introduce to you i'm not going to be doing this because i want you to kind of get used to the real way of of querying elements but this is something that you might want to do later on is mess around with this commands plus it doesn't have to be just one command we can have multiple commands if you're executing something regularly like let's say you need to log into your application to actually run some of your tests you can actually just put it in here so you can do something like you know slash login slash login and then in here you can have all of the different tests so let's say you have you know multiple different tests that you or multiple different things that you need to do to log in and then what you would do over here is or inside of your test you would just simply do side in and then bam you're logged in so it doesn't have to be just one little thing uh you can actually have multiple different things in there all right cool so that is pretty much it and this video is kind of getting long so what i'm going to do is i'm going to pause the video and then in the next section we're going to cover how we can query with well contains so far we have been able to locate elements using the get command but there's many commands in the cypress world that allows us to locate elements one such command is the contains command now if we go to the docs right over here the cypress documentation it says that contains allows us to get the dom element that contains a specific text so what it does is it gets only one element that contains a specific text that we have specified and we can basically use it as such we can have dot contains and then some sort of text now what do i mean by text well when we go here you can see here that we have elements we have get we have this button we have button with many class names and this is the text that we have talked about so let's say we want to get well this one right over here we want to get this element then we would do a cy dot contains and then elements the string elements and what it's going to do is it's going to get this particular h2 tag now this is really cool because it really simulates what the user is ultimately going to do because the user ultimately is not really going to care about hey i want to click this button with this type submit i want to click this button with data test id ultimately they're just going to look at the page you're going to be like okay well i want to click on accomplishments i want to click on habit and so this really simulates ultimately what the user is going to be doing so this is what it is ultimately doing is getting one element so get gets all the elements this only gets one element that specifies the text that we put inside of the parameter now we can do this in multiple ways this is the most typical but we can also do it like this where we specify eselector which is some sort of input or class or id and then we can specify the content itself so this actually is kind of a more specific way of doing it and we're going to look at the multiple different ways we're not going to cover all of them but if you want you can read through the documentation it's very thorough and allows us to really understand exactly how we can use the contains command all right cool so let's go about doing that right now so let's actually go ahead and let's start querying for some of these buttons and now what we want to do is we want to query by their specific text so let's query this button first it says here unique text you can see here that there's no other button with unique text as well it's unique text so let's go ahead and let's uh query for that so let's do this actually inside of another test so it's going to still be in the the describe block but it's going to be a different test because now we're not locating elements with get we're locating elements with contains all right so we're going to do it we're going to say locating elements with contains okay and now what we're going to do is we're going to get a specific element by text and specifically we're going to get by the text of unique text so what this is going to do is going to return this button right over here so to do that let's just put a comment so get element by text and now we're going to do a cy or psi for cypress dot contains and then we're going to say unique unique button i believe or unique text is what we called it so if i save this and if i go back over here you can see that now we have two tests running so you can see all the all the tests right here and it was cool as you can see that hey this this before each ran and then this body ran over here and also we have locating elements with contains we have a before each and you can see here that if i hover over this this has successfully found the correct button so actually found it with the correct text so now let's actually start using the contains but let's use it when the button or the text is not unique so over here we have not unique text and you can see that it's clearly not unique because we have this button with this text and that this button with the same text and this button with the same text and then this button with the same text so it's clearly not unique now what happens when that occurs so let's just give that a go so we're going to say get element get element and this is still get element by text but the text is not unique so let's do cypress or psi dot contains and then we're going to say not unique text if i go ahead and save this and now you can see if i hover over it it just still gets one it doesn't get this doesn't get this it doesn't get this it only gets this rightmost one right over here the right top one and that's because the contains only gets one element so the first element that it matches it's going to get that one element so it's really good in that hey it gets one element so we can actually start performing actions on that element but we have to really be careful because hey if we have multiple uh we have multiple elements that contain the same text we might be intending to get this button but ultimately we end up getting this button so we do have to be careful and so that way we actually have to start specifying well selectors if we really really want to pick whatever it is that we want so we can have any type of selectors remember selector could be a name it could be a class it could be a combination of things for instance we can have a selector where we select for type submit and then we can also have a dot contains that contains a specific text for instance we can have let's say here we are basically combining uh basically uh uh we can have cy so this is with selector so with select door and we can do dot contains and then over here we can say hey we want this to be equal type submit and then we can say as the second string the actual text the actual content so over here we can say not unique text so if you save this you can see it completely passes and you can see that it actually picks the correct one so again we can combine selectors with contains and contains what it does is it kind of ensures that hey we only get one which is actually needed if we want to perform some action now we can combine the contain with the get for instance we can get a specific element and then we can basically say from all those elements i want the one element that contains this text so let's actually try that so now what we can do is we can do something like um you know psi dot get and then we can get let's do the exact same thing so let's just paste that in there and then we can do dot contains and this is ultimately going to result in the exact same thing so not unique text save it and you can see here it results in the exact same thing it was just a little bit different you can see here that it got this and you can see that it got actually both remember get gets both and then we're going to say dot contains this so it's just an extra way of kind of ensuring that hey this is uh the selector or this is the element that we ultimately want all right so let's see my notes here what other ones do i have um you know other other things of course that we can do this doesn't always have to be an attribute selector it could also be it could also be an input so we can say here that hey we want to get the the selector is going to be a form so the selector is going to be a form and then we want to get the button or or basically the element that has this specific text over here so let me kind of illustrate what this is doing so let me quickly save this and you can see here that this okay so this this passes now what is it doing exactly well there is no form element that contains the text not unique text but what's happening is is if i let's go hover right over here you can see that there is a form element and inside of that form element we have a button that contains not unique text so what's happening here is we're saying okay get the form element and then find the input element that contains not unique text that is inside of that form element and that's essentially what's happening and that's why we're able to get this specific element all right cool so that's pretty much it the last thing that i'm going to cover is find so if we go back to the documentation let's go over here to find find is very very similar what it does is it basically finds uh descendants dom elements of a specific selector so essentially we get a selector with the get article and then we basically find a specific element which is going to be a descendant of it so basically this footer tag is going to be inside of the element with this particular class now we can never just do psi dot find because we need to chain this we need to have some sort of parent because it's going to find a child node element so let's just quickly uh go over this i'm not going to go over it too much because we're not going to use it all that much but it's something that we could do so let's say locating elements with command with um with find so we're going to say with find so here what we're going to do is we're going to do psi dot get and we're going to basically get a parent so we're going to get a parent and let's say the parent is the form so let's actually go over here and let's go back to our so over here we have uh let's actually inspect this and let's look into this over here so we can see here that we have a form and this form houses two buttons and this form has an id of form one and again it houses two different buttons so now what we can do is we can basically say okay well get the form that is uh that contains the or get the element that has the id of form one and what i want you to do is find and the any child inside of this element that uh has the class of btn1 so that is going to get this one over here because this is btn1 this one's btn2 again works completely fine you can see here that it gets all of it and then it finds this one cool all right so let's uh let's actually do that again but for btn2 btn2 all right cool and if we go back to our test again you can see that it gets it finds that one and it doesn't have to be just get it could also be contained as long as there is some sort of child element inside of that element that was received from the contains that we want to query for so that pretty much sums it up that's those are the main ways that we can actually start selecting our elements now that we learned that let's actually start selecting our elements and performing actions and the best way to do this is to actually practice it with real life examples so what we're going to do is we're going to test habits so we're going to have multiple tests for habits and we're going to have multiple tests for accomplishments as well and we're going to cover exactly what the tests are and hopefully as we continuously go through them they're going to start making more and more sense and you're going to be more confident with writing your own tests now that we have covered the basic concepts of cypress let's go ahead and actually write our first tests and specifically we're going to write tests for the habits page and we're going to be writing three different tests so for the first test we're going to write is once we click the add button we should expect this model to pop up so that's the first test that we're going to write the second test is once we click the add button and then input some sort of habit like drink a cup of water and then save this habit we see this card display and then the last test that we can write is hey once we add a card we can click on it to toggle the image from checked to x now there's other things that we can also test but we're not going to for instance you can also test that we're able to actually type into this input we can also test that take if we don't type anything and we try to save the changes nothing happens and then we can also test that hey we can also close the modal so those are three additional tests that you can write but i think the first three that i'm gonna cover is kind of a good enough foundation that will allow you to eventually start writing your own tests so let us begin with that right now so as you know if we want to write a test we're going to have to put it in a test file now this test file is specifically just for locators so what we're going to do is we're going to create another test file and we're going to call this test file habit.spec.js this is where all of our dashboard habits tests are going to be located so as usual we're going to put in the reference so let's put in there and then we're going to need to describe block so let's say describe we're going to say habit dashboard because these are all the tests that are related to the habit dashboard and then in here let's start off with the very first test when i click on this this modal should appear okay cool so the first thing that we need to do is add a before each hook to go to slash habits so let's actually go ahead and do that let's do before each and then let's say psy.visit we're gonna visit habits so before each we're going to visit habits now one thing about these hooks you can actually there's multiple different hooks that we can use for instance there is the before all hook the this is a hook that runs one time before all the hooks and then there's also after each and after all so you know if you ever need to perform actions after each test is ran or after all tests have been written something like you know clearing the data or going back to some sort of initial response you would do it with these hooks but we're gonna only use the before each hook in this crash course okay so the first test is hey again immortal should appear when i click the add button so i'm gonna say should display modal when add button is clicked that's the description of the test and then now we're gonna have to we'll perform certain actions so we're gonna have to somehow click on this button now when we click on this button uh essentially what we're gonna have to do is we're gonna have to find this button in cyprus so let's actually go ahead and let's inspect this button and let's go ahead and let's go over here you can see that okay this is a button it has a class of habit add button it also has an id uh and it also you can look at the text itself in this page there's only the add text so we could potentially just go ahead and use contains so there's definitely many different ways that we can go i'm going to use the contains because there's only this one add text in here now it's actually good to combine contains with another selector just in case add appears more than once eventually in the future so let's go ahead and let's say that let's do psi dot contains and we're going to say that the selector is a button and the text is add and then what we're going to do is we want to perform some sort of action so what this is going to do and let's quickly save this uh okay let's save seems like it's not refreshing let's quickly let's go back actually you can see here that there's another integrated test so we can click on this and you can see that okay cool so it got that button but now we want to perform an action on that button well to do that all we have to do is just depend another command and the other command that we're going to append and you can just when you do dot you can basically hover over the other commands that we can use but the other command that we're going to use is dot click because well we want to click on this button so now we can go ahead and save that and you can see that okay the the basically got that button and then it clicked on that button and eventually let's just quickly refresh it you can see that the modal actually pops up so now we have to basically assert that this model exists and how do we do that well we do that with assertions assertions are basically little tests that we take that we do to ensure that our quality of code is the way that we intend it to be so is we basically are going to assert that hey this is uh this modal has appeared so let's go and do that right now so let's first do that by doing psi and we want to get this modal so we want to eventually get this model now to get this model again we need to find some sort of selector so let's go ahead and let's get this modal and let's actually get this modal by this text over here add a new habit because if this text appears somewhere in the document then we know this modal also has appeared because this text is attached to the modal so we can do dot contains this so we can say psi dot contains this and we can go ahead and save it and you can see that everything has been running successfully now what i like to do instead of just do psi dot contains to do our assertion i like to add the should keyword and this is what is eventually going to assert it and we're going to say that hey this should and then in here we have a string of a bunch of different things that we can add and you can take a look at them but we can see here be null be okay b1 but we're going to say be visible this should be visible so this should be visible so you can go ahead and save that and you can see this assertion has been successful all right cool all right so now let's move on to the next test so the next test is when you click the add button and then you add some sort of habit then we should see this card on the page okay so let's do that so we're gonna do should display habit card when new habit is added all right so the first thing that we're going to do is we're going to have to get this button over here and click on it so let's actually do it a little bit differently this time let's do it with the get just to spice things up so you can see here that this habit uh this card has an id so let's just do psi dot get we're gonna do hashtag this id and then what we're gonna do is we're going to click on this button and then let's actually go ahead and save this so let's just double check that it works okay it does work terrific we get our modal and then what we want to do is we want to once we click on this we want to type some sort of habit inside of this input so how do we get this input well very easily we can we can get it with let's actually inspect it we can get it by saying hey we want the input or we can even get it by an attribute so we can say hey go to the input that has a placeholder of habit or go to the tag that has a placeholder of habit to spice things up let's actually do that let's say that hey we want an input that has a placeholder of habit so let's do psi dot get and we're going to say input and then we're going to say that it has a placeholder of habit and then we're going to perform some action on that input so we can append here another action and this is going to be the type action now you can basically read about all of the different things that cyprus can do by literally just uh going to their docks so you can see that there's a bunch of different things so we're not going to cover all of them but for instance there's multiple different actions that we can perform slot like focus or hover or um you know literally anything that you can probably imagine scroll to anything that the user can possibly do cyprus has uh has uh something similar to that so there's there's multiple different actions but most of the time you're going to probably be using click or type but if you ever need to test some other action please go over the cypress documentation all right so what we're going to type is let's say drink a cup of water so that's what we are going to type so let's go ahead here and let's just see that in action so you can see here okay cool now what we want to do is we want to click on this save changes button so again let's go ahead and inspect this button this is a button uh with save changes let's actually use just contains for that so let's do sci.contains and then save changes dot click all right and then what we should do is once we type in something what we should be able to do is basically see that thing as a card inside of our dashboard so what we could potentially do is just say that hey psi dot contains and then we're going to say whatever that we've typed in here we're going to say that hey this should and we're going to say this should be visible so this should be visible and let's actually um let's actually do this just to make it a little bit nicer so this should be visible and one thing about great that's great about cypress is we can have multiple assertions for instance we could also say that hey this should be visible and we can have another dot should so we can also say that hey this should also have let me get rid of this this also should also have class so have class of uh let's quickly inspect this i forget what the class should be but this also should have class of so i believe this is the text so it should also have this particular class over here so it should have habit a card underscore underscore habit container so we can have multiple assertions in here so we can go ahead and save it and you can see that it has successfully been done now one thing for syntax if we have one should instead of having another should we can also just say and instead and it's going to do the same thing so we're going to say it should be visible and have this and that and that and ultimately it results in the exact same thing now how do you know what types of assertions we can have well again what you can do is you can just put the quotes and you can basically just read through uh the assertions that you want to use for instance like i mean these are very very easy to understand so you can basically see okay oh to be called once so maybe here we're asserting a function over here we're saying hey we expect this to be disabled or we expect it to be in hidden uh we expect it to be null so you can just read through all of these different assertions that we have and then you can basically use whatever assertion accordingly and you can always of course go to the docs and try to understand exactly what assertion works best for you all right cool so that's that so now let's go through the last one where we click on it we add a habit and then we basically click on this and this icon should particularly change so let's add another test so we're going to say should toggle icon when habit card is clicked so the first thing that we're going to do is we're going to get that button so let's actually just copy and paste this so let's actually copy and paste what we've done thus far so let's go ahead and let's copy these two or these three so the first thing we're going to do is we're going to get the button and click on it then we're going to add this placeholder or sorry we're going to place we're going to type this into the input and then we're going to click on the save changes button and then what we're going to do now is we're actually going to click on the card that was created so what we're eventually going to get is a card with that has that contains this text so what we can do is we can do psi dot contains and then we can just do a dot click okay cool so now what we can basically do is once we click on this let's just quickly see this right now so the first thing that we do is we get this x right here and let me just see you can see that this has an image tag and the source is this over here so what we can basically say is initially we can say that psi dot get and then we can say that hey the source should be equal to this and then we should we can say you can insert that this should be visible so this should be visible so when i save this you can see that this has failed okay let's see why that has failed did i do things incorrectly here [Music] okay i wonder why that actually failed let's see uh drink a cup of water oh it seems like because we clicked on it so actually we don't want to click on it so let's initially we're not going to click on it and we should see the x and that that succeeded which is cool but then but then when we do click on it so when we do click on it so let's actually go ahead and click on it now now this should not be visible it actually should be the check so this test should fail and it will fail but essentially you can see here that when i click on it you can see that it changes and it changes to checked so let's actually just copy that and then let's say checked and now you can see that all of our tests pass all right so i think that does it and i i think that kind of clears everything up again there's more things that we can potentially test for instance we could also test that hey if you don't put anything nothing changes or if you close this the modal disappears so that's something that you can probably test on your own for practice but these are the three tests that we are going to write for this page now we're going to move on to the next page which is the accomplishments page let us practice cyprus by just writing a few more tests and these tests are going to be tests that are related to the accomplishments dashboard so let's quickly go over the tests that we are going to write the first test is if you don't put any valid input for instance if we have a missing title or missing accomplishment or we didn't go ahead and check check this box we get this error over here saying that hey please complete the items above to continue so we're going to test for that the next thing that we are going to test is okay on a success so let's say we do input everything well we eventually get this loading state and then we get this kind of success page and then we're going to basically test that hey we get the success page what's interesting about this is that we don't get this text right away we have to wait a few seconds and i kind of did this on purpose to kind of simulate asynchronous requests and i'm going to show you how cyprus deals with asynchronicity and it deals with it very very easily now the last test we're going to do is once we go ahead and go to the success page we're just going to test that hey once we go back we go back to this dashboard and all of the input is empty because remember it wasn't empty before then you click on it then you go back and you can see that it is empty now all right so those are the tests that we're going to write and let's quickly begin with the test that basically tests for this error message so to do this let's go to our our cypress directory in here let's create another test file and then this test file is going to be let's call it dot accomplishments.spec.js and then let's copy the reference and then what we're going to do is we're going to have a describe block so a describe block and then in here remember we're gonna have a description of this i'm just gonna call this accomplish mint dashboard and then we're gonna have a fat arrow function and then we're going to have our before each hook and this is just going to visit the page that we wanted to visit so we're going to do side.visit and then we're going to say slash a comp accomplishments so psy.visit slash accomplishments all right cool now let's go ahead and write our first test and this test we're going to say should showcase error if information is missing so show showcase there if this information is missing so we can go ahead and the first thing that we're going to do is we're going to basically uh press this submit accomplish button but we're going to be missing some fields for instance we can say we're missing the uh let's say we input this we input this but we don't check the box so now we can basically uh we still get this error now one thing that we could do is we can basically test it for each case so let's say we do check the box but we don't put in a title we can also test that out but for now let's just say that hey we put in everything but we don't check the box and we should get this error over here okay cool so now let's just do psi dot get and now let's get by placeholder so we're going to say that hey we want to get let's actually actually i believe for this what i did was i gave this a data test id or i guess yeah right here i give it a data test idea so let's actually get by this attribute so let's get by this attribute because it's very very likely that in the future i believe i just deleted the whole thing in the future that this placeholder is going to change maybe we don't want it to be called title anymore maybe we wanted to call my accomplishment title or whatever you know it could potentially change so let's actually get it by data test id so let's go over here and we're going to say that the data test id is equal to this and then we're going to type something so let's say type and i'm going to say my basketball accomplishment so my basketball accomplishment and then let's go ahead and let's get the other one and let's see what i call this over here so let's go here and then this is called the accomplishment input so that's what the data test id is so we can do data psi and we can say accomplishment input we can also type something in here as well let's type in i made ten threes in a row and then we're not going to we're not going to check this box over here we're just going to go ahead and click the submit button let's get this by the text with contains so let's do psi oops let's do psi dot contains and then we're going to submit submit accomplishments or submit accomplishment and then we're going to go ahead and click this button so let's go ahead and just quickly test that thus far everything works out fine so let's go back to our test because now we have a new test file okay so you can see here that everything seems fine however it doesn't seem like it's uh it's not typing in the in the title and this is good this is what i love about the gui because it makes it easy for me to catch exactly what is going wrong because that's not something that i particularly expected so it seems like okay so it seems like i i got both the selectors so essentially the selector here is actually accomplishment title input so let's actually fix that so now if i save this you can see that everything is fine and we do get this error but we want to assert that we get this error so let's do psi dot contains this then we're going to say should and then we're going to say should be visible so let's go ahead and save that and then we can see here that we have successfully asserted this test all right so now let's actually wait for the positive case where we actually type something we check the button and then eventually let's assert that we get this landing page and to assert they get this landing page let's say that we get this success over here now again one thing that's interesting about this is we don't get it right away so you might think for other testing frameworks you know we're going to have to do something like wait for because because most testing frameworks run synchronously however cyprus runs asynchronously and if it actually if it can't find an element what it's going to do is it's going to re-run it until it eventually times out and that's really really really cool so let's actually go ahead and let's actually write our test and that way we don't have to really worry about asynchronicities which is which is really amazing when it comes to this test so let's say should display so this should display the validation we're going to say the validation component if all information is input say that this is an arrow function and then we're going to do psi and let's just basically do what we've done here thus far so we basically have we're getting the element and then we're typing it but now what we want to do is we also want to click on the the check box so we can do sci.get and this is actually an input element with uh if you go back this is actually an input element but with type of checkbox we could use the uh let's actually use this you know what let's use just to spice it up let's use type checkbox now later on if we have multiple checkboxes we're probably not going to want to locate elements in this way but just to learn we can do it this way so we can say type check box and then we can say hey we want to click on this and then all we have to do at this point is do psi dot contains so remember once we have successfully done everything we get this text over here so we can basically say that psi dot contains this text and then this should this should be visible all right so again one thing that's really interesting about this is this text is not visible right away because we get that loading state for some period of time however at the end of the day what it's going to do is it's going to re-run the test until that thing is successful let's actually go ahead and let's uh let's refresh this and you can see here that uh oh well the i actually forgot to click on the button so that's why that failed so let's go ahead and let's just click on the button so let's do this again so click on the button you can see that it's basically waiting and then it went ahead and was successful and that's terrific then that's really really good and it's basically just going to wait some sort of uh specified amount of time until it's like okay well um uh until basically uh it basically times out all right cool okay so that is that and then the last thing we're going to test is basically once we go back then what we want to do is we want to see we want to go back to this page over here and we want the input elements to be empty so let's just copy this test over here and then we're going to change this to should return back to accomplishment dashboard with empty inputs when go back button is clicked so when we go when we press the go back button we should go back to the uh the accomplishment dashboard and the inputs should be um empty so let's just get rid of this assertion right over here and let's just do dot contains and then here we're gonna say go back and we're just going to go ahead and click on this so we're gonna click on it and then what we're going to do is we want to say that hey we go back to this page so let's say that hey this this this piece of text is available so we can do something like psi dot contains and we can say h2 and then we can say the actual content and then we can assert that this should be visible and then we want to insert that the values of these things are empty so let's actually go ahead and get these so let's go over here we got them with this right here but this time we're going to say that instead of typing into them we're going to do an assertion on them so we're going to say that hey these these guys should have value of empty so they should have value of empty similarly over here this should have value of empty now the last thing is we're going to make sure that this is not checked so let's get this element over here and then we're going to say dot should and then we can see here that we have b dot checked so b dot checked so this is basically asserting that this should be uh checked now with every single assertion we can add not in the beginning to basically have the opposite case so not be checked so you can go here save it let's just wait a little bit and there we go the last one there we go everything has been successful so cool so that is another set of tests and that's pretty much it for project one now we're gonna move on to project two where we're going to actually be dealing with a client that actually is communicating with a real server and we're going to figure out how we can test things with that so far we have been dealing with testing applications that are not making http requests to a back-end service now in this section we're going to change that we're actually going to work with our same client our dashboard application but this time it is going to be interacting with a server that i also created and it's going to basically mock an application that actually interacts with the server now one thing that's great about this is because cypress is inherently asynchronous it's really not ultimately going to change how we test our application so regardless if it's going to make http requests or not the tests are ultimately going to stay relatively the same so let me just kind of explain two different approaches that we can take when testing our application now before i do this go ahead and go to project two and in project two you can see here that we have a client and a server so in order to open up the uh the client just cd into the client and then do an mpm install to install all of the dependencies and then do an mpm start to start that application and you should get a terminal window that looks a little something like this now then cd out of it and then go to the server so go to the server so then you would just in another terminal window you would cd into the server directory install all of the dependencies and then do node index dot js to start the running server you should see a terminal that looks a little something like this don't mind these errors you should see something like now listening on port 3000 and the last thing that we need to do is once everything is up and installed just go to the client so cd into the client and then just do an mpx cypress open in order to well initialize a cypress application and open it up inside of your terminal window and this is very familiar we've seen this before and let's actually just quickly get rid of this so over here we're just going to say that we want to ignore some files so let's go ahead and let's do that right now let's go and ignore some of these files and let's specify a base url so we're going to say the base url is http colon localhost 3000 then we're going to say that hey we want to ignore some test files and these test files exist right in the examples directory and that's pretty much it so if we save this and we eventually go back we should see uh some errors and that that error basically should well let's actually just say that i got this we should see basically an error saying that hey there's no uh test files here so it seems like it has just pretty much failed which is which is essentially what we want ultimately all right cool so now the absolute last step and it seems like let's actually go ahead and let's just do mpx cypress open so now what we want to do is we actually want to test out our application now our application is a little bit different so our application if we go to localhost 3000 and i refresh the page you can see here that the application is a little bit different so over here instead of elements we have rewards and we're gonna test this out first so essentially what this is is um a bunch of rewards that uh basically we got for accomplishing our habits but this isn't something that uh we went ahead and input right away from the client this is actually a request that we made to our server and our server got us back this data and we can actually see this by looking at the network tab so if i were to refresh this you can see that hey we made a request to localhost 4000 right over here so localhost 4000 slash rewards and we got back this data and over here you can see that we got this data so what we can do is we can basically test that we got this data and essentially there's two ways that we can basically test something that's interacting with a server so the first thing is we can basically test the client and the server so we can basically say hey i expect i expect that hey we get this list so we get this list and essentially what this is doing is testing that hey the client is rendering it appropriately as well as the server is sending that data so we can basically test these things simultaneously or what we can do is mock the http request and that way essentially what's going to happen is we're going to send back some dummy data that's not coming from our actual server but it's mocking what actually is what actually our server is sending and that way we can really just focus on testing the client side over the server side and there's very very good reasons why we want to do this and i'll get to it in a little bit but first let's just do this one over here and let's just test that hey we get these uh these uh basically this this list right over here okay so let's just make sure that everything is running appropriately so it seems as though everything is running we have our tests okay got it uh seems like in the cypress.json i did put the i did put the you know what let's just get rid of the examples let's just get rid of it i'm not sure why that's not working appropriately so let's just do that and now if i were to refresh i guess this is not still not working uh okay cool so now in here what we're going to do is we're going to add another test file this is going to be called rewards.spec.test so rewards.test and this is js not typescript and then in here we're going to let's just double check that this works cool it does in here we're just going to have our reference so remember we're going to have that reference type and that reference type is going to be of type cypress and then we're gonna have our describe block so the describe block and this describe block is gonna be called accomplishment dashboard or actually wait this is not the accomplishments we're going to call this the rewards dashboard okay so the first thing we're going to do is we're going to test that hey these rewards are um basically placed here we can actually see this rewards and what that does is it basically tests the client that it's rendering these rewards appropriately and also testing the server which is uh sending off these rewards and if you want to see the server very very simple application you can see here that we have a get route that basically sends back these rewards very very easy it's not interacting with the database or anything and then we also have a poster out that we'll talk about a little bit later okay cool so the first thing that we're going to do is inside of this describe block is as always we need a before each hook that's going to do psi dot visit and then we're gonna go to slash rewards and then let's have our first test so we're gonna say should display a list of rewards so it should display a list of rewards and then in here what we can do is we can just say psi dot get and what we can do is we can basically get let's get the let's actually inspect this uh if we inspect this you can see here that we have a ul tag so let's actually get this ul tag so side.get this ul tag and then we can say that inside of this ul tag we should have uh we should have some text that contains uh this right over here so we we have this text and we have this text so let's just say dot should and we should say that it should contain and then we're going to say it should contain 500 500 points uh 500 points for drinking eight cups of water for seven days straight we can also append an and in there and then we can say 850 points for a fasting for five straight days so if i were to save this and go back here and run this test you can see everything is fine and dandy it actually works and again what this is doing is it's testing both the client and the server and what's great about cypress is you can see the http request that was made so we made this and then it went ahead and asserted that hey the client and the server are working correctly which is cool but there are some cases where we actually don't want to get the data from the server itself and the reason for this is let's say we are asserting the content but what if the server is dynamic and it always is going to render different content what if you know for instance it's not going to render this and it's not going to render that maybe it changes over time that could cause some failures also what if the server renders this content relatively slow and we want our tests to run a lot faster so that is a problem another problem is we could basically face cases where we're adding data so we're posting data and we want to test that and we don't want to actually make that request to our server which eventually will add it to our database if we are connecting it to the database so instead what we can do is mock http requests so we can basically tell cyprus and this is actually true for any testing framework really but we can tell cyprus that hey if we make if if uh this test eventually encounters this http request we want you to intercept it and return back this data and the data that we return back is going to conform to the data that the server would usually send back because again we're mocking it so let's actually go ahead and let's do that right now so now what we're going to do is we're going to basically test the exact same thing but this time we're going to mock the http request so let's add another it statement and then here we should say it displays a so it displays a list of rewards but this time we're using a mock okay so the first thing that we need to do here is we need to intercept the http request so remember the http request that is being made so if i went to the network so the http request that is being made is to our server which is http localhost colon 4000 slash rewards so we need to intercept this request so let's actually go ahead and let's copy that and let's intercept it now how do we intercept a request well we use the sai dot intercept command and then over here the first thing that we're going to do is specify uh what the method of this request is so is it a get or is it or sorry what the verb of this is so is it a get request is it a delete request is it a post request this is a get request and then we're going to specify the url that we want to intercept so we're going to say that if you ever had hit a get request that is making a request to this particular url we want you to intercept it and send back some data and what that data is is going to be inside of this uh inside the second parameter right or the third parameter right over here so essentially what we're going to do is we're going to say this object and then we're going to say fixture and then we're going to say rewards dot json rewards.json so what does this mean over here well as you can see we have this fixtures directory and what this fixtures directory basically contains a bunch of json files that mock json data that's really all it is at the end of the day so what we can do is we can create a rewards.json so we can create a rewards.json and then we can go ahead and basically add some some data in here so let's actually go ahead over here and let's just copy let's copy some some data it's actually copied let's copy these three and i might have to do a little bit of you know what let's actually go to my github page let's go to final this is just going to be a lot cleaner you can go to clients we can go to cypress fixtures rewards json we can just copy this data so essentially what this is going to do is just again this is just some data that we're going to use to mock our http requests and essentially here we're saying that hey we want to use the fixture of json or rewards json so send me back this data right over here and this is all that this is doing so it's intercepting the get request to this url and it's sending back this data so we're actually not making a request to the client we're just going to send back this data by intercepting it and then ultimately what we can do is we can make the same exact assertion so now at this point we can pretty much ensure that hey we're getting back this data all the time and this is going to be super fast because we're not going to make any http requests and if you know there's some actions like adding to the database or caching or whatever we're going to skip that because we're intercepting it so let's go ahead and save this and now you can see it works perfectly fine so the first one you can see all of it and this was because we made a request to the server but here you can see if i go here you can see that it didn't work which is strange i was not expecting that actually i was expecting to only see three um and this didn't really work the way that i intended it oh wait okay that's because this is localhost uh fourth three four thousand not three thousand we intercepted the wrong url so let's go ahead and you can see here now we only have three okay cool so you can see that it actually intercepted it and he used the data that we put inside of our um our words.json okay so that is really really cool so now let's actually just move on to the very last one and the very last one is basically the accomplishments page and this time we are making http requests so this is going to be uh something that's uh so we still have our validation over here and this is just a client-side validation but we can also go ahead and we can yeah go ahead and do this successfully and this is going to make a post request to our api and you can see that the message is you get accomplishment sent now another thing that i added is maybe we want to have some sort of filtration we don't want people to put any sort of word in there we don't want anybody to put any word maybe we don't want people to put you know cuss words or bad words um and i'm not gonna go ahead and start typing some bad words so what i did was inside of the server i basically uh essentially said that hey if the title or the accomplishment includes a graph and this is going to simulate a bad word it's going to return a response of your content is not appropriate and the client is going to take this response and it's basically going to showcase that error so if i put graph in here you can see here that it actually makes an http request and it sends back your content is not appropriate so this actually again is going to be a kind of a client server model and we could go ahead and basically test the client as well as the server and let's actually go about doing that right now or we can mock the response so let's actually go ahead and let's just test the client and the server and then we're going to have another test where we mock the response okay so let us go here let's add a let's ah do where are we going to call this role we're going to call this accomplishment dot spec dot js and then let us add this let's add the describe block so we have a describe block in here and then this is going to be the accomplishments dashboard and then let's also have a before each of course because before each we're going to run this and i'm missing some syntax here before each we're going to do accomplishments and then we're gonna have an it block and we're gonna say should display in appropriate content error when text or accomplishment includes graph because this is an inappropriate word for our sake for some reason okay so let us go here and let's do psi dot get let's just do let's just get by the placeholder so we're going to get by the placeholder that is equal to title and then what we're going to do is we're going to just type in let's just type in this is my accomplishment all right so nothing with graph here but then let's just say that for the text area we have the placeholder and then this is going to be my accomplishments and then what we're going to do is we're going to uh type in here that my accomplishment is i pet a giraffe so i pitted a giraffe that was my accomplishment but we're including the bad word which is giraffe and then of course what we're gonna have to do is also click on that check box so let's do type of submit so get the element with type of submit and we're just going to go ahead and quickly click on it cool and then we're going to do psi.get we're going to have to click on the button let's just get it by the element and let's click on it again this is probably not good practice but uh whatever just for a quick sake so now essentially because this contains graph we're going to basically expect that this content is visible so now what we can say is psi dot contains and then we're gonna say that hey your content is not appropriate we're going to say that this should and this should be this should be dot visible so if i save this and then we go back here we go to the accomplishments page and it seems like we didn't really click on the button itself so type of not type of type of checkbox there we go there we go and it has worked and you can see that it actually made a request and you can see the take this has returned back a 406. so this is really really great and this is testing again the client and the server but again what if we don't want to do this what if you know if we add this and this ends up saving to our database and we eventually don't want to do that or we end up caching it or or um you know there's multiple reasons why we eventually really don't want our tests to be interacting with our server we might want separate tests for that but uh we don't want our actual test to interact with our server and start making real http requests so instead again what we can do is mock this request so we can basically save this we can basically copy this we can just say that hey this time we want to do this with a mock and then over here similarly what we can basically do is psi dot intercept so we can do psi dot intercept and then what we can basically do is you can say that this is a post request and then we can say http and then we can say local host localhost 4 000 and then of course then we're going to have our uh function now we don't necessarily have to have a fixture in here we could also have an arrow function that is basically going to perform some sort of logic and the the function is going to contain the request itself and what we can potentially do here is do something like request dot reply and then this is going to reply with a response so it's going to reply with a response and the response is going to be well we can do res.send and then the response is going to be of message and then your content is not appropriate so just to quickly clarify this uh i believe i misspelled that let me just quickly copy this and paste it in here just to quickly clarify this when you make a http request you get back this response over here with the message of your content is not appropriate so what we could do is we could also add a handler here instead of a fixture we can add a handler that's basically going to reply with this object right over here your your content is not appropriate so now if we go ahead and save this you can actually go here and you can see that this was actually intercepted and just to prove this to you i can say that your uh your uh shirt is not appropriate for some reason and you can see that that's exactly what's displayed however of course the thing is going to the assertion is going to fail because that's not actually placed inside of our ui element so let's just say content is not appropriate and you can see that this actually intercepted the request all right i think that's pretty much it for this crash course i hope you guys enjoyed it i actually really enjoyed learning more about cypress and teaching it as well and it's something that i'm definitely going to be consistently using throughout all of my projects and applications so uh stay tuned for the next one
Info
Channel: Laith Harb
Views: 7,826
Rating: 4.9874606 out of 5
Keywords:
Id: avb-VDa3ZG4
Channel Id: undefined
Length: 123min 4sec (7384 seconds)
Published: Sat May 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.