- In this section, we're going to write
some real JavaScript tests
that execute against real JavaScript code
that talks to a real HTML document.
So, this is the, the correct way
to test JavaScript talking to an actual webpage.
So, it's in this folder: JsDom_LoadingHtmlAndJs.
Let's take a quick look there first,
before we look at the details.
So, there's the folder
in Lesson 8, at JsDom_LoadingHtmlAndJs.
If you open that in a code editor,
what you'll find is a couple of things actually,
well quite a few things.
I've got the HTML document.
that's going to be loaded into my test.
I've got the code, which I want to test.
This is my actual code, my script.
That's some real JavaScript that I want to test.
I'll go to that in a moment.
But the tests are written here
and then I've got a bit of configuration
that I need to explain.
I've got configuration defined in my package.json
that I need to just explain.
And I've also got some configuration
in jest.config that I'm just going to confirm.
And I've got some other configuration in babel.config.
Okay. So, three different configuration files,
effectively, that I need to describe,
plus the HTML page,
the code that accesses the HTML page,
and the test against that code.
Okay. So, there were few things
that we need to discuss first.
So, I think the first place
is just to have a look at the HTML document
and I'll explain the scenario.
So, the idea is this is a table of products.
It's got three rows for three different products.
Each row has got two columns.
So, for example, the first row:
in the first column is the name of the product,
in the second column is the price.
I'm using CSS classes to differentiate between the columns.
The first column has a description class,
description, description,
and then for each row the second column
has a CSS class of price, price, and price.
So, what I'm actually gonna do in my code,
is I'm gonna find all the, all the table definition cells,
all the table data that have a class,
a CSS class of price.
I'm gonna grab these values
and I'm gonna add them up in my code
and give out the total.
And then I'm gonna write a test
to make sure that the total is correct.
So, that's the HTML content.
Just looking at this,
there's my TD with a class price,
another TD with a class price,
and then the third TD with a class price.
So, the next step:
let's write some code to actually calculate the total price.
So, here it is: myscript.js.
That's in the code folder as well
if you want to just have a look at it.
So, let's have a look at it.
It's, first of all, it's exported.
It calculates the total price.
So it goes to the document,
it searches.
First of all, it gets the products table.
Products table is the table that contains
all the table cells.
Within that table, I select all elements
that have a TD element name and a price class.
So, this syntax: search for the element name TD
and the .price is a class.
It'll gimme back all the TD elements for the prices.
So, it'll basically select the three price elements.
I'm gonna add those values up together.
So, set the total to zero,
loop through all the price elements,
the three TD price elements.
For each TD element, get the inner HTML.
And that would be a number, like 300.
But when you get text from a webpage,
it always comes back as a string.
So, I need to convert it into number.
And once I've got the number, I can add it to the total.
And at the end, I return the total.
So, that should hopefully work.
If this code is correct,
it should give me back the correct number
when I feed it that HTML document.
Okay. Now, just one observation.
This here is an ECMAScript module.
There are two main types of module or file in JavaScript.
We have
what we've been looking at most of this video series
is common Js modules,
which kinda like node.js,
where in a common Js module,
at the end of the module,
you'd have a statement like module.exports
to say which symbols are exported can be imported elsewhere.
But in a web browser, we don't use common Js.
We use ECMAScript module.
We use this syntax for exporting symbols.
Okay.
So, the way in order to support ECMAScript modules in Jest,
we have to have a bit of configuration
so that it knows to expect this ECMAScript module syntax,
instead of supporting the common Js module syntax.
So, to summarize, to enable us to use ECMAScript modules
in our tests, we have to configure our environment.
In order to allow ECMAScript modules to be loaded by Jest,
we've gotta tell it to use Babel, basically.
In my package.json,
I've added some development dependencies for Babel.
Okay.
And you have to then install those packages in your folder.
Okay. So, if you wanna run these tests yourself,
go to the folder
JsDom_LoadingHtmlAndJs,
open a command prompt window,
and in that command prompt window, type in this command:
npm install,
or yarn install,
and that will install the Babel packages.
It takes a moment or two-
probably takes about 30 seconds to install those.
Okay. So, assume that you've done that on your machine.
Once you've done that, you can then run the tests.
Okay. So, I'll leave that go assuming that's gonna work.
There is another piece of configuration.
You've also kind of gotta configure the Babel transpilar.
Babel is a transpilar
that converts modern ECMAScript syntax
into traditional JavaScript.
Okay. So, in my, I've got another file
called babel.config.json, which is here.
And in there, basically the Babel preset that
this is quite a complicated area.
The way that Babel works:
there are a thing called presets that basically tell Babel
what kind of conversions is it meant to do.
And when you set this preset,
basically what that says is
I'm going to, I want be able to
transpile my code into ECMAScript 2015.
This is the baseline version of traditional JavaScript.
It's the lowest common denominator,
all browsers support at least ECMAScript 2015.
Okay. So, that's also necessary.
Okay. So, now then, here is my test.
Now there's, there are a couple of things
that I need to point out here.
We've got two separate files involved:
an HTML file and code.
We need to load them both into our test
before we can run the test.
So, let me give you a quick sketch.
So, first of all, we had the HTML file.
Okay. That contains the actual data,
if you like, or the HTML content indexed on HTML.
This statement will load that HTML into my test.
So, if I draw my test kind of here,
this bit of code here will load the HTML document
into my test environment.
Okay. So, that's good.
So, I now have access via the document object,
remember, via the document object provided by Js DOM,
we now have access to that HTML content.
It's loaded in all the price data, effectively,
into my test environment.
But also we've got our JavaScript code,
the actual JavaScript code
lives in another file.
So, like we've been doing
for the, all the different lessons in the past,
we also need to load our JavaScript file
into our test environment as well.
And that's the way that you do that.
Okay. So, when you are using common Js,
so when you're using ECMAScript modules,
that's the way they import symbols.
If you've written any code in React or Angular,
you'd have seen syntax like this
import from my script,
it kind of knows that we're talking about my script, Js,
import the function.
I've imported that function from that file.
When you import a symbol from a file,
it automatically loads that file into the test environment.
So, the HTML content has been loaded
and so has my test code.
What I can then do, is I can write statements
like this document, this variable here document.
That's going to be basically that,
if I can just draw this picture here,
that will point to the route,
the document node in HTML content
that I've read in
The document element will be the HTML.
This will be the entire content of the file.
So, that's basically where the file content
gets loaded in to here.
This statement, that we've already discussed,
is already loaded in the JavaScript code.
So, that means we're now ready to write tests.
Let's write some tests.
So, I call my function, calculateTotalPrice.
So again, let me just draw a quick reminder.
In my, in my test,
my test has basically loaded the HTML content
into the document,
like so.
I've also loaded my calculate total price function,
calculateTotalPrice, like that.
So, that function,
that function is going to be accessing the document.
It'll access the document that we just loaded
and it'll calculate the total price
of elements in that document.
Okay. And it'll give me back a function
just like it would do in a normal environment,
but within our test environment.
And it should give me back,
well it says here the total price should be 1200.
Let's, let's have a quick look to see if we agree with that.
So, I have skis that cost 800 pounds.
That's quite expensive.
Plus 300 pounds for boots.
That's 1100 pounds.
Plus 100 pounds for goggles.
Wow. That's really expensive.
That comes to 1200.
So, if my code is correct,
then it should have loaded the document,
then done the correct algebra
and it should have come up with that figure.
The total price should be 1200.
Okay. So, if I run the tests and it works.
So, just to summarize what we've seen there:
the HTML document contained the actual HTML,
my JavaScript file contained my actual code,
I read the HTML file into Js DOM document,
I imported my JavaScript,
I called the JavaScript,
it accessed the HTML document,
and I've asserted that the result is correct.
So, that basically provides us
with a standard baseline going forward.
This is the way to load the HTML content
and the JavaScript
so that the JavaScript can access the real HTML content.
And it's a viable, useful test.