UNPKG

@happy-dom/jest-environment

Version:
179 lines 6.73 kB
"use strict"; /* eslint-disable filenames/match-exported */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const JestUtil = __importStar(require("jest-util")); const jest_mock_1 = require("jest-mock"); const fake_timers_1 = require("@jest/fake-timers"); const happy_dom_1 = require("happy-dom"); /** * Happy DOM Jest Environment. */ class HappyDOMEnvironment { fakeTimers = null; fakeTimersModern = null; window; global; moduleMocker; /** * jest-environment-jsdom" has the default set to ['browser'] * As changing this value would be a breaking change, we will keep it at ['node', 'node-addons'] until we do a major release * * @see https://stackoverflow.com/questions/72428323/jest-referenceerror-vue-is-not-defined */ customExportConditions = ['node', 'node-addons']; _configuredExportConditions; /** * Constructor. * * @param config Jest config. * @param config.globalConfig jest global config. * @param config.projectConfig jest project config. * @param options Options. */ constructor(config, options) { let projectConfig; let globals; if (isJestConfigVersion29(config)) { // Jest 29 globals = config.globals; projectConfig = config; } else if (isJestConfigVersion28(config)) { // Jest < 29 globals = config.projectConfig.globals; projectConfig = config.projectConfig; } else { throw new Error('Unsupported jest version.'); } if ('customExportConditions' in projectConfig.testEnvironmentOptions) { const { customExportConditions } = projectConfig.testEnvironmentOptions; if (Array.isArray(customExportConditions) && customExportConditions.every((condition) => typeof condition === 'string')) { this._configuredExportConditions = customExportConditions; } else { throw new Error('Custom export conditions specified but they are not an array of strings'); } } // Initialize Window and Global this.window = new happy_dom_1.Window({ url: 'http://localhost/', ...projectConfig.testEnvironmentOptions, console: options.console || console, settings: { ...projectConfig.testEnvironmentOptions?.settings, errorCapture: happy_dom_1.BrowserErrorCaptureEnum.disabled } }); this.global = this.window; this.moduleMocker = new jest_mock_1.ModuleMocker(this.window); // Node's error-message stack size is limited to 10, but it's pretty useful to see more than that when a test fails. this.global.Error.stackTraceLimit = 100; // TODO: Remove this ASAP as it currently causes tests to run really slow. this.global.Buffer = Buffer; // Needed as Jest is using it this.window['global'] = this.global; JestUtil.installCommonGlobals(this.window, globals); // For some reason Jest removes the global setImmediate, so we need to add it back. this.global.setImmediate = global.setImmediate; this.fakeTimers = new fake_timers_1.LegacyFakeTimers({ config: projectConfig, global: this.window, moduleMocker: this.moduleMocker, timerConfig: { idToRef: (id) => id, refToId: (ref) => ref } }); this.fakeTimersModern = new fake_timers_1.ModernFakeTimers({ config: projectConfig, global: this.window }); // Jest is using the setTimeout function from Happy DOM internally for detecting when a test times out, but this causes window.happyDOM?.waitUntilComplete() and window.happyDOM?.abort() to not work as expected. // Hopefully Jest can fix this in the future as this fix is not very pretty. const happyDOMSetTimeout = this.global.setTimeout; this.global.setTimeout = (...args) => { if (new Error('stack').stack.includes('/jest-jasmine')) { return global.setTimeout.call(global, ...args); } return happyDOMSetTimeout.call(this.global, ...args); }; } /** * Respect any export conditions specified as options * https://jestjs.io/docs/configuration#testenvironmentoptions-object */ exportConditions() { return this._configuredExportConditions ?? this.customExportConditions; } /** * Setup. * * @returns Promise. */ async setup() { } /** * Teardown. * * @returns Promise. */ async teardown() { this.fakeTimers.dispose(); this.fakeTimersModern.dispose(); await this.global.happyDOM.abort(); this.global.close(); this.global = null; this.moduleMocker = null; this.fakeTimers = null; this.fakeTimersModern = null; } /** * Runs a script. * * @param script Script. * @returns Result. */ runScript(script) { return script.runInContext(this.global); } /** * Returns the VM context. * * @returns Context. */ getVmContext() { return this.global; } } exports.default = HappyDOMEnvironment; function isJestConfigVersion29(config) { return Object.getOwnPropertyDescriptor(config, 'globals') !== undefined; } function isJestConfigVersion28(config) { return Object.getOwnPropertyDescriptor(config, 'projectConfig') !== undefined; } //# sourceMappingURL=index.js.map