- In this section, we're going to take a look
at how to use JSDOM.
JSDOM is a pure-JavaScript library that implements HTML
and the document object model.
Effectively, JSDOM is an emulation library
that mimics a subset of a browser's capabilities.
It behaves like a mock browser
in which we can execute our JavaScript tests.
So, under normal circumstances,
when you're running your JavaScript code,
full steam ahead,
obviously your JavaScript would run inside a browser,
and that's fine,
it can access the document object inside a browser.
But, when you are running JavaScript tests
those tests do not run inside the browser,
so we have to have something else that provides us
a document object that we can test against.
And that's what JSDOM gives us.
JSDOM is effectively a mock browser.
It provides a document object,
and a document object model API,
and our code then executes against JSDOM
instead of executing against an actual browser.
Our code and our tests are exactly the same as before,
except they execute in a different environment.
So, in our tests, we can write code
to load content into the document object model.
Our actual code that we're trying to test
can use the DOM API to access content,
add elements, remove elements,
that kind of thing.
And then in our tests, we can make sure
that the document object model is correct.
Has my code updated the document object model correctly?
Right, so we're gonna see how to do that in this section.
Jest, luckily for us, already includes the JSDOM library.
So there's very little work that you need to do
to use JSDOM in Jest.
There is one slight caveat, and that's this,
by default Jest runs in node JS mode.
So in other words,
it assumes that your JavaScript tests
will be executing effectively on the server.
If you've got Jest code that wants to access a webpage,
then you've gotta tell Jest to run in JSDOM mode instead.
Okay, so by default, Jess runs in server mode
and it doesn't create a document object.
You have to set a flag that tells Jest to run in
JSDOM mode, so that it enables client-side testing,
you can then write tests using the document object.
So the JSDOM intro folder
is where we're going to be looking in this section.
This is what it looks like, lesson 8, JSDOM intro.
If you open that folder in a code editor it looks like this.
I've got two tests, one test that's gonna fail,
and one test that's gonna pass.
Okay? So we'll have a look at the test that fails first
and we'll see why it fails.
And then we'll have a look at the test that passes
afterwards and we'll see why that passes.
So, first of all, this test is going to fail.
This is the first test.
In my test I grab the document object,
and I assume that it exists.
So what could possibly go wrong in that test?
Well the problem is,
that by default, Jest thinks we're running in server mode,
and that on the server you don't need a document object.
So if I ran this test Jest would fail,
because it doesn't have a document object.
The default test environment there's no JS,
server-side, not JSDOM, not browser side.
Therefore, Jest doesn't create a document object.
Therefore, this test is going to fail.
If I run that test, you'll see that it fails.
And the error message, you can see here,
is complaining about the document object.
The document object is not defined.
And the reason for that again, is because Jest thinks
that this test is a server test on the server.
There's no need for a document object model.
So the document object,
Jest didn't create the document object.
So, the fix is actually quite straightforward.
What you do is you embed a block comment,
would you believe,
at the beginning of your file.
Typically, you can do this file by file if you like,
or you can do it kind of globally,
across your whole test suite.
So, we'll see that in a moment.
Just for now,
if you've got one file you can have this comment,
this block comment, Jest environment JSDOM.
I've set in the jest environment document block comment
to be JSDOM.
And that flips the mode,
Jest now thinks that we're running in JSDOM mode.
Oh, you're running your tests in a browser?
So JSDOM,
sorry, Jest will create a document object for us,
as if this document was a real webpage.
This document object is actually provided
by JSDOM virtually in pure JavaScript,
but that doesn't affect our tests.
As far as our tests are concerned,
this behaves like a real webpage that we can execute within.
So, if we're running in JSDOM mode,
then this document object will be created by Jest,
and it's gonna work.
We've set the test environment to JSDOM,
therefore Jest will create a document object,
and that test works successfully.
So if I run that test, you'll find that it works fine.
And you can have a go at running this test as well yourself,
just to prove the point.
Now, if you think about it,
it would be okay to set that flag on each individual file.
In my example here,
I have set the Jest environment to be JSDOM.
You can set that file by file if you like,
but you can imagine that's gonna get quite tiresome,
quite quickly.
So a better approach is to set the flag globally.
You can set in your Jest config JS file,
you can set this.
You can basically set a global flag test environment JSDOM.
Okay? So that means that all tests now
will execute in JSDOM mode,
therefore they'll have a document object.
Now, you might have noticed,
in my code suite,
I do actually have a Jest config JS,
but, I had it commented out.
Okay? So basically when I ran my tests,
this didn't actually apply.
So, what I can do,
is I can uncomment that code.
If I uncomment that code,
and then I ran the first test again,
this first test would now automatically run in JSDOM mode,
because it's a global setting.
So if I ran test one again,
now it would work.
Okay, so that's probably the best thing to do.
Probably in your test suite, you're gonna have, you know,
10, 20, 100
individual test models.
So rather than setting each one individually
to run in JSDOM mode,
it's probably a better idea to set it globally like this.
Okay, and then all tests will automatically
enable you to implement DOM testing.