Cypress Tutorial - Writing E2E Tests For Your Apps

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone so this is going to be a cypress tutorial now cyprus is a testing framework that i really love that allows us to write tests super intuitively super easy and it kind of makes tests kind of fun and what i did was i forked over a repository from cassie due's github if you don't know who cassie do is i highly recommend you go follow her on twitter because she makes super entertaining dev content i've worked over her teddometer repository which is a to do app but it has some more advanced features than a kind of like a tutor app you might use to learn react and i thought this was perfect because a lot of people already know how to do apps work at least a lot of people do but this has more advanced features for us to be able to write tests for so that's why i thought this was a great idea so what i want to do is i want to go ahead and demonstrate all of what this app does and then we'll talk about the tests that we're going to be writing okay so here is the app that we're going to be writing tests for so you can see this is the date and then here's the weekday and the reason why it shows that is because that kind of comes into play into some of the functionality of the app that we'll go into in just a second we can go ahead and create a new to-do i'll create three tests one two and three and i wanna show you the different states that to do's can be in and that sort of thing so i'm gonna click pause on uh test one and you can see that it goes to this do later accordion and if i click complete on test two it creates a new accordion called completed so now we have three different lists we have ones that are already completed we have ones that we've put off till tomorrow and then we have the ones that we need to get done today now with that being said you can look here at the top that it separates them into their own colors so the ones that are paused and put off till tomorrow that's represented by yellow and the ones that are completed is represented in green and what this is saying is 75 or actually this is more like 66.7 of all of my tasks for the day are complete and out of that 66 50ish percent of that is completed tasks and 50-ish percent of that is tasks that i've put off till tomorrow and then you can see that this is the amount remaining so this is a little progress bar of your tasks it's going to send you a notification if you have notifications enabled on your browser that says something like you have some tasks to complete you know blah blah blah so it's going to send you a push notification and we're actually going to be testing that in cyprus the original application let you set the interval of time between like 15 minutes 30 minutes or an hour but in this version of the app i actually just set it to do it every 30 minutes on the second now as you can see here at the bottom there is this reset progress button now if i were to click this i want you to look at the way that this app is right now there's um there's three different to-do lists completed due later and the pending items if i click reset progress what happened here was that the completed items were deleted the pending items stayed the same and then the paused items moved into the pending list that was by clicking the reset button now if i have all of my to-do's and i don't click the reset button and i had it just like it was previously if it rolls over to the next day then it's going to do that automatically and also it's going to send us a push notification as well that says resetting and we're going to be testing all of that in cyprus so what i'm going to do is i'm going to start off by showing you what it's going to look like when we're done so here we have a full test suite that i'm going to run right now and i want you to watch what happens and as you can see it opens up a browser and it's automating basically somebody using the app and it's clicking on a bunch of stuff it's adding to-do's it's deleting stuff it's doing all sorts of crazy stuff it's doing it very quickly and while it's doing that it's checking to make sure that it's doing things that we would expect it to do just the exact same way that we would expect it to another really cool thing about cypress is i can click on any of these tests so each of these is a test i can go to any of these tests and i can hover over each of these steps and each of these steps if you look on the right is a frame in time so i can actually look at every single thing that happened inside of the application during the tests and i can actually go so far as to pin that so that i can inspect the element and see exactly what things were like at the time uh that something might have happened and once it's all over i can actually come in here and interact with the dom and everything so it's super cool and super helpful for debugging and is just really awesome so that's what it looks like when it's complete so we're going to go through all of this and i'm going to write the tests and explain everything and how that works but i wanted to quickly mention a couple of things this app was originally written by cassie do as a electron app built using react and as of november 2020 cyprus does not support testing electron apps so what i had to do was actually had to go in and change the code to make it a normal react application and in that process i actually did some things like adding some test ids which is going to help us a lot when we're writing our tests so we can select things in our tests very easily and reference things in the tests so what i did was i have a github which is a fork of the original as you can see here and i have two branches now if you're wanting to follow along with this tutorial and learn as we go please switch over to the tutorial branch because that is all of the finished source code without any of the cypress stuff so that's what you would want to start with however i've also included in the master branch the complete full code including all of the cypress tests and as you can see inside of here i included lots of comments throughout so you can see what each of these things are doing if you don't feel like watching the video so i've included those links in the description below and while you're there please go ahead and give me a like subscribe if you haven't already and let's go ahead and get started with this tutorial alright so what we're going to go ahead and do starting just right off from scratch is cloning the repository so i'm going to go ahead and type in git clone paste in the repository url and then click enter and it's going to clone the repository from github so once this completes we're going to cd into it and install all of our dependencies and all that good stuff so it's completed so i'm going to go ahead and cd into that and let's take a look at git branch so right now it just says master is the only branch but what i'm going to go ahead and do is say get checkout tutorial and now i want to ls to make sure that the cypress folder is not in here so if you switch over to the tutorial branch and you're following along make sure you type in ls and make sure that there's no cyprusy stuff inside of here yet so if i do get checkout master and ls you can see that there's a cypress folder but you want to make sure that if you're following along that that does not exist anyway i'm going to go ahead and check back into the tutorial branch oops i think i typed that wrong all right cool cool so i'm going to go ahead and type in npm and install cypress because we're going to need to install cypress however i'm also going to need to make sure that we install an eslint plug-in and the eslint plug-in what that's going to do is it's going to make sure that we're not getting any eslint errors when we're writing our tests so go ahead and put a space and paste in eslint hyphen plug-in hyphen cypress click enter and let all of this install it'll probably take a minute or two now that that is complete i want to open up my bs code and open up that folder where we have this tutorial and i'm going to go ahead and zoom in for you all so you can see it and what i need to do is i need to actually create an eslint rc file so in the very base of all this type in eslint rc.json to create this file and what you're going to want to do is you're going to want to paste in the same configuration that i'm using right here which again just ensures that you know you don't get any eslint errors when you're writing your tests cool so with that aside we really don't have to worry about any more of that kind of specific stuff and we can focus just on cypress and we need to write a new command that lets us run our cyprus tests the command that we need to create is called cyprus and the command that we need to run is called is actually npx cypress open you're just using a more recent version of npm you're gonna already have npx so you don't have to worry about that if you're using an older version if you try to run this it's not gonna work i would go ahead and update your version of npm so that you can stay up to date with the latest tools anyway so with that i'm gonna go ahead and make sure i zoom in here and run npm run cyprus which is that command that we just created and let's see what happens here as you can see a little dashboard pops up and i want you to go back to your vs code so that we can take a look at something notice that there's a cypress folder now and a cypress.json file running cypress for the first time is going to create these this uh this folder and this file for us which is really neat and inside of this cypress folder we have four different folders support plug-ins integration and fixtures now inside of fixtures you're going to put things like your mox if you're communicating with an api you can actually mock your api requests and you will want to put all that kind of stuff in here but we're not going to be doing api requests in this tutorial so i'm going to delete this example file and inside of integration you can see an examples folder with a bunch of different tests in there we're going to go ahead and delete those and now inside of plugins that's where you can put literally your plugins and inside of support there's this commands file we're going to be creating a custom command at uh pretty early on in this tutorial so i just want you to keep in mind that this commands file allows you to write custom commands and cypress makes it super easy for us to write our own custom commands to reduce boilerplate code alright so i went ahead and closed my package.json file because i'm not going to need that anymore at least right now and i'm going to open my integration folder and i want to create a new file i'm going to prefix it with one and the reason why is because it runs the tests in a specific order it actually runs it in alphabetical order and we want our tests to run in a particular order so i'm going to actually put o1 to prefix the test and then i'm going to name this test to do.spec.js cool so the very first thing i want to do inside of here is paste this line right here three forward slashes and then reference types this allows our uh code editor to access cypress's intellisense and also if you're using typescript i'm pretty sure this will help with that as well but we're not going to be using typescript in this video that was just more for information but yeah this is going to allow us to have intellisense so the first thing i need to do is type in context context is literally that it's what is the context of the tests that you're going to be right and the context here is to do's that means that the tests that we're writing in this file are in the context of to-do's and for each test that we write we're going to use it and we're going to put a string in here and what it's going to say is like what it should do so it adds to do's so it should add to do's if it doesn't had to do then it's not working right and the second argument is a function now the function is going to be the tests that we're going to write essentially each individual command the first thing that we want to do is we want to make sure that we navigate to the app's url and in order to do that we could do this we could say cy which is cypress's alias here cy dot visit and we could just type in manual http colon forward slash forward slash local host 3000 and i'm going to save that just so we can see it work really quick and i'm going to run this just to make sure that it does indeed go to localhost 3000 okay the reason why it's not doing that is because we actually need to be running the application while we're running the tests so inside of here i'm going to create a new tab and navigate back to where your project is so i'm going to do that right now and once inside of there i'm just going to run npm run start or you can just do npm start okay it says react scripts is not recognized as an internal external command so i'm actually going to need to run npm install one more time so i'm going to let this finish really quick okay so apparently i had forgotten to run npm install we installed cypress and the eslint plug-in but we forgot to run npm install to get all the other dependencies installed so that should be good to go now so i'm gonna go ahead and clear this out and run npm run start to get the actual app running and then this the app itself needs to be running uh while we run our tests so once this finishes booting up all right it's finished on my end i'm going to stop this and then restart the test so that we can make sure it navigates to the location awesome so it does happen to go to the proper place but what i was kind of getting at was i we don't really want to hard code the url because we may be running these tests in different environments and the url may be different for example we might be running them in a integration like a continuous integration server or we might be running them on a staging server and they may have a different urls in every single environment so what we want to do is create an environment variable that we use in order to get that url so the easiest way to do that is to actually create a file at the top level at the root level and call it cypress cyprus.nb.json and then in here we're just going to put a json object and i'm going to call the very first property of this base url and i'm going to set the value equal to http colon forward slash forward slash localhost 3000. so now we have a environment variable that represents our url but how do we access that in here well it's actually pretty simple we can just clear this out use capital cypress and dot n and then that's a function and we pass in the property that we want to access inside of our environment variables which is base url so i'm going to save this and then i want to run the test again and see if it still works so it still works perfectly fine which means that our environment variable is working perfectly fine all right so now that we know that that works good with environment variables we can actually go ahead and start writing our our actual tests now we're going to be using local storage here to actually store all of our to do's so every single time we write we run this test suite we want to make sure that we clear local storage so that we start with a fresh plate or a fresh slate is what i meant um c y dot clear local storage does that for us so just by running this line of code it's going to clear all of the local storage out and now we're going to start off with a nice clean slate very first test that we want to write is to make sure that we're able to add to do's when we first start off we want to make sure that we don't have any to do's on the screen at all yet so we want to make sure that the length of to-do's is zero and the easiest way to test that is to use the test ids that i put into the app and make sure that the length of the to-do array is zero we can do this really easily by referencing the data test id like this so we're saying cy.get and we want to get an element where the test id is equal to to do like this now we want to say that it should have length and the value should be zero now what this is saying is the we should be able to get a all of the to do's on the screen and we should only have a total of zero so let's run this and see what happens it works now just throughout the process of writing tests i like to make sure that it fails when i expect as well and what i mean by that is i'm gonna come in here and i'm actually gonna put one let's see what happens if i say should have length one okay great so now it's hung and it's going to fail so give it a second perfect it failed and the reason why i want to do that is i want to make sure that the quality of the tests that i'm writing is good so it should always fail when you expect and then it should then pass when you expect and if you're just writing tests and you're not checking to make sure that they fail you could be writing tests that always pass and you don't want to do that so i like to make sure that i'm writing tests that fail and then you know flip it to make sure that it passes when i would expect it to that's awesome but we're going to be doing this uh get by test id thing a lot so this is where i want to write a custom command really quick so this is very simple we just want to go out of the integration folder and into the support folder and into this commands.js file now i want you to paste this in cyprus.commands.ad well you're gonna have to type it sorry i'm gonna paste it but you'll have to type it dot add and add is a function in the first property of add is the name of the command that you want to create and the second is a is a function and inside of this function you can put any number of commands inside of here so basically what you're doing is you're taking a bunch of boilerplate and reducing it to a single command and this becomes super helpful when you have very very very complex things that you're repeating throughout your tests you can really reduce the amount of boilerplate by creating custom commands like this but this is just going to be relatively helpful for us because now we have this custom command called get by test id and to use it all we have to do is get rid of this and it automatically creates this command for us now so i can say cy dot get by test id and we want to pass in the test id that we want to get which is to do now let's run it and make sure that this still works well actually we need to change that back to zero really quick because we still have it at one so let's change that to zero and it works perfectly fine so yeah so i just wanted to um show you how custom commands work and we're gonna be using this throughout the entire tutorial so it's super helpful for us so moving on what we're gonna do here is we're going to create our first to do with the test and we're going to access test id and the test id we want to grab is add to do input so we're grabbing an element with the test id add to do input which is the input that you type inside of in order to add to-do's and inside of there we want to put use the type command and it will literally type into that input whatever we put inside of here which in this case we're going to put learn cyprus as our first to-do then the second line here is just saying we want to grab the add to do button and we want to click it and so let's save this and see what happens here as you can see it happened so fast you could barely see it but it typed that in it clicked on the button and it added the to-do so i want to just have three to-do's in the beginning to work with so i'm gonna paste this in i want you to you know create whatever to do's you would like using those lines of code that we just went through in my case here i'm gonna say write tests and be happy and save it just to make sure that it runs through and it's still working as expected so just like we did in the very beginning of this test we checked to make sure that there was zero now that we've created three to-do's we want to make sure that there's three so as you can see here dot get by test id should have length three this is you can almost read this code like it's in english which is really good and i save it and now we have a passing test and this test is pretty much already good enough to say that it works but i like to go a little bit further and i'm gonna show you i'm gonna paste in this code and tell you what it does so the first piece that i pasted in here is going to say that the very first to do on the screen should have a text value of learn cyprus and the very first one has that so this test should pass now um the the last three lines here it's calling each of the three individual lists if you remember there's a pending list a pause list and a completed list of to-do's i want to make sure that paused and completed list are empty and that the pending list has a length of three so that's what these are saying and you know i can kind of go through and explain what this is saying but i think it's pretty self-explanatory we're saying cy dot get by test id pending list and the children inside of that list in other words all of the to do's inside of that list should add up to have a length of three and then zero and zero for the other two so saving that we go in here and the tests are all passing now we have successfully written our first test so so far you can see how easy it is to write tests in cyprus so with that being said i'm going to kind of breeze through the rest of these tests until i get to a part that might look a little bit more unfamiliar to you and then dig into that but i think you get a pretty good understanding of what's going on here so i'm going to start moving a little bit more quickly so if we remember we wanted to make sure that we tested the to do's that we can add to this but we also wanted to make sure that we couldn't add empty to-do's so under the first it i'm just gonna call it an it we're gonna put another it and we're gonna say does not allow users to add empty to-do's and it's just a three-line test let's take a look at it so we just wanna make sure that the to-do list has a length of three we want to click on the add to do button because we know that the input is empty because we haven't typed anything inside of it and we want to make sure that the length of the to-do list is still three and that is a very simple test that allowed us to make sure that we could not pass in empty to-do's so our third test here is to make sure that we can pause to do's now i'm going to go through this and talk through it as we go getting rid of the comments the way that contains work is it basically says does the screen contain the text do later anywhere on the screen is there the text due later in this case we want to say that should not exist so in other words we should say what we're saying here in plain english is do later should not be on the screen right now this is the second because it's just like an array zero is the first item one is the second we want to grab the second to do click the pause button on that and then now do later should be on the screen because do later is the header for the accordion of all the paused to do's then this triple line of code is just like the triple line of code up here but now we're making sure that the pending list has two and the pause list has one and the completed list still has zero so i'm going to save this and watch this run really quick as you can see do later is on the screen and the tests passed and there's one inside of here and two inside of here so you can also confirm these tests with your eyes as you go through here so that is the paused test let's go ahead and paste in the resumes to do's test which is going to just basically make sure that we can resume to do's manually instead of waiting for them to reset so the very first three lines just says we want to make sure do later is on the screen because we do have one paused already then we want to click on the resume button and then we want to make sure that do later no longer exists on the screen and now we're back to the original state of pending list having three pause the list having zero and completed list having zero so let's save this and have a look all of the tests are passing you can see that in the as i hover over this you can see originally do later was on the screen and as i drag my mouse down this you can see after we click on the resume button the do later disappears and the tests are passing as as expected so the next to do test is we want to test that we're able to complete to do's so under that it i'm going to paste in this test and we're going to talk about each of the lines that's happening here and i bet you can already guess what's going on here uh we want to make sure that completed is not on the screen initially then we want to grab the third to do and click complete on that now completed should be on the screen then we want to make sure that pending list has two paused list has zero and completed list has one so let's run this test and have a look and again the tests are passing you can see completed is right here and you can see this has two and this has one and the paused list is zero awesome so the we want to make sure that we can delete to do's so pretty much the same thing but a little bit easier let's go ahead and paste in this it right here and what this is saying again is we want to make sure be happy is on the screen and it is actually one of the to-do's so be happy is on the screen and we want to grab the delete button the third delete button on the screen so let's actually take a look at what this is doing there's three delete buttons on this screen and vertically in order the third delete button is be happy so if we click on this delete button this is the third delete button if we click on that we're effectively clicking the delete button for the be happy to do so keeping that in mind we're saying we want to find the third delete button click on that and then once we click on that be happy should no longer exist on the screen and then pending should have two paused should still have zero and completed should now have zero so let's go ahead and save that and take a look and as you can see all the tests are passing and it looks just as you would expect it to look here on the on the right side so so far so good let's go ahead and uh finish up this with our very last to-do test which is allows users to reset the to do state manually now this is going to be a slightly bigger it block so i'm going to go through this one i made sure to put the three rules that we talked about earlier right here at the top the rules are paused items will move depending completed items will be removed and pending items will remain unchanged whenever the reset button is clicked so going down this block i'm going to explain all of these things and kind of explain the logic so we want to get the reset button and say that it should not exist because initially um based off of the last test here which you can see right now there is no reset button and that's because none of the to do's are completed but if i come over here and click on complete for one of these to do as you can see it moves to the completed area and now the reset progress button is visible so with that being said initially it should not be visible then we're going to go ahead and add a new to do called test reset command so that's what these lines are doing now we should have three pending items because we just added a new to do and then the others should be unchanged now what i'm doing is i'm completing one to do and i am pausing another to do so now at this point in in my head i'm thinking okay we should have one in each list we should have one completed to do one paused to do and one pending to do so that's what this is saying then finally we're gonna go ahead and click that reset button and what i would expect is the completed to do should disappear so then that means that the length should be zero just like right here hopefully you can see what i'm highlighting i know that my little video is in the way possibly but sorry about that um paused list should then be zero because the paused item should now be in the pending list which means that pending list should have two and that's what the logic of this test is saying here so i'm going to save this and make sure that all of this runs as expected and it looks like it did so i'm just going to break this down and just kind of scroll down and make sure that everything is happening just as i thought it would and it is so that is great and that's really the beauty of cyprus is it really makes it so easy to write these tests and it uses popular syntax that everybody's familiar with if you're used to writing tests so just a quick side note that um we're going to be writing the tests to test notifications but if you want the actual uh notifications to work for the app without having to stub them which we're going to be stubbing these well i'll talk more about that in a second but if you want to actually physically see these notifications on windows 10 i actually had to follow these three steps i had to go to my settings and i'm talking about operating system settings and i had to navigate to notifications and actions and then i scrolled down to ensure that chrome was enabled because on my end it was disabled so you have to make sure that that works now on os 10 i have no idea it probably works differently um just quickly google it if you want to be able to see how to do that but we're going to be stubbing that now what that means is we're basically going to say we're going to create a fake function that replaces the browser's concept of notifications i know that sounds crazy and we're going to spy on it and say if and basically determine whether or not it's been called as expected so again hard to talk about in english so let's go ahead and just do the code so inside of integration we're going to create a new test file i'm going to prefix this with o2 and this is going to be notifications or notification let's see what we want to call it notification or notifications we'll do plural notifications.spec.js and go ahead and put in our context and the context is of course notifications or function and we can start building our first it block the first thing we want to test is that it displays 30 minute reminder if there are pending to do's so display is a 30 minute reminder if there are pending to do's now this one was a little bit tricky for me to figure out but they do offer a very convenient api for being able to do this so i'm going to talk us through how all of this works so the very first thing that we're going to do is we're going to stub the window.notification object now notifications if you want to do push notifications and apps you're actually going to be using the notification api which is going to be end up being an object on the window the window object so there's going to be an object called notification which is a based off the notification class set on the window object itself and you're gonna there's an api for you to be able to communicate with that class and it allows you to show notifications and here in the code what we're doing is we're visiting the base url just like we did in the first test to make sure that we're on localhost but we're adding this on before unload thing and we're passing in the window object here and we're saying we want to stub notification on the window object and we want to call it notification so this dot as notification is basically like us setting a variable that we can reference later in our tests called notification so keep that in mind and we're going to move forward a little bit remembering that we now have stubbed notification so we now have a way to tell whether or not a notification has been called or not so with that being said let's go ahead and add a pending to-do item so this right here is going to add a new to-do called cyprus or learn cyprus and i'm gonna save this and actually open up my dashboard and click stop and click on notification specs so that we can be running this instead of the entire test suite as we go so so far so good we can see that it created our learn cypress and i'm not seeing any errors and if you hover over here if you bring your mouse on the left side at the top you can see there's this new section called spies and stubs i'm going to open this up and you can see that we have in fact created a stub on notification and you can actually see the alias name is also notification so that's also super great there's a visual confirmation that we've successfully created our stuff super helpful so what i want to do is i want to use the cypress clock api to set the browser's time to a specific point in time now the specific point in time that i want to set my browser's clock to is this crazy number right here but in utc or in uh in in javascript timeland this represents november 27th at exactly midnight and i'm doing that because that's an even 30 minute slot and if you remember every 30 minutes on the second it's going to show a notification so what i'm effectively doing is moving the browser's concept of time to midnight at a time when we would expect a notification to happen except this is exactly one second before midnight i apologize i said it was midnight but it was actually this is 11 59 59 seconds so one second before midnight and one second before midnight we would expect the notification not to have been called yet so that's what this is saying because we would expect this to be called at exactly midnight so one second before midnight we wouldn't expect a test a notification yet so we're going to cl we're going to tick forward one second in time and now that we've ticked forward one second in time we would then expect notification to have been called with you could say uh you could see here we're saying we're gonna get that stub and it should have been called with todometer reminder and if i just copy this code or this line of text and search for it here you can see that's what we're calling our notification with in the actual application so the title of this notification is todometer reminder so we're making sure that the notification is being called with that so that we're not just getting another random notification we want to make sure that our tests are passing perfectly as expected and then afterwards after we run that we want to make sure that we restore time back to normal otherwise we're going to just get an infinite loop of notifications which we don't want to do so this is saying cy.clock which is a promise and once that promise resolves we're going to take clock and call clock.restore to restore time back to normal okay so i've gone through all of what this does and the logic behind it let's watch it work awesome now as you can see we can go through time and see that uh we've created the to-do and at this point the notification has not been called we took forward a second now it has been called but you can't see the actual notification that's perfectly fine because right here um i'm not sure if you can see this i can maybe zoom in just a little bit you can see that it shows the actual notification here right here so it says two dominar reminder and the body of text don't forget you have one task to do today one incomplete blah blah blah so it actually shows that right there so you don't have to manually go in and make notifications work for your app in order for you to test it super convenient super convenient okay so we now have uh tested the notifications for a 30 minute reminder we also want to test notifications on the following day because if you remember when it becomes the next day we're going to send a notification that says hey we're resetting everything and then we're going to call reset so let's do that so now that you have the knowledge of how that last test works this is going to make a lot more sense for you right here so i'm going to paste in our next it block and again walk through what it all it's doing so the test that we want to do here is we want to test to make sure that it displays next day reset notifications and just like the last test we want to stub and make sure that we have a reference to the stub notification and we want to add three to-do's this time so all this is doing is it's adding three to do's learn cyprus write tests be happy code you already understand no big deal we want to make one paused and one completed so we're clicking the pause button on one and the complete button on another and we're making sure that there's you know each of them are in their separate list just as we would expect normally now we're saying cy.clock and we're doing this with new date constructor instead of a preset date like last time so what we're doing is we're setting the clock to the time that it is right now so that we have control over the clock but we don't want to change the time right now so now we have control over the clock but it's set to right now then what we want to do is we want to say that the notifications have not been called yet because we would expect that to not have been called then we're going to go forward exactly 24 hours so now we're jumping into the next day and that's what this uh i think it's like 8 million 86 million 400 000 milliseconds is exactly 24 hours so we're saying tick forward 24 hours and then now we would expect notification to have been called okay now the last one we we said have been called with todometer reminder let's go ahead go into the app code and make sure that we say to have been called with and the proper text so let's change this from have been called to have whoops wrong line of code here all right have been called with what was exactly was have been called with we want to make sure that we have this and let's see what text it is that we need to be using here so let's jump into the application code inside of source components and i'm just going to go inside where i would expect this code to be which would be actually inside of hooks probably use reminder notification and it's not so it's going to be possibly use date check yes tedometer reset time so this is the text we would expect to see inside of this particular notification so i'm going to paste that as the second argument here so now we should expect that to run as expected and we're testing it the right way then it's going to res it's going to call that reset function that we clicked manually earlier automatically so we should expect now there to only be two to do's instead of three and the paused to do should now have been moved into the pending list so we should have zero for paused zero for completed and two for pending all right so let's save this and run it and make sure that this works and then have a look at it it works great so just going inside of here i want to make sure that my stub looks the way that i would expect yep body is it it's a new day and then you can kind of hover over it and see the rest of the text if you want but yeah this is expect exactly what i would have expected to happen as you can see right before it does that we have do later and completed on the screen but then when it resets it actually removes all of that so the reset functionality is working as expected as well alright we're almost done here this next test is going to be very short but we just want to make sure that we test the you know every part of the app that's important and the next piece that we're going to test is that it displays the proper date and weekday so let's create a new file inside of integration make that o3 and then we're going to call this date.spec.js and again you know throw in the context and everything the context here is date and the we're only going to have one test inside of here and that's an it block that the the test is gonna be displays the correct date information now fun fact here this date this time stamp right here is april 29 1973 on a sunday which is david bell's birthday who is the inventor of parkour which i just wanted to throw in there so i'm going to create a reference to the clock and i'm going to set the time to april 29 1973 that's what this millisecond value is going to equate to when we pass it into the date constructor and then now we're saying we want the clock to go there then i'm going to reload the browser so saying cy.reload is effectively like clicking refresh in the browser and when we click refresh we would expect the day to have text 29 because it's the 29th the year should be 1973 the month should be april prefixed to just apr or not prefix but abbreviated and then the weekday should be sunday and so when we i'm to go ahead and stop the test runner save this file and then run that test of course actually [Music] this test will not run like this because we haven't visited we need to visit the url so the very first line in here needs to be cy dot visit oops capital cyprus dot n and we want to grab base url so that needs to be the very first thing we run inside of this test so let's run it again it says cy.visit is not a function here let's just do this instead let's just set the clock to the date that you know april 29 1973 and then after we set the clock then let's visit the base url and see if that works and it does so you can see here that it says 29 april 1973 and sunday so that's that let's go ahead and write our very final test so for this test all we want to test is that the width of the progress bar is as expected and if you remember there was two pieces to the progress bar there was both the completed and also the paused we're going to test both of those to make sure that they're the proper width according to the number of stews that are both paused and completed compared to the total number of to-do's so let's create a new file called o4 and underscore that with progress.spec.gs and i'm going to paste in my test code here and walk you through it so the context is progress and we only have one test inside of here and it displays the proper width that's what we want we want it to display the proper width so we're going to visit the base url make sure we're on the right page basically we're going to say cy.getbyte to do which gets all of the elements on the screen that have the test id to do so in this case it would end up being an array and we're going to say it should have length 0. so there should be no to-do's on the screen whatsoever initially let's add four to-do's it's gonna be complete tutorial learn cypress edit video and upload video those are my four to-do's that i've written here and we're going to complete two to-do's so we're gonna click the complete button on two of these to-do's and then the pause button on one of these to do's and again if you just if you think about this i can explain this really quick dot eq is saying you want to click which particular one and it's just like an array where you access the first item as zero and when we do that when we click the zeroth complete button that gets moved to the bottom because now it's completed and so now when we're clicking the zeroth complete button again we're actually clicking the one that was below the first one because if you click on that complete button it moves to the bottom now we're clicking on the first one again which is actually a different one and then again if we do one we're actually clicking the second one and since there's four that ends up being the last one in the pending list okay so think about that as you're writing this and just kind of imagine it in your head as you're typing it out to try to figure out what it would look like before you run it so after we click all of that stuff we want to make sure that the progress bar has the proper width so before we even look at the bottom code here let's think about this let's talk about it we have two that are completed one that's paused and out of all of the to do's we have a total of four so that means each to do represents 25 of the width of the progress okay so if we've completed two then we would expect the green to be fifty percent of the width of the entire progress bar because half of a hundred percent is fifty percent and half of four is two so that's why then we have one in the pause list and one fourth is 25 so we would expect the yellow portion to be 25 of the entire width of the progress bar but here's the catch to that the way that the progress is built in css is it's actually stacked and layered so let's quickly pull open the application so i can give you an explanation as i do this so i'm going to add a third to do so i'm going to complete actually i'll add four so we can have exactly what we're going to be testing here so let's complete two of them and pause one now you can see that the yellow portion here is exactly one quarter of the entire bar however if we just inspect this element and look at what's really going on underneath the hood we can see that the yellow portion is actually 75 of the width it's just layered so the completed bar is on top of it so it's kind of like an illusion that's how it's being created in reality if we go back to this test we would really expect this to be that portion of the progress bar to be 75 percent of the width and i hope that makes sense you can play with it yourself and figure out exactly what it is i'm talking about but we're going to move forward show you exactly what the assertion is going to look like so i wrote some comments here that says the width of the container we don't want to hard code the pixel value it's actually 550 pixels but we don't want to hard code that because if some developer if some engineer changes that width we don't want to have to go back and update our test we want it to just work automatically so instead of hard picking that hard coding that pixel value we're going to grab and invoke the width on the progress container and then we're going to take that width oh look i just got a to-do reminder that's pretty funny you probably didn't see it the video was in the way but i just got a reminder so we're going to take the width that we get from this invoke command and we're going to perform some math on it so let's start with the progress complete progress if you remember that should be 50 percent of the total width so let's see what that looks like we're saying that the complete progress should have css width so we're accessing width property of the css and we're saying it should be equal to width times 0.5 so width being the full width of the progress bar 0.5 when we multiply it by that cuts it into one half so we're saying that it should be 50 of the whip and we're using string interpolation to calculate that value into an actual number and then put pixels at the end so out of 550 pixels 275 would be 50 percent of 550 so this would actually evaluate out to 275 pixels and you'll see that in just a moment now again the pause progress is going to be 75 of the width so we're going to say it should have css and we're going to access the width property of that css and say that it should be equal to width times 0.75 pixels and that's that's it so i'm going to save it and open it up oh we got to open up the dashboard and run the test really quick see if it works and it works great so let's have a look here on the on the right i'm sorry the left side you can see that it says expects 275 pixels to equal 275 pixels so that's what i was saying 50 percent of 550 is 275 and then you can see the second one here 412.5 is 75 percent of 550 so it evaluates out just like we would expect it to which is awesome so now i'm going to just click run for integration specs i'm going to click on this and let it all run just to make sure all the tests pass before we you know conclude it's pretty it's pretty satisfying to watch this go through on its own awesome so now we have all of these tests passing we have completely tested this app using all of the test scenarios that we talked about in the beginning of the video and it was super easy to do it using cyprus and actually pretty fun at least i would think so let me know in the comments if you think it was fun otherwise you know either way give this video a thumb up okay so that was cypress and i really hope you enjoyed this video if you did please don't forget to give me a thumbs up it really helps me out subscribe if you haven't already and i'll see you guys in the next tutorial [Music] you
Info
Channel: PortEXE
Views: 5,519
Rating: undefined out of 5
Keywords: testing react apps, cypress.io, cypress, cypress tutorial, cypress react, e2e tests, e2e, e2e testing, testing tutorial, writing tests for react, beginner cypress tutorial, web development
Id: uNd9HxIHptY
Channel Id: undefined
Length: 46min 5sec (2765 seconds)
Published: Sat Nov 28 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.