Frontend testing JSDOM web apps
Tags: frontend, jest, jsdom, opensource
Published: 2023-12-09 23:40:34

I have been working on expanding my understanding of creating test environemnts and developing tests for various languages.  It’s a fascinating and challenging element of the development process that I have been wanting to explore for a long time now.
  
Having successfully created a test environment and written testing for my Python static site generator project, I thought it would be a good learning experience to implement testing for a different project that I have contributed to in the past.  This [RegEx Pro]( https://github.com/hammadsaedi/regex-pro) project is the front-end  for a JavaScript web app that defines a number of tools to test and validate regular expressions against user input.

I decided to use the [Jest](https://jestjs.io/docs/getting-started) testing framework to create a testing environment for the application. Going into this I had minimal familiarity with Jest and immediately, I realized that this task was venturing into unfamiliar territory in teerms of my understanding of testing front-end code.  Specifically, the project has a fairly straightforward [structure which utilizes JSDOM]( https://github.com/hammadsaedi/regex-pro/blob/main/script.js) to render the web app.  While the source code was simple and straightforward in it's method of rendering a UI, it presented a unique challenge in developing the appropriate test environment which needs to interact and render the DOM elements. 

Investigating options for testing JSDOM with Jest was a surprisingly difficult task.  I found that there is limited documentation on the basics of writing tests for JSDOM. What information I did find described many varied approaches to the problem.  I came to realize there a quite a few frameworks and tools to address front-end JS testing, with widely varying  methods. The documentation I found addressing this challenge was often beyond my level of comprehension and often addressed much more complex cases than I was attempting.

In the end, I found this article, [Frontend testing in Node with jsdom](https://oliverjam.es/articles/frontend-testing-node-jsdom) by [Oliver Jam](https://oliverjam.es/) which provided a very simple entry point to understanding front-end testing for JSDOM.  In addition, it provided an example [repo](https://github.com/oliverjam/frontend-testing-jsdom) which creates simple but functional JSDOM test environment. Being able to work through the environemnt configuration on a fundamental level was extremely helpful in understanding the challenge I was facing and allowed me to make some progress towards my goal.

What I was able to implement is undoubtedly the first iteration in configuring an appropriate test environment. It can be [reviewed here]( https://github.com/bryce-seefieldt/regex-pro/tree/issue-33). 
I would really appreciate any feedback on what I have implemented and suggestions on streamlining the configuration and the tests I’ve written so far.  I still intend to work further to address code coverage, including more comprehensive integration testing and expanding the unit tests. This will require some further research on my part into testing user input cases. 

Some of my key takeaways from the process so far:
-	The RegEx Pro application has an [index.html]( https://github.com/bryce-seefieldt/regex-pro/blob/issue-33/index.html) entry point , which renders [script.js]( https://github.com/bryce-seefieldt/regex-pro/blob/issue-33/script.js) as the landing page. The most challenging step in understanding the use of Jest for testing JSDOM elements was learning how to generate mock document objects which can be used to test the various JS modules independently.  
-	The approach I took to address the creation of JSDOM objects for independent unit tests required a number of dependencies. In the end the following dev-dependencies were required in [package.json](https://github.com/bryce-seefieldt/regex-pro/blob/issue-33/package.json):
```
  "devDependencies": {
    "@babel/core": "^7.23.5",
    "@babel/preset-env": "^7.23.5",
    "babel-jest": "^29.7.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "jsdom": "^23.0.1",
    "jsdom-global": "^3.0.2",
    "text-encoding": "^0.7.0"
  }
```
-	A major hurdle that took quite a bit of trial and error to solve was Jest producing the following error at runtime:
`SyntaxError: Cannot use import statement outside a module` 
Which was related to importing modules into  .test.js files. It was solved by installing Babel and including the following `.babelrc` file in the project:
```.babelrc
 {
    "presets": [
        "@babel/preset-env"
    ]
}
```

-	As well, the syntax for the [test files](https://github.com/bryce-seefieldt/regex-pro/tree/issue-33/tests), utilized the following code to initialize a document object that can be called within the test functions to render the applications various JSDOM components:
```*.test.js
import { JSDOM } from "jsdom";
const dom = new JSDOM();
global.document = dom.window.document;
```
As my research continues into front-end testing I have read about a number of other approaches and frameworks that may facilitate JSDOM testing, including the [Selenium](https://www.selenium.dev/) framework which may offer some more comprehensive tools for integration testing and CI workflows.  I will continue to post updates as I refine and expand my initial testing for this project.