Today I learned: Jest used with JSDOM as environment does not support navigation, full stop!
Posted on
TL;DR
JSDOM does not support Navigation to different pages.
Context
I use the Jest testing framework, configured to use JSDOM as environment.
After failing to write a test that asserts clicking on a link would navigate to a new page, I spent hours researching for a solution. That was only to realised it is mission impossible. Jest is not to blame though!
At this point, to be very honest, the only one to blame may be me. Indeed what I
was trying to does not make so much sense as the navigation in my use case is
not instructed by Javascript but through the default behaviour of HTML anchor
links.
I believe I got trapped by the fact that in the past, I mapped some mouse and
keyboard interactions in Jes. These though only involved changes to be asserted
onto the current page and therefore made sense and were functioning.
In case you are using Location.assign(url)
in your implementation, you may
be interested into reading Ben Ilegbodu's post: Mocking window.location methods
in Jest & jsdom. It is a use case worth a cover in your tests suite.
Learning
Crawling through loads of Github issues, Stackoverflow threads and blog posts...
I landed on the JSDOM documentation which mentions it "does not handle
navigation", full stop.
It explains that clicking a link will change nothing, i.e "there will be no
new Window or Document object, and the existing window's location object will
still have all the same property values".
This confirms we cannot assert a link click default behaviour because the way to
do that would have been to check for the value of
window.document.location.href
, but it won't change!
Conclusion
JSDOM is not a Web Browser nor a Web driver and therefore has no primary
interests on implementing Navigation. It emulates the DOM, what implies the
current Document Object Model. Although it is also used for scraping websites,
it expects its consumers to direct it to the pages to be scraped rather than
offer crawling/navigation support. It's fair!
In the JavaScript ecosystem, PhantomJS is better suited candidate for such use
cases.
Reference
jsdom/jsdom: A JavaScript implementation of various web standards, for use with Node.js