- When you configure your Jest test environment to use JSDOM
as we've seen, Jest creates a document object
as if your test was actually running in a browser.
You can then use the regular DOM API
to access the document object.
As far as your test is concerned,
the code is running in a browser.
It really isn't, it's running in the JSDOM
emulation of the browser
but that doesn't affect your code in any way.
You just use the regular DOM API
as if it was a regular web application.
So we're gonna start looking in this section
at how to access the DOM content
and to test that our code updates it correctly.
So it's in this folder, JSDOM_AccessingContent.
Okay, so that's where you want to go.
And if you open that folder
in a code editor, it looks like this.
I have a couple of tests,
a simple test just to get us started,
trying to figure out how to navigate the content
of the document, the header and the body.
And then example two is a bit more ambitious.
We're gonna start actually adding content
to the DOM tree and verifying that it's correct.
In all of these tests,
we're gonna basically be running in JS DOM mode.
Okay, so this Jest, config JS,
it says all tests will be executed
in the jsdom testEnvironment.
Therefore, Jest will create a document object
that our tests can execute against.
Okay, so there's just a reminder.
We've set the JSDOM test environment in our Jest config.
Okay then, so here's our simple, first test.
And on the right hand side
I've drawn a little picture just to remind you about
the structure of the document.
This basically is the default content that JSDOM creates.
It creates a document object with an HTML element,
this is called the document element.
Okay, so the document node is document.
The document object has a property called document element.
It's kind of like the root element.
HTML is the document element or the root element.
And then it has a head child and a body child,
all of this content here is created automatically for you
by JSDOM as a starting point.
And on the left hand side, you can see
I've got some code here,
which tests access to that little document object structure.
Okay, so I've got three tests.
Let's have look at the first test.
The first test, I basically grab the document object
and I'm hoping that it exists,
because I've configured JSDOM as my test environment,
it will exist.
Therefore, this test will pass.
The document property does exist,
and it'll give me this object here.
Okay, what about the second test?
In the second test, I take the document object,
and remember the document object
has a property called document element,
which gives us this element here.
Document element is a euphemism
for the root element in your webpage.
It's the HTML element.
So this will give you back a pointer,
effectively, to the HTML element.
I can check that the HTML element is not undefined.
Okay, so it does it exist.
I can also check that the document element,
in DOM every node has a property called node name.
Like basically, what's the name of the element?
What's the name of the element?
I'm expecting it to match this regular expression.
So in other words, I'm expecting the document
element's name to be HTML case insensitive.
You gotta be a bit careful with JSDOM
because these elements,
I think it generates them with capital letters.
So if you're doing matching on element names,
you probably want to be always
using a case insensitive comparison.
Okay, so what about the third test?
Let's have a look at this.
Grab the document element,
that would be the HTML element there.
I'm gonna use query selector,
that's a standard DOM API.
Query selector, you can give it a CSS selector.
This year we'll search for an element called head.
Does my document element have somewhere
a child element, or descendant, called head?
And does it have a descendant called body?
Yes and yes.
When you call query selector, this here is a CSS selector.
It could be the name of an element,
like head, or body, or div.
Or, it could be a CSS class like '.important',
or it could be an ID, like '#myID.'
So you can use any CSS selector.
This will check that the head element exists
and the body element exists.
Okay, so that's basic navigation.
It gives you an idea of the content that we get
for free using JSDOM and how we can access the content here.
If I ran that test, then it works.
Okay, now what about the second test?
The second test here is a bit more ambitious.
This is in example two, test JS.
So in here I'm gonna have a look
at several different tests,
just to kind of illustrate how
to create content in different ways, right?
So we're gonna have a look at three different ways
of creating content in my kind of pretend webpage,
via the document object.
So I'm gonna use JSDOM, create some content in the document
and then write some tests to check
if the content is correct.
So, first of all, in the first test
we're gonna create an element in the webpage.
So basically, whenever you wanna create content in DOM,
you always go back to the document object
and you say, "create element."
You give it the name of the element you wanna create,
and what that does, it just creates a node.
So I'll create a node, like an element basically,
a div, doesn't have any content yet.
So the way you set the content,
or one of the ways,
is you can say take the element
and set this inner HTML to be "Hello."
Technically speaking, that actually creates a sub-node,
a text node, that contains the text that you just specified.
Okay, so technically we've got two nodes there,
the div element, plus it's child content, the inner HTML.
This test doesn't really go too far.
It just checks that the element isn't null,
well of course it isn't because I just created it.
And it also checks that the element in the HTML is "Hello."
And of course it is because I've just assigned it there.
So that's like a starting point.
To take it a step further, what we'd need to do
would be to integrate this content into our actual webpage.
So let's see how to do that.
So, first of all, this is my second test.
On the first line there in red, I've created a div element,
so here's mydiv element.
And then we set this inner HTML to be ID, at "Hi" even.
Okay, so basically there's some inner text there, "Hi".
I've set this ID, nodes have an ID property.
Okay, so I'll kind of draw its ID here,
technically speaking as an attribute.
So the ID attribute is now set to be mydiv.
Okay, so that's the kind of idea
that you want to have in mind.
So at the moment I've created a div
but I haven't kind of integrated it into my web content.
So the easiest way to do it is this.
The document object provided by JSDOM
has a property called body,
which automatically gives you back the body element.
And in that body element, I'm appending the div.
So there'll be a body element in my webpage.
There'll also be a head element,
and there'll also be an HTML element,
and there'll also be a document property there.
Okay, so that's the basic structure that we've got.
When you say document body,
it automatically gives you access to this node here.
And in that node, I've just appended the div.
That's the easiest way of adding content.
At the end of my body, as its last child,
append this div.
So mydiv is now part of the webpage.
Right, so if I go back to my document,
so that's basically going back right up to the top here,
so this is going back up to the document node.
I can say, find the element whose ID is mydiv.
So this is a genuine request, this is effectively
like a mini pretend webpage.
And find the div whose ID is mydiv.
It should give me back that div,
if this is all properly integrated
I should get back a pointer to this div element.
So this should be he element that I found.
Check that I have found it,
and check that its inner HTML is "Hi."
Okay, so there you go.
Create elements like this.
This code would probably be in your actual web page,
this real JavaScript code.
And then this is how you can check that the content exists.
Find the element in the document
and then check that it's content is
what you expect it to be.
Okay, so creating elements manually, one by one,
create an element, set its HTML, set its ID.
You can do this for each individual element, one by one,
but if you wanted to build a complex list, for example,
it would be quite painful creating each list item
as an individual object,
and then adding it one by one.
An easier approach, sometimes,
is just to formulate an entire string of HTML
and just add it to the document directly.
And it builds the DOM tree accordingly.
So here, what I've done,
I'm using JavaScript these days, we have a back tick.
Back tick is called, like a template string.
It can span multiple lines, it's a multi-line string
and that can be quite handy
if you wanna formulate some lengthy HTML.
So here it's just a string at this stage,
an unloaded list of items
that you might take on a ski holiday, for example.
This HTML, or this string,
I'm assigning to the body of my document.
This is the easiest way of loading content
into your document object, so that you can test against it.
So again, remember what's going on.
There's a document object provided by Jest, or by JSDOM.
It had an HTML child,
that's the document element.
The HTML child has a head child and a body child.
And then what I'm doing here, in one single fell swoop,
I'm saying, take that body and set this entire
inner HTML to be that.
So that will automatically, basically add the unloaded list,
plus three list items, list item, list item, list item.
Each list item will have some text: skis, boots, goggles.
Okay, so just by assigning HTML like that,
to the inner HTML of the body,
you're effectively creating the document structure
that you want to test against.
You can then write tests against that document structure.
And that's what I'm doing here.
I'm saying query Select All,
that will give you back a collection of all nodes
of type L I, it'll give back a node list,
containing three list items: skis, boots, goggles.
I called that L I S, as in list items.
Check that it's a node list,
check that the length is three
because there were three items added.
Get the first element,
so this will give me back a point there
to the first list item.
So that would be that one there.
Check that it's inner HTML is "Skis,"
and then the second one is "Boots,"
and the third one is "Goggles."
So hopefully you can see how this pans out.
Basically, the document body property
is the key point here.
You can just give it a whole chunk of HTML
and that sets up the document structure,
against which you can then write your tests
to see if it's updating the document structure correctly.
Although it's quite a simple example,
it's also quite a realistic example
of how we're gonna be going on for the rest of this lesson.
So just need to run that test and it works.