Happy DOM Global Registrator provides a utility for registering Happy DOM (a JavaScript implementation of web browser APIs) globally in Node.js environments, primarily for testing purposes. It exposes a simple API to set up and tear down a complete DOM environment including window, document, and other web APIs in the global scope.
npm install @happy-dom/global-registrator --save-devimport { GlobalRegistrator } from '@happy-dom/global-registrator';For CommonJS:
const { GlobalRegistrator } = require('@happy-dom/global-registrator');import { GlobalRegistrator } from '@happy-dom/global-registrator';
// Register Happy DOM globally with default settings
GlobalRegistrator.register();
// Now DOM APIs are available globally
document.body.innerHTML = '<button>My button</button>';
const button = document.querySelector('button');
console.log(button.innerText); // "My button"
// Clean up when done
await GlobalRegistrator.unregister();Register Happy DOM in the global scope to make DOM APIs available throughout the Node.js environment.
/**
* Registers Happy DOM globally.
* @param options - Optional configuration object
* @throws Error if Happy DOM is already registered
*/
static register(options?: RegisterOptions): void;
interface RegisterOptions {
/** Window width. Defaults to 1024 */
width?: number;
/** Window height. Defaults to 768 */
height?: number;
/** Initial URL for the window */
url?: string;
/** Browser settings configuration */
settings?: IOptionalBrowserSettings;
}Usage Examples:
// Register with default settings
GlobalRegistrator.register();
// Register with custom window dimensions and URL
GlobalRegistrator.register({
url: 'https://example.com/',
width: 1920,
height: 1080
});
// Register with browser settings
GlobalRegistrator.register({
settings: {
navigator: {
userAgent: 'Custom User Agent'
},
disableJavaScriptEvaluation: true
}
});Unregister Happy DOM and restore the original global environment.
/**
* Closes the window and unregisters Happy DOM from being global.
* @returns Promise that resolves when cleanup is complete
* @throws Error if Happy DOM is not currently registered
*/
static unregister(): Promise<void>;Usage Example:
GlobalRegistrator.register();
// Use DOM APIs...
document.body.innerHTML = '<div>Content</div>';
// Clean up
await GlobalRegistrator.unregister();
// DOM APIs are no longer available
console.log(global.document); // undefinedCheck whether Happy DOM is currently registered globally.
/**
* Returns the registered state.
*/
static get isRegistered(): boolean;Usage Example:
console.log(GlobalRegistrator.isRegistered); // false
GlobalRegistrator.register();
console.log(GlobalRegistrator.isRegistered); // true
await GlobalRegistrator.unregister();
console.log(GlobalRegistrator.isRegistered); // falseComprehensive browser settings configuration interface imported from happy-dom.
interface IOptionalBrowserSettings {
/** Disables JavaScript evaluation */
disableJavaScriptEvaluation?: boolean;
/** Disables JavaScript file loading */
disableJavaScriptFileLoading?: boolean;
/** Disables CSS file loading */
disableCSSFileLoading?: boolean;
/** Disables computed style rendering */
disableComputedStyleRendering?: boolean;
/** Handle disabled file loading as success */
handleDisabledFileLoadingAsSuccess?: boolean;
/** Settings for timers */
timer?: {
maxTimeout?: number;
maxIntervalTime?: number;
maxIntervalIterations?: number;
};
/** Settings for fetch */
fetch?: {
/** Disables same-origin policy (CORS) */
disableSameOriginPolicy?: boolean;
/** Disables validation of certificates against the list of supplied CAs */
disableStrictSSL?: boolean;
/** Fetch interceptor */
interceptor?: IFetchInterceptor | null;
/** Virtual servers used for simulating a server that reads from the file system */
virtualServers?: IVirtualServer[] | null;
};
/** Error capturing policy */
errorCapture?: BrowserErrorCaptureEnum;
/** Settings for the browser's navigation */
navigation?: {
/** Disables navigation to other pages in the main frame or a page */
disableMainFrameNavigation?: boolean;
/** Disables navigation to other pages in child frames (such as iframes) */
disableChildFrameNavigation?: boolean;
/** Disables navigation to other pages in child pages (such as popup windows) */
disableChildPageNavigation?: boolean;
/** Disables the fallback to setting the URL when navigating to a page is disabled */
disableFallbackToSetURL?: boolean;
/** Sets the policy for cross-origin navigation */
crossOriginPolicy?: BrowserNavigationCrossOriginPolicyEnum;
};
/** Settings for the browser's navigator */
navigator?: {
userAgent?: string;
maxTouchPoints?: number;
};
/** Settings for the browser's device */
device?: {
prefersColorScheme?: string;
prefersReducedMotion?: string;
mediaType?: string;
forcedColors?: string;
};
/** Debug settings */
debug?: {
traceWaitUntilComplete?: number;
};
}
enum BrowserErrorCaptureEnum {
/** Happy DOM use try and catch when evaluating code, but will not be able to catch all errors and Promise rejections. This will decrease performance as using try and catch makes the execution significally slower. This is the default setting. */
tryAndCatch = 'tryAndCatch',
/** Happy DOM will add an event listener to the Node.js process to catch all errors and Promise rejections. This will not work in Jest and Vitest as it conflicts with their error listeners. */
processLevel = 'processLevel',
/** Error capturing is disabled. Errors and Promise rejections will be thrown. */
disabled = 'disabled'
}
enum BrowserNavigationCrossOriginPolicyEnum {
/** The browser can navigate to any origin. */
anyOrigin = 'anyOrigin',
/** The browser can only navigate to the same origin as the current page or its parent. */
sameOrigin = 'sameOrigin',
/** The browser can never navigate from a secure protocol (https) to an unsecure protocol (http), but it can always navigate to a secure (https). */
strictOrigin = 'strictOrigin'
}
interface IFetchInterceptor {
/** Hook dispatched before making an async request. */
beforeAsyncRequest?: (context: {
request: Request;
window: BrowserWindow;
}) => Promise<Response | void>;
/** Hook dispatched before making a sync request. */
beforeSyncRequest?: (context: {
request: Request;
window: BrowserWindow;
}) => ISyncResponse | void;
/** Hook dispatched after receiving an async response. */
afterAsyncResponse?: (context: {
request: Request;
response: Response;
window: BrowserWindow;
}) => Promise<Response | void>;
/** Hook dispatched after receiving a sync response. */
afterSyncResponse?: (context: {
request: Request;
response: ISyncResponse;
window: BrowserWindow;
}) => ISyncResponse | void;
}
interface IVirtualServer {
/** URL pattern to match for virtual server requests */
url: string | RegExp;
/** Directory path to serve files from */
directory: string;
}
interface ISyncResponse {
/** HTTP status code */
status: number;
/** HTTP status text */
statusText: string;
/** Whether the response is successful (status 200-299) */
ok: boolean;
/** Final URL after redirects */
url: string;
/** Whether the response was redirected */
redirected: boolean;
/** Response headers */
headers: Headers;
/** Response body as Buffer */
body: Buffer | null;
}When register() is called, the following properties are typically added to the global object:
document - DOM document objectwindow - Window object (references global)location - Location object for URL manipulationhistory - History object for navigationnavigator - Navigator object with browser infoscreen - Screen object with display infosessionStorage - Session storage APIlocalStorage - Local storage APIcustomElements - Custom Elements registryCSS - CSS-related APIsinnerWidth, innerHeight, outerWidth, outerHeightscrollX, scrollY, pageXOffset, pageYOffsetself, top, parent (all reference global)The GlobalRegistrator throws errors for invalid usage:
try {
GlobalRegistrator.register();
GlobalRegistrator.register(); // Throws: "Failed to register. Happy DOM has already been globally registered."
} catch (error) {
console.error(error.message);
}
try {
await GlobalRegistrator.unregister(); // Throws: "Failed to unregister. Happy DOM has not previously been globally registered."
} catch (error) {
console.error(error.message);
}import { GlobalRegistrator } from '@happy-dom/global-registrator';
// Before tests
GlobalRegistrator.register({
url: 'http://localhost:3000',
width: 1920,
height: 1080
});
// Your tests using DOM APIs...
document.body.innerHTML = '<div>Test content</div>';
const element = document.querySelector('div');
// After tests
await GlobalRegistrator.unregister();GlobalRegistrator.register();
const style = document.createElement('style');
document.head.appendChild(style);
style.innerHTML = `
body {
background-color: red;
}
@media (min-width: 1000px) {
body {
background-color: green;
}
}
`;
// Access computed styles
const computedStyle = globalThis.getComputedStyle(document.body);
console.log(computedStyle.backgroundColor); // "green"
await GlobalRegistrator.unregister();