Starting Cypress Iframe Test0:35
So I start with an empty iframe, but then I immediately call this function loadIframe. It tracks down the iframe, and it sets the attribute equal to that URI that loads the iframe. Again, super simple stuff here, and this is what we get. Okay, so let's try to work with it in Cypress. Now, I've set up an iframe spec file to get us started. All right. So yeah, we could say visit the home page and then get the iframe. And if we switch over and run Cypress, sure enough, we tracked it down. But as soon as I try to do anything with it, for example, let's see. That iframe has an ID, or I'm sorry, the button within the iframe has an ID.
Inspecting Yielded jQuery1:34
Now, we're still going to visit the home page. I'm going to get that iframe, but then I want to show you if I log what is yielded from that, what you'll see if we give it a refresh, open up Chrome DevTools, is we should get the jQuery selector. Yeah, so this is, again, if you're familiar with jQuery back in the day, this is just like doing something like this. In fact, it's identical. You can even do stuff like this. Cypress.$ is jQuery proxy. Kind of cool, isn't it? But anyways, if we run it, we are logging the jQuery instance, and we can see the zero property.
Accessing Iframe Document Body2:36
Then Cypress.log, what you got there. All right, let's have another look. So we run it again, and now, sure enough, we do have the iframe document. And if we take a look at the body, here's everything that got loaded in. Okay, great. So now we have the document. Let's get the body and then perform our selector. Okay, so let's see. zero.contentDocument.body. Let's see, did that work?
or just pass it to Cypress.log if we want to inspect it, and we have that instance. Now I could, as you've learned, we could invoke the jQuery text method, and we should be able to see this. Here we go. So find the button, invoke the text method on that element, and, of course, it yields click me. All right, so now step one, but we are interacting with the iframe, which means I can do things like this. Find the iframe, and then with that button,
which means I can do things like this. Find the iframe, and then with that button, or by the way, again, you'll often see people add the $ sign at the beginning. This is an old jQuery convention that just serves as a reminder. You're not dealing with the button element. You're dealing with the jQuery wrapped version of that button, the selector, which again means you have access to things like this or HTML. You get the idea. Anyways, at this point, I could say expect button.text to equal what was it? Click me.
Anyways, at this point, I could say expect button.text to equal what was it? Click me. So let's see if this works. We come on back, and it passes. Great. What else? Well, we found the button, so, of course, I can continue chaining there. So we run it, and, yeah, it works. We clicked on it. All right, good job.
Extracting getIframe Helper4:39
We clicked on it. All right, good job. We're now interacting with our iframe. But let's make this a little bit cleaner and then deal with some edge cases. So we'll start by extracting a simple function here, like getIframe. So we can just grab what we did earlier and return that. All right, so this would allow us to shorten this to getIframe. A little better, and I think it should still work. It does. Actually, on that note, so we don't have to see that alert.
we give it a run. There we go. So there's the log, and we still have the body. However, it's now the body element. It's no longer wrapped in Cypress, so we can't continue chaining. What we can do in those cases, though, is wrap it again. I could say then Cypress.wrap what was yielded, the body. Okay, so now if we do it again, just to make this very clear for you, so we give it a run, one, two, and let's see. Now if I take a look at what was logged, it should be the jQuery instance,
Creating Custom Cypress Command9:07
One, two. It finds it. It continues forward, and the assertion passes. Okay, so now this is working. Let's take this a step further. We have our function here, and that's useful, but I'm probably going to reach for this often. So why don't we make this a custom Cypress command doing cypress.commands.add. We'll call it getIframe, and the logic will be right here. Let's pull that up.
We'll call it getIframe, and the logic will be right here. Let's pull that up. Next, let's put these on their own line, and I'll let you take a look at that. Okay, so now I can say cypress.getIframe, which is what we named it here. All right, so with any luck, we run it again. One, two, and it passes. Okay, so now this shouldn't live here. It can live in your support commands directory.
Okay, so now this shouldn't live here. It can live in your support commands directory. So they give you a bunch of examples here. Let's just get rid of all of that and paste it in, and that's a fine place for it to live. So now if I come back, this is what we're left with, much cleaner, and it should still work. So now that we understand how to work with iframes, let's switch back to that Laracasts registration example that we worked on in the last episode,
Applying to Stripe Registration10:15
let's switch back to that layer cast registration example that we worked on in the last episode, and I told you where it sits. Yeah, innerStripeCard. I left that as a cliffhanger. Let's have a look now. Commands.js, and here it is. Notice it's almost exactly the same thing. The only difference is a couple places where I've set log to false.
The only difference is a couple places where I've set log to false. This is a way to turn off Cypress logging. So for things like this or wrap, you may not want that to be logged. So in those cases, as the second argument to get or it or wrap, you can turn off logging. So that can be useful. But yeah, it's the exact same thing we wrote. Now if we look at innerStripeCard,
But yeah, it's the exact same thing we wrote. Now if we look at innerStripeCard, so this is where we call it here, just have a look. I have some basic options that we merge in. We will assume that we want the stripeCard to be approved. So if it is approved, we use this cardNumber that stripe will recognize and will mark as approved when testing. But if it should be declined,
and will mark as approved when testing. But if it should be declined, then we use a special card number that stripe will decline. So have a look. We grab the iframe. And then if we want to use that selector for further queries, I can use this within method. So now whenever I say cypress.get,
I can use this within method. So now whenever I say cypress.get, that's no longer from the document route. That would be from the iframe that we just fetched. So get the cardNumber, type some numbers. Get the expirationDate, type some numbers. Now the only thing I don't love here, I'll be honest with you, is notice how I keep adding weight there. I don't like doing that.
it's waiting up to four seconds for the body to load in, and then it wraps it so I can continue chaining, and then we perform our queries as usual. Get the cardNumber and fill it out. That's all there is to it.
