﻿1
00:00:04,607 --> 00:00:05,667
Throughout this course,

2
00:00:05,692 --> 00:00:09,733
we have emphasized the importance
of writing tests for functionality

3
00:00:09,758 --> 00:00:12,900
instead of looks
and other stylistic choices.

4
00:00:13,567 --> 00:00:18,300
However, there are scenarios
in which it is important to ensure

5
00:00:18,325 --> 00:00:21,900
the application visuals
aren't being changed too much.

6
00:00:22,300 --> 00:00:27,233
One way for us to achieve this protection
is by writing visual regression tests.

7
00:00:27,673 --> 00:00:29,867
For the sake of simplifying this lesson,

8
00:00:29,933 --> 00:00:33,000
I have already pre-configured
our Wordle project

9
00:00:33,067 --> 00:00:36,533
to support end-to-end tests via Cypress.

10
00:00:36,933 --> 00:00:41,333
You can pull this project at this point
by using the link in the description.

11
00:00:41,700 --> 00:00:46,667
But let me give you a quick rundown
on how I've set up Cypress in it.

12
00:00:47,300 --> 00:00:50,767
I started by installing Cypress
as a dev dependency.

13
00:00:51,733 --> 00:00:55,267
And then I created a script
called test-e2e,

14
00:00:55,367 --> 00:00:57,467
which runs cypress open.

15
00:00:57,986 --> 00:01:00,786
Since our project didn't have Cypress yet,

16
00:01:00,811 --> 00:01:06,000
Cypress has provided us with a quick
wizard to pre-configure an example test.

17
00:01:06,500 --> 00:01:08,443
I went with component tests

18
00:01:08,467 --> 00:01:11,323
because I wanted to write
a quick visual regression test

19
00:01:11,333 --> 00:01:12,967
for our WordleBoard.

20
00:01:13,633 --> 00:01:18,300
Since our project is using TypeScript,
I also wanted to provide support for it.

21
00:01:18,633 --> 00:01:23,200
This could be achieved
by placing a tsconfig.json file

22
00:01:23,233 --> 00:01:24,900
in our Cypress folder.

23
00:01:25,967 --> 00:01:30,067
Notice the type of Cypress
in our compiler options.

24
00:01:35,050 --> 00:01:38,133
I then updated the placeholder tests

25
00:01:38,158 --> 00:01:41,917
that Cypress has provided
with an end-to-end test

26
00:01:41,933 --> 00:01:45,467
that ensures
the display message is displayed

27
00:01:45,492 --> 00:01:47,967
when the user makes a correct guess.

28
00:01:50,397 --> 00:01:53,833
If you see this,
this is the test that we have right now.

29
00:01:54,133 --> 00:01:56,675
We have a user typing
all the different guesses,

30
00:01:56,700 --> 00:01:58,250
and then Cypress is ensuring

31
00:01:58,275 --> 00:02:01,467
that the message congratulations
is rendered to the screen.

32
00:02:02,733 --> 00:02:04,667
Okay, so now we are at a point

33
00:02:04,692 --> 00:02:08,600
where we can run
a regular Cypress component test.

34
00:02:08,833 --> 00:02:12,900
Now let's turn this test
into a visual regression test.

35
00:02:13,533 --> 00:02:15,400
One way for us to achieve this

36
00:02:15,400 --> 00:02:20,100
is by installing
the Cypress Image Snapshot plugin.

37
00:02:20,567 --> 00:02:23,700
The link for this package
is also in the description.

38
00:02:24,900 --> 00:02:26,133
To install the package,

39
00:02:26,158 --> 00:02:30,700
we can do pnpm i -D
to install it as a dev dependency,

40
00:02:30,860 --> 00:02:32,900
and then the package itself,

41
00:02:33,033 --> 00:02:37,000
which is
simonsmith/cypress-image-snapshot

42
00:02:40,507 --> 00:02:46,933
Okay, now we need to add
this plugin to our cypress-config.ts.

43
00:02:48,963 --> 00:02:50,230
And you can see over here

44
00:02:50,255 --> 00:02:52,963
that these are the configurations
for the component tests,

45
00:02:52,967 --> 00:02:54,400
which is all we have.

46
00:02:54,553 --> 00:02:56,100
And to plug that plugin,

47
00:02:56,125 --> 00:02:59,567
we can just use
the setupNodeEvents callback,

48
00:03:00,233 --> 00:03:04,733
and call the add
imageMatchImageSnapshotPlugin function.

49
00:03:05,567 --> 00:03:10,033
This plugin function
takes the on object as a parameter.

50
00:03:11,367 --> 00:03:13,833
Do note that everything
that I'm doing here

51
00:03:13,858 --> 00:03:16,933
is described
in the documentation of the package.

52
00:03:17,546 --> 00:03:19,667
The link is also included
in the description.

53
00:03:21,200 --> 00:03:23,533
We also need to register the commands.

54
00:03:23,558 --> 00:03:29,763
To do this, we can go to supp/component
inside of the cypress folder.

55
00:03:31,383 --> 00:03:35,450
And here we can load
the image-snapshot commands

56
00:03:35,467 --> 00:03:39,867
by calling the method
addMatchImageSnapshot command.

57
00:03:41,197 --> 00:03:42,633
It's just a function call,

58
00:03:42,667 --> 00:03:46,233
and as long as we're invoking
this function in our support file,

59
00:03:46,366 --> 00:03:47,577
we should be good.

60
00:03:48,367 --> 00:03:51,140
Now we can go to our example test

61
00:03:53,947 --> 00:03:55,600
and change our assertion

62
00:03:55,633 --> 00:03:58,967
to instead of being
contains the victory message,

63
00:03:58,992 --> 00:04:03,433
we can change it
to be match-image-snapshot.

64
00:04:06,957 --> 00:04:11,067
Now let me explain
snapshot tests for a second.

65
00:04:11,667 --> 00:04:15,616
They work by comparing
the current output of the application

66
00:04:15,641 --> 00:04:18,167
with a given source of truth.

67
00:04:18,800 --> 00:04:24,033
This source of truth is created
the very first time you run the tests

68
00:04:24,067 --> 00:04:26,700
without having a source of truth defined.

69
00:04:27,200 --> 00:04:31,833
What I mean by this is that
the very first time we run this test,

70
00:04:31,933 --> 00:04:34,833
we're still technically writing the test,

71
00:04:34,967 --> 00:04:42,067
because this first execution will be used
to save the output as the source of truth.

72
00:04:43,113 --> 00:04:47,200
So as you can see over here,
the test already automatically ran

73
00:04:47,233 --> 00:04:50,833
because Cypress is running in watch mode,
but the first time it ran,

74
00:04:50,867 --> 00:04:53,667
it was just saving the snapshot.

75
00:04:55,026 --> 00:04:59,677
And I can see the snapshot file in here.

76
00:05:00,700 --> 00:05:03,333
So you can see that Cypress
has created a new file

77
00:05:03,733 --> 00:05:07,765
called Displays the victory message
if the player provides guess

78
00:05:08,180 --> 00:05:09,900
with the word of the day.

79
00:05:10,233 --> 00:05:15,967
This is exactly the name of the test,
and it's just a photo of our application.

80
00:05:18,603 --> 00:05:21,250
I can run this test again
as many times as I want,

81
00:05:21,267 --> 00:05:26,310
and it will still continue to pass as long
as I don't provide any drastic changes.

82
00:05:26,747 --> 00:05:29,300
Okay, so let's commit this.

83
00:05:32,870 --> 00:05:35,800
We can say that a good
commit message in this case is,

84
00:05:35,825 --> 00:05:42,767
Setup Visual Regression testing
for WordleBoard.

85
00:05:46,257 --> 00:05:51,533
Also do notice that we are committing
the snapshot itself.

86
00:05:52,957 --> 00:05:58,033
This is very important because
the snapshot is part of the test itself,

87
00:05:58,133 --> 00:06:01,267
so always make sure
that you're including the snapshot file

88
00:06:01,292 --> 00:06:02,417
n your commit.

89
00:06:04,557 --> 00:06:07,033
What if we change what the user is typing?

90
00:06:07,187 --> 00:06:10,150
What if instead of typing
the word of the day,

91
00:06:10,175 --> 00:06:14,200
which is tests, we type happy instead?

92
00:06:14,840 --> 00:06:16,077
Let's take a look.

93
00:06:17,717 --> 00:06:19,967
We can see that our test has failed.

94
00:06:19,992 --> 00:06:21,633
I can even try running this again,

95
00:06:22,400 --> 00:06:25,933
and look at this,
Cypress is failing our tests.

96
00:06:27,180 --> 00:06:30,467
If we want to see the difference
between the expected result

97
00:06:30,492 --> 00:06:35,233
and the received result,
we can look into the diff-output file.

98
00:06:35,967 --> 00:06:38,933
This is located
inside of your snapshots folder.

99
00:06:39,153 --> 00:06:41,467
Under the test-switch folder name,

100
00:06:41,539 --> 00:06:44,363
you're going to find
a folder called diff-output.

101
00:06:44,388 --> 00:06:48,300
If we expand this, we can see
that there is a new file image in here.

102
00:06:48,700 --> 00:06:51,367
If I click on it, this is what I see.

103
00:06:51,900 --> 00:06:55,500
The left-hand side shows the expectation.

104
00:06:55,833 --> 00:06:59,767
The right-hand side shows
what was the current input,

105
00:06:59,767 --> 00:07:04,133
and in the middle, we can see
a diff between both outputs.

106
00:07:05,667 --> 00:07:11,167
Notice that our test has identified
a drastic change in the third row,

107
00:07:11,192 --> 00:07:13,367
which is true
because instead of typing tests,

108
00:07:13,392 --> 00:07:15,830
we're typing happy, and it also noticed

109
00:07:15,833 --> 00:07:20,100
that the victory message
is completely missing in the new result.

110
00:07:20,633 --> 00:07:22,367
This is pretty nice, right?

111
00:07:22,525 --> 00:07:24,220
Another thing that I want to point out

112
00:07:24,233 --> 00:07:26,767
is that if we try
to make a commit right now,

113
00:07:26,900 --> 00:07:31,133
you can see that the diff-output folder
is being tracked.

114
00:07:31,733 --> 00:07:34,400
We shouldn't be committing
these diff files at all

115
00:07:34,425 --> 00:07:38,033
because they are just failed test results.

116
00:07:38,166 --> 00:07:40,833
So we should add this to the git ignore.

117
00:07:41,237 --> 00:07:42,770
So first, I'm going to, of course,

118
00:07:42,795 --> 00:07:45,367
revert to this change over here
that broke our test.

119
00:07:45,767 --> 00:07:49,367
But I also want to add this
to our git ignore.

120
00:07:53,523 --> 00:07:55,910
So you can see over here
that what phpStorm has done

121
00:07:55,933 --> 00:07:58,700
is just added
this extra line to my git ignore.

122
00:07:58,833 --> 00:08:00,530
but this is being too specific.

123
00:08:00,555 --> 00:08:02,400
I don't want to ignore just this file.

124
00:08:02,533 --> 00:08:06,600
I want to ignore everything
that is inside of the diff-output folder.

125
00:08:06,900 --> 00:08:13,300
So I'm just going to change this
to say anything under the Cypress folder,

126
00:08:13,467 --> 00:08:18,000
as long as it's inside of the diff output,
should be ignored.

127
00:08:18,333 --> 00:08:19,790
If I try to commit again,

128
00:08:19,800 --> 00:08:23,800
you can see that the only file
being modified is the gitignore file.

129
00:08:25,100 --> 00:08:31,200
That's perfect. So let's save this
as ignore snapshot test diff files.

130
00:08:31,693 --> 00:08:33,137
Before we close this lesson,

131
00:08:33,162 --> 00:08:38,133
I do want to point out that I have
changed the test itself to make it fail.

132
00:08:38,507 --> 00:08:43,600
A real-world example would involve
some change in the component itself

133
00:08:43,667 --> 00:08:46,867
that would cause
the drastic visual regression.

134
00:08:47,067 --> 00:08:51,000
So let me demonstrate
a more realistic case.

135
00:08:51,333 --> 00:08:56,633
If we go to the WordleBoard
and we try to change the CSS for main,

136
00:08:57,867 --> 00:08:59,796
let's just say
that I'm going to change this

137
00:08:59,821 --> 00:09:03,100
to just rotate around the z-axis.

138
00:09:03,167 --> 00:09:09,167
So I can say transform, rotateZ,
and let's just rotate it 92 degrees.

139
00:09:09,533 --> 00:09:15,300
Now that I save this,
we can see that our tests are failing.

140
00:09:15,599 --> 00:09:17,940
Beautiful. And of course,

141
00:09:17,965 --> 00:09:20,233
I should be able
to see the diff file again.

142
00:09:21,566 --> 00:09:24,467
And you can see
that it's drastically different

143
00:09:24,492 --> 00:09:26,467
than what we expected.

144
00:09:27,366 --> 00:09:29,900
Awesome. Today we have covered

145
00:09:29,925 --> 00:09:34,633
how to quickly write visual
regression tests for our Vue components.


