Installing Cypress and Server0:55
And let's go ahead and npm install it. So this may take a while because Cypress is an Electron app and we all know Electron apps are quite large. So grab a drink and hopefully it's done by the time you're back. Okay, that's done. And it didn't take too long this time because as you can see, it's pulling from a cache. But the first time I installed it, it took at least three or four minutes. Okay, so the next step is to make sure your dev server is running. So I'm going to do gridsum develop. And you can see that we're running on localhost port 8080.
Creating First Cypress Test2:25
So I'm going to make a new file here within the integration folder. And we'll just work with this. So say example.spec.js. And the Electron app should have detected that. And now you see this example.spec.js. And now we can start writing our tests. So we can say describe. And this allows you to group your tests, say my first group of tests. And then the second parameter is a callback. And here's where you can group your tests.
And then the second parameter is a callback. And here's where you can group your tests. So let's start with the most basic test, let's say it works. And then again, the second parameter is the actual test. And it should say expect(true).toEqual(true), just to see our test passing. So now when I save this, I didn't run the test yet. So let's go ahead and click on example.spec. And Chrome will open. And now you see our tests are loading. And there is our first test.
OK. So let's run this test and see if this works. There we go. And just to make sure that it fails when it doesn't find the text, so let me add some gibberish here and see that again. And as you can see, it waits some time to see if there's an AJAX request being made. But if it can't find it, then it will fail. Cool. So let's set our base URL instead of hard-coding that localhost:8080.
Configuring Base URL5:12
Cool. So let's set our base URL instead of hard-coding that localhost:8080. So let's grab this. And within cypress.json, I believe, where is it? So I think it's in the root. So yeah, there it is. We can add our base URL here. So we can say baseUrl. And we can just give it that. Actually, this is JSON, so we need to do this.
Testing Blog Navigation6:02
And that's still failing because I didn't change it. So let's change it back. And let's make sure this works. Cool. So what else can we test here? Let's test that our blog works. So we want to be able to visit /blog and see our blog posts. And these posts correspond to files on our file system. So just markdown files. Go into blog.
So just markdown files. Go into blog. And you see other markdown files here for posts. And there are ways to treat this test like a traditional test. So before the test, you want to make a new file, a new markdown file like this, assert against that data, and then delete that file after the test. But for this case, we just want to do some end-to-end testing and just sort of mimic what the user will see. So for this case, we just want to make sure that we can see blog posts as we visit this page.
So for this case, we just want to make sure that we can see blog posts as we visit this page. So let's go ahead and do that. So let's duplicate this. And let's just say it visits the blog page. And we want to visit blog. And we just want to make sure it contains a post. So let's say introduction to Gridsome. And let's run this test. And both tests are passed.
And let's run this test. And both tests are passed. Cool. Now, that test just tested if we visited the page. So that would be the equivalent to just typing in here. But we can also write a test if we want to click this specifically. So let's do that. Let's say it can click the blog. So from the home page, we want to click this button here, or this link. So how do we grab that link?
So from the home page, we want to click this button here, or this link. So how do we grab that link? So there are a few ways to do this. So the contains method actually grabs the DOM element that it finds it in. So if I do this, so if I'm looking for the text blog, which isn't very robust, but it should work in this case, then it's going to return that DOM element. And then we can click that DOM element. And then we can grab this for the assertion. And we can also assert that the URL should include /blog. And let's see if this works.
And you can see it's currently in the mobile version. And we want this to be a desktop version. So we can actually switch the viewport width. So let's do that. So for our second parameter in our describe method, we can set the viewport width. So let's do this and close that out and put a comma. And now we can set viewport width. And let's set that to 1280. And we can set the height as well. But I'll just stick to whatever default is.
We can do the same for clicking the actual blog post. But that's pretty much the same as this. So I'll skip that. So now if you saw our test ran in seven seconds. And if you keep adding tests, this can take quite long. So what you can do is use the --only method. And it will only run that test. And this works for the it methods for individual tests. Or for the describe method for groups of tests. So now this should run only that single test that we just did.
Or for the describe method for groups of tests. So now this should run only that single test that we just did. Or if we grab this whole thing and make a new describe block, we can do another group of tests, but only run this group. So I'll do this. Let's say describe my second group of tests. And let me remove this. And let's say only here. And this should only run this group. Cool.
Testing Pagination with Selectors12:11
And this should only run this group. Cool. So now we'll continue working with this group. Let's work on the next page. Or the next test, I mean. Let's work on checking if pagination works. So to do that, as a User, I would just go to blog. And I would click on next. And I would just see if the other blog Post shows. So pagination is just set to three here.
And I would just see if the other blog post show. So pagination is just set to three here. Just as a demo to see it working. So let's do this. So let's say it can do pagination on the blog page. So let's visit that blog page. And we want to click the next button here. So this button right here. So again, we can do that trick and use containsNext. And then click it.
So again, we can do that trick and use contains next. And then click it. But like I said earlier, this isn't too robust. And if this text appears somewhere else, it's not going to work. So a good approach would be probably to add some sort of selector on this element. So you can use anything you want. You can use an ID. But I like using custom attributes. So let's go into that next button. So I believe it's in a component called PaginationPosts.
So let's go into that next button. So I believe it's in a component called PaginationPosts. And it's right here. So let's set a attribute here. Let's call it data-cypress. And let's say next. And I believe I have it within the class. So let me just move it out right here. And now we can comment this out. And we can use the get command or get method.
And now we can comment this out. And we can use the get command or get method. And this takes a selector. So the selector is going to be square brackets. data-cypress equals next. Did I name it lowercase or uppercase? I'm going to stick to lowercase here. Okay. And this will return that DOM element. And we can click it.
And this will return that DOM element. And we can click it. And now we can do the same thing we did above for checking the URL. So let me grab that. And we paste that in. And the URL should be blog/2. And we can also assert that we see a blog post that belongs to the second page. So let's just assert we see this. So we can do cy.contains.
So let's just assert we see this. So we can do cy.contains. And paste that in. Okay. Let's run this test. And it didn't find that element. That's because I did not save it. So let's save that. And let's run our tests again. So to run it again, just go back to your test and just save it again. That should rerun it.
scrolls to that section. So how do we test that? So let's make a new test. So let's just duplicate this. And let's say canScrollTo. So I'll just test projects for this test. And you can do the rest for, or I'll do the rest for the other tests in the final version. So let's visit to the home page. And let's click that button. And again, I'm just going to use this naive way. But in the final version, I'll probably add data
that button. And again, I'm just going to use this naive way. But in the final version, I'll probably add data cypress attributes. So let's say projects. And let's click it. And let's just run this and see if it actually works in the test here. So keep an eye on the browser. And you see it does scroll to that section. So I already have an ID on this section because that's how scrolling works. So to show you that, I believe it's in the default layout. And let's
you that, I believe it's in the default layout. And let's see, ID equals. Sorry, it's in the index.view. So ID equals project. So there it is. So we just want to assert that this section is visible in the current viewport. So let's try that. So let's pretend like we don't click on the button just to see it fail. And then we want to
Testing Theme Switcher18:07
theme. Okay. We'll visit the homepage. And we have to give the button a selector here. So we'll give it a selector called data-cypress equals switchTheme. And we want to check that class. So that class is called contentWrapper. And I believe that's unique. So we can just use that. So say contentWrapper. And to check the existence of classes,
So say content wrapper. And to check the existence of classes, we can do shouldHaveClass. And in this case, we want to do a theme-dark. And that should check that class. Okay. So let's add this attribute before I save this. And I believe it's in a component named ThemeSwitcher. Okay. So let's put it in here.
I believe it's in a component named ThemeSwitcher. Okay. So let's put it in here. Should be a button, but I guess I made it a link. So I'm going to put data-cypress equals switch-theme. I'm going to save that. Go back here. Let's run our test. And let's see if this works. And I have an error. I think yeah, this should be get. Sorry. Let's try it again.
Testing Search Results20:37
tests are getting long. So I'm going to only run this one. And let's say we can search for BlogPost instances. And we want to get the search. So I'll add a selector on that. And we want to type in it. So we want to type, let's just say introduction. Okay. And let's comment this out or delete these two. And let's add this data-cypress equals search to the search.
delete these two. And let's add this data-cypress equals search to the search box here. And I'm not sure where this is. Is it in default? Oh, no. I think I have a component for it called SearchInput. And there should be an input here. And there it is. So let's add data-cypress equals search. Let's save this. And what do we want to assert? So if I search for something, we just want to assert that there are search results.
So if I search for something, we just want to assert that there are search results. So this is an unordered list. And this corresponds to where is it? There should be an unordered list here. Actually, it's not an unordered list. It's just this right here. So it's just these results right here. So we can put a selector on this as well. So let's say data-search-results and make sure to quote that.
So let's say data searchResults and make sure to quote that. And we can just assert that that's visible. So let's duplicate this searchResults and say shouldBeVisible. And let's try that out. Back to Chrome. And you see a type and it passes.
Testing Mobile Hamburger Menu23:04
So let's start by making a new describe method with that viewport. So let me just grab this. And let's make a new describe block down here. And let's just copy this. And let's say it shows the hamburger menu. And we have to set the viewport to something smaller. So I'll say 400 and also set the height here. So let's
we want to assert that the menu is visible. So let's add another menu here or another element or another selector, I mean, and say shouldBeVisible. So change this should shouldBeVisible. Okay. And let's make this work. Let's get rid of this. So where is this hamburgerMenu? I believe it's in default. So let's look for the button here. I believe it's this right here. So let's say data
show the menu. And now for that menu, like I said, we can add data-cypress equals menu. So let's grab this and let's add it to our menu. And that should be visible. So that's in here. And this is our menu right here. This unordered list. Okay. So data-cypress equals menu. And let's see if this works. So I'm going to say not be visible before we click it. And let's see.
