Check out a free preview of the full Testing Fundamentals course
The "DOM Testing Tools" Lesson is part of the full, Testing Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Steve explains that DOM testing is more difficult because DOM APIs are unavailable in the Node.js runtime. Libraries like Happy DOM solve this problem by providing a JavaScript implementation of a web browser without its graphical user interface.
Transcript from the "DOM Testing Tools" Lesson
[00:00:00]
>> Steve Kinney: Turns out front end engineers tend to do stuff in the web browser, I've heard it happens. There are some things about testing the DOM that we have to think about in terms of everything we've talked about so far. One, your tests don't run in the browser, yet, they we'll deal with that, this moment, they don't.
[00:00:18]
Your tests run in Node. Node runs JavaScript that is true, but it doesn't have any of the browser APIs, right. Has some of them, I'm not gonna get into the difference between the behavior object model and the document object model and where actually console log and settimeout live in the JavaScript spec, nobody cares.
[00:00:36]
Important part is you don't have access, there is no DOM in node. Right, it's not a browser, there's no browser APIs, ish. Turns out the DOM is one of those APIs, this means the node doesn't have the DOM, which means you can't test the DOM from node.
>> Steve Kinney: Do it anyway, by lying.
[00:01:00]
>> Steve Kinney: So there are a few different libraries. If you use Jest, JSDOM is built in. If you use Vitest, you have the choice between two, because why not? JSDOM and HappyDOM. JSDOM, in the earlier days, a fellow named Dominic DiCola re-implemented the DOM in JavaScript, right? The entire DOM spec in JavaScript, I think it's a larger community thing at this point.
[00:01:28]
But it's basically adds back in all of those browser APIs into the node environment. So you have stuff like document.queryselector, document, window, all of those fun things that are not node. It puts in spec compliant replacements for those. You have a choice between two of them, I don't really care which one you pick honestly.
[00:01:51]
I'm gonna be honest with you, I pick HappyDOM cuz of the name. It is the smaller, lightweight one but what makes JSDOM, the bigger, heavier one is that it's probably more accurate, right? So for most things, if you're just putting some DOM nodes on a document and seeing if they're there, HappyDOM will do the trick.
[00:02:11]
If you run into weird edge cases, the bigger heavier JSDOM works. Honestly, I don't care which one you use. I pick HappyDOM cuz I like the name, right? Things to keep in mind is that it's not a real browser, so you're not gonna catch stuff like the nuances of, let's be honest, Safari, or Firefox or whatever, is simply a compliant version of that.
[00:02:34]
And also, I have a few workshops on performance, where my rule about performance is not doing stuff is faster than doing stuff, right? So, yes, you can bring in this entire simulation of the DOM that is doing more stuff than not doing stuff, thereby your test will be slightly slower.
[00:02:53]
Ask me, how much slower? Honestly, imperceptibly. Cuz if your test suite does take forever to run you are gonna run it less. Also, we all know, you open up that PR and you sit there and you stare at it until all those statuses turn green, don't you? You do wait for it, you don't do anything until all those tests pass, you just watch it, me too.
[00:03:16]
So yeah, you might still run into browser specific issues, it's not a browser. But it is really good for, hey, I've got this piece of code that modifies the DOM. Because like I said earlier, can you fire up an entire browser and use that to test your code?
[00:03:31]
You can, but on that same principle, do you know what takes a really long time? Firing up an entire browser, loading up the entire page, and go ahead and just to see if, one string changed, right? And so this is a really great strategy for that uncanny valley of it's not just a function that takes two numbers or string and modifies it.
[00:03:55]
But I don't necessarily wanna whip up the entire app in a browser and test it right? So great for, I wanna grab one component, or I wanna check for one event listener, or something along those lines, works really well for that. I will show you this in the code, but there is basically one small tweak in vitest.
[00:04:16]
I think it is just built in for free and just, but I'd have to remember. This is what it looks like in vitest, and there's actually a few more things to talk about here, which is so that environment happy-dom, by default, the environment is node. If you change that string to from environment node to environment happy-dom, guess what?
[00:04:40]
You now have loaded in with all your tests, happy-dom. If you change it to JSDOM, guess what you have now, JSDOM. There's also test setup files, we'll talk about that one later. The other one is globals which is out of the box in vitest, but not in jest.
[00:04:57]
You have to import describe expect and it from vitest and jest, they're globally available. This just makes vitest more like jest. I turned it on from most of our examples so that you didn't have to think about the difference. So these are just some configurations that we can do as well, but let's actually see it in action.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops