Mocking the DOM Is A Mistakeimage
All Stories

Mocking the DOM Is A Mistake

A couple weeks ago, I started working on an open source, all-in-browser video editor leveraging the new WebCodecs and WebGPU APIs. It's been a lot of fun, but working with new, relatively undocumented and untested APIs has presented both expected and unexpected challenges.

One of those unexpected challenges has been setting up a testing framework.

Pasted image 20230526075500.png

See, WebCodecs and WebGPU are barely available in the latest chromium browsers. So, obviously (to me now) they aren't available yet in DOM emulators like jsdom and happy-dom that are usually used with testing frameworks like vitest and jest.

This was a frustrating problem and a reminder that you can be mocked by your mocks. Mocking is a necessary part of testing in many cases, but at the end of the day it's a total hack. And people smarter than me on Twitter felt me pain. One of those people who reached out with consolations and suggestions was my friend Matt Brophy.

Pasted image 20230526075652.png

Matt's spicy take that inspired this articles title felt right-on in that moment. Since 2019, he's consistently run into issues working on projects that couldn't be reliably tested due to limitations of DOM emulators. And the problem has only gotten more prevalent as browsers have gotten more powerful and more of our code relies on these newer APIs that are much harder to reimplement in an emulator.

But as Matt alludes to in the second half of his tweet, test runners have noticed this problem and are all consistently moving in a similar direction: running our unit tests directly in the browser.

"Isn't that what we've done for a while for end-to-end testing with tools like Cypress, Playwright and Puppeteer?" you ask.

Yes...but...these e2e testing frameworks historically have only focused on allowing us to "play user" and perform automated interactions against our full applications. Now, however, new projects are enabling us to test individual components and functions in those same headless browser environments.

Vitest, Playwright, Storybook, and Puppeteer are all working on versions of this type of testing. However, most of them are experimental and not ready for prime-time just yet.

There is one though that was recommended to me by Edouard Bozon that Just Works™️ and is what I'm using now for Framecrafter: Web Test Runner.

Pasted image 20230526075725.png

This aptly named project from Modern Web does exactly what its name suggests. Using Playwright under the hood, WTR runs Mocha and Chai unit tests in real browser environments. The server it runs is built off of Rollup and ESbuild, meaning that it's wicked fast and extensible.

In fact, thanks to a community plugin by GitHub user @remcovaes, I was actually able to have WTR use my Vite configuration directly. So now, my tests are running nearly identically to the way my code runs in development and production. How cool is that?!

There are a couple gotchas with WTR though. The HMR and watch features aren't the most reliable or usable right now - which can be a big hit to developer productivity. So, I don't actually recommend switching just yet - especially because the frameworks you already use like Vitest and Playwright are already implementing their own versions of in-browser unit testing.

All-in-all, I'm excited that so much innovation is happening to help us test our client-side JS code where it was meant to be the browser.

Until next time.

Drew Lyton
Drew Lyton
Friday, May 26, 2023

I'm a software engineer, ex-founder and writer who cares deeply about creating a better relationship between technology and society. I'm currently writing a book about early stage entrepreneurship.


If this article has been valuable and you'd like to be notified the next time I post, subscribe to my newsletter!

Each week, I share my latest post along with three other works from people smarter than me on whatever topic is top of mind. Of course, you can unsubscribe at anytime.