I'm testing a JavaScript function that amends a DOM element with Mocha, Chai and JSDOM. However I am running into issues when as the DOM I've mocked up with JSDOM doesn't appear to be connecting to the JS file where the function is. When I run the test in npm, I get:
TypeError: Cannot set properties of null (setting 'innerHTML')
This error is on the line where the function changes the element value. The function itself works in the browser when I am running the actual HTML file.
I understand that JSDOM mocks up the DOM for the purposes of the test, which is what the JS file needs use, however it doesn't appear to be actually reading this mocked up DOM so it's just seeing it as NULL. I have reviewed several tutorials to try to figure out why such as https://sparkbox.com/foundry/improve_unit_testing_with_mocha_chai_jsdom and https://freecontent.manning.com/testing-with-node-jest-and-jsdom/
and I have looked on several questions here on StackOverflow before (including This very informative page but despite trying the solutions, I still can't seem to get it hooked up. I understand it in theory, but after 3 days I can't see what it is that I'm missing.
I've included relevant code snippets below - can someone steer me in the right direction?
Function to be tested:
export function updateDisplay(value) {
document.getElementById("display").innerHTML = value;
}
Test
import {expect} from "chai"
import {JSDOM} from "jsdom";
import {updateDisplay} from "./foo.js";
describe("Update Display", function () {
beforeEach(() => {
const dom = new JSDOM(
`<html>
<body>
<div>
<p id="display"></p>
</div>
</body>
</html>`,
{ url: 'http://localhost' },
);
global.window = dom.window;
global.document = dom.window.document;
});
it("should update the text content of display element", function () {
const value = "TEST";
updateDisplay(value);
expect(document.getElementById("display").innerHTML).to.equal(value);
})
});
package.json - relevant sections only
{ ...
"scripts": {
"test": "mocha -r jsdom-global/register"
},
"devDependencies": {
"@babel/cli": "^7.17.10",
"@babel/core": "^7.18.0",
"@babel/node": "^7.17.10",
"@babel/preset-env": "^7.18.0",
"@babel/register": "^7.17.7",
"chai": "^4.3.6",
"eslint": "^8.14.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.1.0",
"eslint-plugin-promise": "^6.0.0",
"fs": "^0.0.1-security",
"jsdom": "19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^10.0.0"
},
...}