When running tests with "testEnvironment": "node" and expect determines via duck typing that it has DOM nodes to compare it throws ReferenceError: Element is not defined since Element isn't available in Node.
Use "testEnvironment": "node" and run this test
describe("reproduce bug", () => {
it("should know that inside a 'node' env there is no 'Element' in scope", () => {
expect({ nodeName: "div", nodeType: 1 })
.toEqual({ nodeName: "div", nodeType: 1 });
});
});
The most likely culprit in my opinion is this region where it was determined per duck typing that the things to compare are DOM nodes and then an unguarded instanceof Element check is run https://github.com/facebook/jest/blob/master/packages/expect/src/jasmineUtils.js#L134
It should always check that Element or any other host object is defined before it is used - so the test above should be green.
https://repl.it/repls/PureFrightenedIntegers
npx envinfo --preset jestPaste the results here:
> npx envinfo --preset jest
npx: installed 1 in 3.224s
System:
OS: Linux 4.15 Ubuntu 18.04.1 LTS (Bionic Beaver)
CPU: (4) x64 Intel(R) Core(TM) i3-5005U CPU @ 2.00GHz
Binaries:
Node: 8.10.0 - /usr/bin/node
npm: 6.7.0 - /usr/local/bin/npm
npmPackages:
jest: ^24.0.0 => 24.0.0
Wanna send a PR for it?
/cc @pedrottimark
This code in vue-test-utils.js fails (@vue/test-utils 1.0.0-beta.31). Just installed today released jest 25.1.0 and ts-jest 25.0.0 with vue-jest 3.0.5 (latest)
function polyfill() {
// Polyfill `Element.matches()` for IE and older versions of Chrome:
// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
}
}
This was fixed in #7995 (included in 24.3.0), and we just forgot to close this issue.
@postb99 could you please open up a new issue with reproduction steps? https://repl.it/repls/PureFrightenedIntegers does not reproduce using 24.9.0 or 25.1.0 for me, so I think your issue is different somehow.
@SimenB Thanks. I just fixed it... By installing jsdom-global as stated here: https://vue-test-utils.vuejs.org/guides/#choosing-a-test-runner despite it should have been set up automatically.
So I may open an issue but I think I misread something in documentation... How to find the culprit ?
So the relevant packages for my setup are these ones. I write .vue components using typescript, and now Jest runs the test fine. The test code is also written in ts.
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.8.3",
"@types/jest": "^24.9.0",
"@types/jsdom": "^12.2.4",
"@vue/cli-plugin-babel": "^4.1.2",
"@vue/cli-plugin-typescript": "^4.1.2",
"@vue/cli-plugin-unit-jest": "^4.1.2",
"@vue/cli-service": "^4.1.2",
"@vue/test-utils": "^1.0.0-beta.31",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^25.1.0",
"jest": "^25.1.0",
"jsdom": "^16.0.1",
"jsdom-global": "^3.0.2",
"ts-jest": "^25.0.0",
"typescript": "^3.7.5",
"vue-jest": "^3.0.5",
"vue-template-compiler": "^2.6.11"
}
jest.config.js:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
// before the test framework is installed
setupFiles: ['./src/__mocks__/client.js'],
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'vue', 'node'],
transform: {
// process `*.vue` files with `vue-jest`
'.*\\.(vue)$': 'vue-jest',
// process `*.ts` files with `ts-jest`
'^.+\\.ts?$': 'ts-jest',
'^.+\\.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$',
testURL: 'http://localhost/8081'
}
client.js :
require('jsdom-global')()
remove testEnvironment: 'node', (or set it to the default jsdom) and then you don't need jsdom-global anymore.
This works well and even speeds up my tests, 4 suites of 37 tests run in 7s instead of 10s when testEnvironment is set to "jsdom". I don't know why I missed the best testEnvironment to set in the documentation, In fact I did a copy-paste from a colleague's project, this was not the best idea.