From the course: Advanced Cypress

How to handle non-Cypress async promises - Cypress Tutorial

From the course: Advanced Cypress

How to handle non-Cypress async promises

Welcome back to video Number 5. In this video, we're going to build upon what we learned in the last video about the synchronous and asynchronous features of Cypress, and explicitly look at how to handle non-Cypress async promises. So if you remember, any Cypress command with the cy.syntax, anything that's built into Cypress is going to queue up and then run in order. But if we're using some sort of non-Cypress command, in the last video we looked at console logs, but maybe you're looking at, like, a network request or want to do something with some data that's coming in, if it's not a Cypress command, it's going to run first before any of the Cypress commands. So the learning goal in this video is pretty simple. We're going to look at when to use the .then method in Cypress, which is built into Cypress to explicitly handle non-Cypress promises. So let's go ahead and dive in. Okay. So quick refresher. On our last video, we saw that any of these cy commands are going to run in order. They'll run sequentially, but then this console log, since it's not a Cypress specific command, it's going to skip the line and run first. And so one thing that we can do is if you're trying to run a console log sequentially, you can use this cy.log. And that will actually print to the little Cypress command runner window -- or excuse me -- test runner window, and so you'll be able to see this print in order. And it's helpful for when you're console logging, you want things to run in order, but this can only be used for console logging. But let's take a quick look at this. So we -- if we save this and then we switch over, again, making sure that I've got two terminals running; one with the npm start command on whichever operating system that you're on. So I'm using Windows, I've got that npm run start windows command going. And then in the second terminal, I've got the cy:open command running which pops this open. So if I open up the test and I inspect the console, we can see "test is finished" is already printed here. We wait the 5000 seconds, and now we have the cy.log, Cypress log used. So that's helpful. But, again, can only be used for logging information. There's not really like you can't go ahead and then, like, grab that information and then store it in a variable or, like, take a subsequent action after you have that information you're just using it for logging. So Cypress does allow you to use the .then syntax, which will allow you to run a Cypress command. And then when that command successfully executes, it can run another command, even if it's not a Cypress command. So let's take a look at what this looks like. So if we pop back over here, what we can do instead of this console log in this, we can get rid of this cy.log. And then I'm actually going to cut this console log, actually, I'm going to cut the whole eslint-disable piece, as well. So we're going to visit, we're going to findByPlaceholderText, and type. And then we're going to wait the 5000 milliseconds like we did before. This time instead of putting the console log afterwards because we've seen that putting the console log afterwards does nothing aside from hit that console log immediately, what we can do is use .then. And this is just like if you've used .then in any other project, it'll operate similarly where you have the callback function. And then inside of it, we can run whatever command we want. So in this case, it's a console log. Maybe you're fetching some data after this. So maybe you make like an Axios request or a fetch request. So we'll visit, we'll findByPlaceholderText, we'll wait, and then we should see the test is finished at the end rather than immediately hitting. So let's take a look. I'm going to stop this. Run it. Open up my console. And so notice now, test is finished hits at the end. So running it one more time, we can see that the visit command is hit. There's nothing in the console, yet. We're waiting 5000 milliseconds, and now the test is finished. So, again, kind of a smaller-scale use case here with console logging. But if we take a look at the test, what we could do inside of here is you could do, you know, like I said, like a fetch request. And then if you had yourapi.com or whatever, you know, whatever you had inside of here, you could then do something with that data. Say you had, like, a variable up top that you wanted to store some information in and use that further down in your test, or you wanted to make sure that a certain element on your page loaded first and we checked for that element and then making a network request. So it's a really powerful tool to be able to use this .then that allows you to use non-Cypress commands in the synchronous Cypress fashion, similar to how it queues up these commands. So this is, kind of, a way of like almost like hijacking the Cypress commands to use for non-Cypress commands. And in this case, we looked at console logging. But, again, the .then can be used for any sort of non-Cypress asynchronous promise commands that you're looking to run in your test. So I went ahead and grabbed an actual API, the SpaceX API endpoint. And let's take a look at what this might look like in a more sophisticated example. So we can drop this down to, like, two seconds just for this case. And beneath a console log, we can do -- we're just going to use the fetch API. And so I have this api.spacexdata.com/v3/missions. And then we can use our .then inside of here since this is a promise. So we'll get our response and then we'll response.json it. And then after that, we'll grab the data and we'll -- I'm going to grab this eslint-disable bit and then console.log the data. And let's see. About formatting. There we go. Okay. And then this looks like it needs some extra space. No console with any -- cool. All right. So we're just using a basic fetch here to request some data, and then we're going to just -- we're going to console.log that data. But this is to show you, kind of, inside of this .then. Now inside of here -- we can get rid of this test is finished one. Now inside of here, we're using a non-Cypress asynchronous promise where we're fetching some data. And so we can -- we don't see any cy inside of here, we're just console-logging some data down here after we've fetched it, convert it to JSON and -- convert it from JSON and then console.log that data. So let's take a look at what this looks like. So I'm going to restart the test. Console was cleared, we're waiting 2000 seconds. And now inside of our console, we have our spacexdata. So the cool thing about that is then if I wanted to grab like, again, the first item in that array, I could check the mission name and make sure that it's fetching correctly, or I could check that it -- that the array here has a given length. Maybe I'm expecting 10, maybe I'm expecting that it should have some length greater than zero. So really cool opportunity to kind of, again, hijack that series of Cypress synchronous commands by using the .then. This .then unlocks the ability to then continue using promises. Because if we put this fetch on the outside, like we saw in the last video, that would just run first. There might be some other commands that we need to run first, so we might need to visit a certain page, we might need to type something, we might need to click on a button, and we want all those things to run first before we then, you know, make our fetch here, make our get request, whatever it may be. So recapping, we saw in the previous video that Cypress is going to run in order, but any non-Cypress commands are going to run first. So in this video, we're taking advantage of .then off of Cypress commands. So remember that there does need to be a Cypress command initially. But if we add .then, we can then utilize non-Cypress commands like fetching data to then run sequentially as we'd expect. So in the next video, we're going to build upon this idea by building out some more assertions. So we'll actually be able to test that an array should have a certain length, that a text should have a certain value, that a button should exist or should not exist, things like that, that'll actually get a little bit more in-depth into writing some more tests. So thanks again as always for watching. As always, check out our blog and community pages for more information, cool testing tricks, ways to use LambdaTest and incorporate it into your workflow and just learn more. So thanks again and I will see you next time.

Contents