Repository navigation
Research and Provide a Demo of Unit Testing for front-end JavaScript code #7152
Description
Activity
- addedrole: back end/devOpsTasks for back-end developersTasks for back-end developersFeature: InfrastructureFor changes on site technical architectureFor changes on site technical architecturesize: 2ptCan be done in 7-12 hoursCan be done in 7-12 hours
on Jul 28, 2024 - moved this to New Issue Approval in P: HfLA Website: Project Board
on Jul 28, 2024 - addedDraftIssue is still in the process of being createdIssue is still in the process of being created
on Jul 29, 2024 - removedDraftIssue is still in the process of being createdIssue is still in the process of being created
on Sep 17, 2024 63 remaining items
- addedstatus: To Update!No update has been providedNo update has been provided
on Oct 17, 2025 - addedstatus: 2 Weeks InactiveAn issue that has not been updated by an assignee for two weeksAn issue that has not been updated by an assignee for two weeksand removedstatus: To Update!No update has been providedNo update has been provided
on Oct 24, 2025 I'm making progress, although this has turned into a bit of a science project and I'm working to pull the scope back in.
The main issues that I'm working are...
-
The JS has Liquid and Frontmatter, so it needs to be parsed before it can be imported into a test.
- This is not a huge problem -- it can be fairly easily done with gray-matter and liquidjs...
- BUT, if I want tests to be able to manipulate what is pulled in my the liquid statements dynamically, I have to parse and render the code within the context of the test, NOT as part of a Jest transformer
- AND if I do some sort of non-transformer-based dynamic transform-and-import, getting coverage reporting becomes extremely complicated.
- I got coverage working by using jest transforms and the real liquid data (from _data, _includes, etc.), but wasn't satisfied with having potentially moving data as a dependency for these tests. I considered fixed test data as well but didn't love that solution because it makes the data being tested very rigid.
- Path forward: I'm planning to abandon getting coverage to work for these "unit" style tests.
-
The frontend JS is a mix of CJS and ESM, but all have the extension .js
- Jest (and probably most test runners) need a hand in knowing what the format of these files is.
- Path forward: I'm proposing renaming the frontend JS files that use ESM syntax as .mjs, which is the standard extension for that syntax
-
Many frontend JS files don't export test functions, they just execute on the DOM immediately with eventWatchers, etc.
- This basically means that the DOM is an input and and output to all of these scripts, and the script mostly produces "side effects" rather than outputs.
- That's no problem and easily testable in Node with jsdom, but it's straying away from the "unit test" definition, which I've seen often imply "deterministic input and output"
- Path forward: I'm pursuing a sort of mix between what I consider "unit" testing and "integration" testing. The tests use the actual HTML DOM that they would work on (pulled in from the associated live HTML files) because that seemed more sensible than standing up an entire parallel DOM. These JS tests could break if the HTML changes, which to my eye is not necessarily a bad thing (maybe the JS became non-functional as well and needs to be addressed).
What I've actually done:
- made a parser that translates our .js files with inline liquid statements and gray matter into importable files/modules
- wrote some sample unit/integration tests for hamburger-nav.js, project.js, and vrms-events.js.
- I got super bogged down trying to get coverage working with the transform -- now that I'm dropping that, I hope to still meet my initial ETA of 10/31 for a PR on this.
-
- addedstatus: UpdatedNo blockers and update is ready for reviewNo blockers and update is ready for reviewand removedstatus: 2 Weeks InactiveAn issue that has not been updated by an assignee for two weeksAn issue that has not been updated by an assignee for two weeks
on Oct 25, 2025 - removedstatus: UpdatedNo blockers and update is ready for reviewNo blockers and update is ready for review
on Oct 31, 2025 - addedsize: 8ptCan be done in 31-48 hoursCan be done in 31-48 hoursand removedsize: 2ptCan be done in 7-12 hoursCan be done in 7-12 hours
on Nov 21, 2025 Hi team, update on this issue:
As stated above, and in my PR (#8411), I was able to create a working Jest infrastructure for testing our front-end JavaScript, and running those tests in PR CI. However, ultimately, I don't think that a unit test infrastructure is a good fit for the current website JS, and I recommend closing this issue. I came to this assessment for two reasons:
-
Liquid Statement Rendering Complexity
As noted in the original issue, our JS uses Liquid Jekyll statements embedded in the JS that are then rendered into pure JS during the Jekyll build process. Unit tests need to be run on pure JS, so any test infrastructure needs to find some way to replicate that rendering -- either by relying on a full site build (slow) or doing a targeted render of the files under test (fast but complicated). I chose the targeted render approach using Jest Transformers, because I found the iteration loop of waiting for a full site build during each run to be too long. The transformer ultimately works, but I feel that it would be hard to maintain and would add a layer of difficulty in understanding the test environment for new contributors. -
Few Logic-Only Functions:
Unit tests work best on code that is easily broken up into discrete "units", with deterministic inputs and outputs. Our site JS is not structured that way -- the majority of the complicated code in our frontend codebase that we would have the most interest in testing does direct DOM access and manipulation, making them dependent on external state. It's possible to write unit tests for code like this, but it requires a significant amount of surrounding setup to build a fake environment for the code to execute on.
I think that unit testing would become much more viable if we restructured the frontend JS to isolate pure logic functions from Liquid Jekyll rendering and direct DOM access -- then, we could focus unit testing efforts on those isolated logic functions and avoid the complexity introduced from the two issues above. However, that would be a major effort, and might not be the direction our site should go, given that (from my read) most of the interesting logic needs DOM access to function.
The other approach that I think we could take is focusing on end-to-end testing of the rendered site. With end-to-end testing, we avoid both of the issues above, and would be able to generate tests that, in my opinion, are more straightforward and would more easily provide bug detection and prevention. I ended up putting together a test PR of this concept against my own fork here: ryanfkeller#1171, showing some basic tests against the /projects page running in CI.
-
- moved this from In progress (actively working) to Questions / In Review in P: HfLA Website: Project Board
on May 16, 2026
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsQuestions / In Review
Overview
We need to select a strategy and a test framework for running unit tests against the front-end JavaScript code in the HfLA website, so that tests can be run first locally and then ultimately as a Pull Request check, in order to ensure the quality of JavaScript code updates. In this issue several sample unit tests will be developed and will be run locally from the command line.
Action Items
unittests-JSfrontendResources/Instructions
https://jasmine.github.io/
[How to Test a GitHub Action with GitHub Actions]