تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Fix Default App Test0:27

So I have a test here, which is the default test in createReactApp. I just moved it to this test folder, like I showed you in the last video. And it is failing because it's looking for this learnReact text, which is not there anymore because we have our to-do app. So how about we start with something simple? Let's just say it renders the App component. And let's just look for some text here. So how about we just assert that to-do app shows correctly. So let's call this titleElement. We can use screen.getByText to query that.

So let's call this title element. We can use screen.getByText to query that. And we can say to-do app here, to-do app, okay. Let's save that. And we are now passing. So again, just go through the features of the application and write tests as to how the user would test the app manually. So how about for our next test, let's just make sure that it shows the default to-dos. So let's say test shows the default to-dos. And I'm actually going to change this to it because that reads better.

Test Default To-Dos1:25

So let's say test shows the default to-dos. And I'm actually going to change this to it because that reads better. It shows the default to-dos and it renders the App component. So if you take a look at our app, we do have default to-dos here. So all we have to do is ensure that these DOM elements are in the document. So let's go ahead and do that. Let's say toDo1, we can use getByText. And this one is finishedReactSeries. And I'll do the same for toDo2 and toDo3. So I pasted in toDo2 and toDo3.

And I'll do the same for toDoTwo and toDoThree. So I pasted in toDoTwo and toDoThree. Now we can expect them to be in the document. So toDoOne, toDoTwo, and toDoThree, okay. Let's save that. And our tests are passing. If you want, you can even use the beforeEach method that runs before each test. And we can get rid of this renderApp here for each test. So let's get rid of this. Let's put it in a beforeEach method.

Refactor with beforeEach2:28

So let's get rid of this. Let's put it in a beforeEach method. beforeEach. That's a callback. And within that, we'll run this. We can remove it from here as well. Not sure why there's an underline there. Let's see if it works. And it's still passing. It's up to you if you want to do that.

Test Adding To-Dos2:50

And it's still passing. It's up to you if you want to do that. Sometimes you might take different props for each test. But in this case, we're always rendering the default app. So this is fine. Okay, now for our next test, let's test if the app can add to-dos. So let's say it can add to-dos. And if you go back to our actual application, we can add to-dos by submitting this form. And you can do that by hitting Enter after you type in the to-do. Add to-do, hit Enter, that submits the form, and it adds the to-do.

And you can do that by hitting Enter after you type in the to-do. Add to-do, hit Enter, that submits the form, and it adds the to-do. So we have to select this input box here, hit Enter, and then check if a new element is added to the DOM. So let's do that. First we need a selector for this input here. So we can make use of that plugin that I showed you from the first video, Testing Playground. Let's go ahead and select this. And we can use getByRuleTextBox, but I'm going to use the placeholder one down here, because there's also text boxes when we double-click to edit the to-do.

And we can use getByRole, but I'm going to use the placeholder one down here, because there's also text boxes when we double-click to edit the to-do. So if we click on placeholder, it's going to change the selector here and use that one instead. So let's go ahead and copy this. So it's getting the element by the placeholder text. Go back to our code. Let's get rid of this. Let's say const toDoInput equals this. Then after we select that, we want to type into it, so we can make use of userEvent.

Let's say const toDoInput equals this. Then after we select that, we want to type into it, so we can make use of userEvent. I think we have to import that, so I'm just going to paste the import up here. And we want to make use of the type method to simulate typing. So let's type into the toDoInput, and let's type in our new toDo here. So we can say newToDo. And to simulate the enter press, we can wrap the word enter in curly braces. Okay, and now we want to search for this new toDo. So we can use screen.getByText again. So let me just grab one of these.

So we can use screen.getByText again. So let me just grab one of these. Let's paste that in. Let's say const newItem, and that should be new to-do. Okay, and then we can expect that to be in the document. So let's grab this. Let's paste this in. Let's say expect newItem to be in the document. Let's save this, and let's see if it passes, and it does. Next, let's test if there's a line through any completed to-dos.

Test Completion Styling5:20

Let's save this, and let's see if it passes, and it does. Next, let's test if there's a line through any completed to-dos. So by default, goGrocery is completed. So we want to check if there's a line through it. So let's go ahead and do that. So let's go ahead and do that. I'm going to grab this test here. Let's paste it down here. Let's name it. It shows the line through completed to-do.

Let's name it. It shows the line through completed to-do. So I'm going to grab the first two to-dos, toDo1 and toDo2. Don't need toDo3 here. And toDo1 is not complete, but toDo2 is complete. We can make use of the toHaveClass class in JestDOM to check if it has a certain class. And the class responsible for adding this line through is, let me just double check, it's called line-through, okay? So we don't expect toDo1 to have that class. So we can expect toDo1 not toHaveClass line-through, okay?

So we don't expect toDo1 to have that class. So we can expect toDo1 not to have class line-through, okay? And we do expect toDo2 to have that class. So expect toDo2 to have class line-through, okay? Let's save that. And it does pass. Now, if you want, you can also check if the checkbox is checked. So if it's completed, then the checkbox should be checked. So like I said in the last video, this is one of these cases where we can just make use of normal selectors.

So what we can do is just grab the previousElementSibling. So in this case, we have this already. We just have to grab the previousSibling. So in this case, that would be the checkbox. And then we can use the toBeChecked method in just DOM. So let's do that. So toDo1 should not be checked. So let's do that one first. Let me just duplicate this. toDo1, we can say dot previousElementSibling.

Let me just duplicate this. To-do1, we can say previousElementSibling. And we want to make sure it's not checked. Not. We can use toBeChecked. Okay. There's no param here. And ESLint is giving us this error. But it's better to test the case than to not test it at all. Or you can change your markup in the actual component to make it more accessible.

because that's how we defined it to be by default. And now we want to check the checkbox here to complete the to-do. So let's go ahead and do that. So we can say userEvent.click. And we can do the same thing here. So toDo1.previousElementSibling. Or we can store this in a variable, but this is fine. And then after this, it should be checked. And it should have a line through. So we can do the opposite of this.

Let's say it can incomplete a to-do. So let's start with the second one here. So let's change all of these to to-do2. And the text should be go grocery for that one. Okay, so by default, this one is checked. So we have to swap this. So we do expect it to have a class of line-through. We do expect it to be checked initially. And then we're gonna check the box to incomplete it. And now we can set not here.

Test Editing and Deleting10:23

So let's start with this. Let me just grab this one here. We'll be working with the first to-do. Let's paste that in. Let's say it can put a to-do into edit mode. So we'll grab the first one. And then we want to double click it. So let's say user event DBLclick for double click. And the thing we want to double click is to-do1. Okay, and that should put it in edit mode.

And the thing we want to double click is to-do1. Okay, and that should put it in edit mode. So what's going to happen here is this label should no longer be visible after I double click. And the text box should be visible. So let's go ahead and insert that. So this label right here should no longer be visible after we double click. So let's do that. Let's say expect to-do1 not to be in the document. Okay, let's try that first.

Let's say expect toDo1 not to be in the document. Okay, let's try that first. Okay, it's passing. And we also want to assert that we do see this new edit box. So this one here. So unfortunately, I can't use the plugin for the text box. The text box here, because every time I click this, it focuses this off. So we have to do it manually here. So I'm going to say const toDo1EditInput equals screen.

So we have to do it manually here. So I'm going to say const toDo1EditInput equals screen. And I'm going to use the getByDisplayValue method. So it's getting the element by the current value. So the value is finish react series. So let's do that. finish react series. And we can expect this element to be in the document. So let's grab this. expect(toDo1EditInput).toBeInTheDocument().

So let's grab this. Expect to-do1 edit input to be in the document. Okay, save that. Check out our tests. And everything is still passing. Next, I want to test if you can actually commit the edit. So if you go back to our app here, if we double click, update this, hit enter, it should update the to-do. So let's duplicate what we have here and add that functionality. So let's say it can put a to-do into edit mode.

So let's duplicate what we have here and add that functionality. So let's say it can put a to-do into edit mode and commit a change by pressing enter. So after we double click it, we can type into it. So again, we can use userEvent.type toDo1 edit input. So let's add space today and then hit enter here. So after we hit enter, the text box should no longer be visible. So we can grab this and expect it not to be in the document anymore. So we'll say not. Let's save that, see if that passes.

We added the text today here, and then we should expect that to be in the document. So we can grab this, paste this in, toDo1 updated to be in the document. Save that. Everything is passing. Okay, a few more tests here. Let's test if we can actually delete a to-do. So let's duplicate this one, say it can delete a to-do. So we'll work with this first one here. So let's say expect it to be in the document initially. Okay, and after this, we want to hit the delete button.

Or like I said, you can make this more accessible. So we can use an actual selector, but I'm okay with this. So let's say const toDo1DeleteButton equals toDo1. I said the parent element. And then the next element sibling will be the delete button. First, let's make sure that that's correct. So let's expect that to be in the document. toDo1DeleteButton to be in the document. Let's go ahead and click that. Actually, let's make sure this works first.

Let's go ahead and click that. Actually, let's make sure this works first. Okay, let's go ahead and click that button. So userEvent.click toDo1DeleteButton. And then after that, it should no longer be in the document. So let's grab this. Say it should not be in the document. Save that. That should pass. So again, we have it initially.

That should pass. So again, we have it initially. We hit the delete button, and then we assert that it's no longer in the document. Next, let's test the items remaining count. So we have this remaining count for any remaining to-dos. So as we check it, it updates. So let's make sure that works. Duplicate this. Duplicate this. Let's say it shows the number of remaining to-dos.

Duplicate this. Let's say it shows the number of remaining to-dos. So let's grab that element here that says two items remaining to start. So let's say items remaining. Say two items remaining here. That should be in the document. So let's make sure we check that. items remaining. And then let's go ahead and check the first to-do. Let me delete all of this first.

And then let's go ahead and check the first to-do. Let me delete all of this first. Let's make sure this works first. Okay. And we can just grab some code above for checking the first to-do. So it should be up here somewhere. It's all of this right here. So let's grab this. Or you can extract this to a helper method. If you do this several times throughout your tests.

Or you can extract this to a helper method. If you do this several times throughout your tests. But in this case, I'm just going to repeat it here. So this should check the first to-do. Let's check if this works. Okay, still passing. And now it should be one item remaining. So let's do that or check that. So items remaining after should be one. And let's check if that's in the document.

So items remaining after should be one. And let's check if that's in the document. Save that. And we are at green. And for our last test, let's just make sure that this check all button works. So let me just duplicate this one here. Let's say it can check all to-dos. Let's grab that button here. So const checkAllToDosButton. And again, we can make use of this plugin to grab the selector.

So const check all to-dos button. And again, we can make use of this plugin to grab the selector. So for buttons, it's usually getByRole. And you can see that's what it suggests here. So let's grab this. Let's update this. Okay, why is not reformatting my code? Also, I didn't add prettier here. So let me add a .prettierrc file. I have a snippet here.

So let me add a prettier rc file. I have a snippet here. Let's add that. And now if I save this, it should reformat. It does. So let's go ahead and click that button. Let me just remove all this. Let's say user event.click. Check all to-dos button. And then we can check if each to-do has a line through it.

Check all to-dos button. And then we can check if each to-do has a line-through it. So let me just grab all of the to-dos like we did in the first test, or one of the first tests. So this one here. Let's paste that in. And we can expect them to have a class of line-through. So expect toDo1 to have class line-through. And the same for toDo2 and toDo3. So let me just add that.

Testing practical applications

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟