Lesson code - https://github.com/learnetto/calreact-frontend/tree/m10l4-testing-forms
In this lesson, we'll see how to test our appointment form component.
Let me open AppointmentForm.js.
And let's make a new test file for this component, AppointmentForm.test.js.
Let's copy and paste some imports, and a shallow test from our AppointmentTest file, let's change this to AppointmentForm, and let's remove this.
And import AppointmentForm.
Ok, so the shallow rendering test passes.
Next, let's test our form validations.
We'll simulate a user typing in a title and choosing a date, and test if the button becomes enabled or disabled based on validating.
We don't need the appointment component here, so let's remove that import.
Ok, so let's write our test now.
It toggles form submit button disabled status based on form validity.
What we want to do now is save the form in a const using mount.
*** At 1:35 - should this be transcribed differently? ****
So let's say, const wrapper equals mount router appointment form. And close router.
*** /close At 1:35 ***
So this const wrapper will contain the fully rendered markup for our component here.
So we can see that by using the debug method.
So if we do: console.log(wrapper.debug()) and run the test, you'll see the entire output of the component tree here, starting from browser router.
Ok, so now let's check if the submit button is disabled.
So we'll say, expect(wrapper.find('.submit-button')).
If you look in appointment form, the submit button has this class called submit-button.
*** At 2:18 - should this be transcribed differently? ****
So we'll say wrapper dot find submit button, dot props, dot disabled, dot toEqual true.
*** /close At 2:18 ***
And that test passes.
Next, let's simulate some user input.
Say, typing in the title field, clicking on the next month button, and choosing a date.
We're using the next month button because it's a simple way to make sure it's a date in the future.
The React datetime component probably has another way to choose a date in relation to the current date, but I couldn't find it easily.
So, this will do for our test.
Ok, let's first do the title.
*** At 2:48 - should this be transcribed differently? ****
Wrapper dot find, let's find it by the name attribute.
So we'll say name equals title, and then we'll simulate typing in a title by using a dot simulate method.
Dot simulate, change, value, a valid title.
We also need to add a name here again, name, title.
And reason is, if we don't do this, then the name attribute gets reset.
I don't know if this is a bug or intended behavior, but if we don't do this, the test fails. So let's add that.
Let's check for simulated change work, by console logging the html before and after.
Actually, this needs to be nested inside target, so this needs to be: simulate change, target colon value, a valid title, and name, title.
*** /close At 2:48 ***
Ok, now let's see the output.
You can see the value has changed, from a blank string to a valid title.
Now let's select the appointment time.
We'll first simulate clicking this arrow, and if we look at the markup, we can see that it has a class rdtNext.
And dates have a class called rdtDay.
So let's use them.
We'll say wrapper.find, rdtNext, span, dot simulate, click.
Sorry, this should be dot rdtNext, because it's a class, and we should add dot at zero.
That means we're choosing the first element that matches our selector.
Then we'll say, wrapper dot find, dot rdtDay, dot at, let's say ten, so it's choosing a date in the middle, dot simulate click.
Now we should have a valid title and appointment time.
So we'll assert that the submit button is now enabled.
Repeat this expect statement, and change this to false.
Expect wrapper dot find submit button, where props are disabled, dot toEqual false.
And our test passes.
Just to make sure, if I make this true, the test should fail.
And if I change it back to flase, it passes again.
Cool, so that's a simple test for a form validation.