CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jsdom

A JavaScript implementation of many web standards

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

virtual-console.mddocs/api/

Virtual Console

The VirtualConsole class captures both in-page window.console calls and jsdom implementation messages. It provides event-based access to all console output and jsdom-specific error reporting.

Capabilities

VirtualConsole Constructor

Creates a new virtual console with no default behavior.

/**
 * Creates a virtual console instance
 * By default, does nothing - must add event listeners or use forwardTo()
 */
constructor();

Usage Example:

const { JSDOM, VirtualConsole } = require("jsdom");

const virtualConsole = new VirtualConsole();
const dom = new JSDOM(``, { virtualConsole });

// Without listeners or forwardTo(), console output is silent

forwardTo()

Forwards all console output to another console object.

/**
 * Forwards virtual console output to another console
 * @param console - Target console (e.g., Node.js console)
 * @param options - Filtering options for jsdomError events
 * @returns this (for chaining)
 * @throws TypeError if jsdomErrors is not undefined, "none", or an array
 */
forwardTo(console: Console, options?: ForwardOptions): this;

interface ForwardOptions {
  /**
   * Controls which jsdomError events are forwarded
   * - undefined: All jsdomErrors forwarded (default)
   * - "none": No jsdomErrors forwarded
   * - string[]: Only specified error types forwarded
   * @throws TypeError if value is not undefined, "none", or an array
   */
  jsdomErrors?: "none" | Array<"unhandled-exception" | "css-parsing" | "not-implemented" | "resource-loading">;
}

Usage Examples:

const { JSDOM, VirtualConsole } = require("jsdom");

// Forward everything to Node.js console
const virtualConsole = new VirtualConsole();
virtualConsole.forwardTo(console);

const dom = new JSDOM(`
  <script>
    console.log("Hello from the page!");
    console.error("An error occurred");
  </script>
`, {
  runScripts: "dangerously",
  virtualConsole
});
// Output: Hello from the page!
// Output: An error occurred

// Forward console output but suppress jsdom errors
const vc = new VirtualConsole();
vc.forwardTo(console, { jsdomErrors: "none" });

// Forward only specific jsdom error types
const vc2 = new VirtualConsole();
vc2.forwardTo(console, {
  jsdomErrors: ["unhandled-exception", "not-implemented"]
});
// CSS parsing and resource loading errors will not be forwarded

Console Events

The VirtualConsole is an EventEmitter that emits events for all console methods.

/**
 * Listen for console method calls
 * @param event - Console method name
 * @param listener - Event handler receiving console arguments
 */
on(event: ConsoleMethod, listener: (...args: any[]) => void): this;

type ConsoleMethod =
  | "assert"
  | "clear"
  | "count"
  | "countReset"
  | "debug"
  | "dir"
  | "dirxml"
  | "error"
  | "group"
  | "groupCollapsed"
  | "groupEnd"
  | "info"
  | "log"
  | "table"
  | "time"
  | "timeEnd"
  | "timeLog"
  | "trace"
  | "warn";

Usage Example:

const { JSDOM, VirtualConsole } = require("jsdom");

const virtualConsole = new VirtualConsole();

// Listen for specific console methods
virtualConsole.on("error", (...args) => {
  console.error("Page error:", ...args);
});

virtualConsole.on("warn", (...args) => {
  console.warn("Page warning:", ...args);
});

virtualConsole.on("info", (...args) => {
  console.info("Page info:", ...args);
});

virtualConsole.on("log", (...args) => {
  console.log("Page log:", ...args);
});

virtualConsole.on("dir", (obj) => {
  console.log("Page dir:", obj);
});

const dom = new JSDOM(`
  <script>
    console.log("Message", 123);
    console.error("Error message");
    console.warn("Warning");
    console.info("Info");
    console.dir({ foo: "bar" });
  </script>
`, {
  runScripts: "dangerously",
  virtualConsole
});

jsdomError Event

Special event for jsdom implementation errors and warnings.

/**
 * Listen for jsdom-specific errors
 * @param event - Always "jsdomError"
 * @param listener - Error handler
 */
on(event: "jsdomError", listener: (error: JSDOMError) => void): this;

interface JSDOMError {
  /**
   * Type of jsdom error
   */
  type: "css-parsing" | "not-implemented" | "resource-loading" | "unhandled-exception";

  /**
   * Error message
   */
  message: string;

  /**
   * Original exception (for certain error types)
   */
  cause?: Error;

  /**
   * URL of resource (for resource-loading errors)
   */
  url?: string;

  /**
   * CSS stylesheet text (for css-parsing errors)
   */
  sheetText?: string;
}

Error Types:

css-parsing

CSS parsing errors from the CSSOM parser.

{
  type: "css-parsing",
  message: string,
  cause: Error,        // Exception from rrweb-cssom parser
  sheetText: string    // Full text of stylesheet that failed to parse
}

not-implemented

Called when unimplemented web platform methods are invoked.

{
  type: "not-implemented",
  message: string
}

resource-loading

Resource loading failures (network errors, bad response codes).

{
  type: "resource-loading",
  message: string,
  cause: Error,    // Network error from Node.js or custom ResourceLoader
  url: string      // URL that failed to load
}

unhandled-exception

Script execution errors not handled by Window error event listeners.

{
  type: "unhandled-exception",
  message: string,
  cause: Error     // Original exception thrown by script
}

Usage Example:

const { JSDOM, VirtualConsole } = require("jsdom");

const virtualConsole = new VirtualConsole();

// Handle all jsdom errors
virtualConsole.on("jsdomError", (error) => {
  switch (error.type) {
    case "unhandled-exception":
      console.error("Unhandled exception:", error.cause?.stack || error.message);
      break;

    case "css-parsing":
      console.error("CSS parse error:", error.message);
      console.error("CSS content:", error.sheetText);
      break;

    case "resource-loading":
      console.error("Failed to load resource:", error.url);
      console.error("Cause:", error.cause?.message);
      break;

    case "not-implemented":
      console.warn("Not implemented:", error.message);
      break;
  }
});

const dom = new JSDOM(`
  <html>
    <head>
      <style>
        /* Invalid CSS */
        .class {
          color: #invalid-color;
        }
      </style>
      <script src="https://nonexistent.example.com/script.js"></script>
    </head>
    <body>
      <script>
        throw new Error("Unhandled error in script");
      </script>
    </body>
  </html>
`, {
  runScripts: "dangerously",
  resources: "usable",
  virtualConsole
});

Combining forwardTo() and Custom Handlers

You can use both forwardTo() and custom event listeners together.

Usage Example:

const { JSDOM, VirtualConsole } = require("jsdom");

const virtualConsole = new VirtualConsole();

// Forward regular console output to Node.js console
virtualConsole.forwardTo(console, { jsdomErrors: "none" });

// But handle jsdom errors specially
virtualConsole.on("jsdomError", (error) => {
  if (error.type === "unhandled-exception") {
    // Log to error tracking service
    errorTracker.captureException(error.cause);
  }
});

// And capture specific console methods for analysis
const errorLogs = [];
virtualConsole.on("error", (...args) => {
  errorLogs.push({ timestamp: Date.now(), args });
});

const dom = new JSDOM(html, {
  runScripts: "dangerously",
  virtualConsole
});

Default Behavior

If no virtual console is provided to the JSDOM constructor, a default one is created that forwards everything to the Node.js console:

// These are equivalent:
const dom1 = new JSDOM(html);

const virtualConsole = new VirtualConsole();
virtualConsole.forwardTo(console);
const dom2 = new JSDOM(html, { virtualConsole });

Setup Timing

Set up event listeners before creating the JSDOM instance to capture errors that occur during parsing:

const { JSDOM, VirtualConsole } = require("jsdom");

// GOOD: Listeners set up before JSDOM creation
const virtualConsole = new VirtualConsole();
virtualConsole.on("jsdomError", (error) => {
  console.error("Error:", error);
});
const dom = new JSDOM(html, { virtualConsole });

// BAD: Listeners set up after - may miss parsing errors
const dom2 = new JSDOM(html, { virtualConsole: new VirtualConsole() });
dom2.virtualConsole.on("jsdomError", (error) => {
  // May miss errors that occurred during parsing
  console.error("Error:", error);
});

docs

api

cookie-management.md

jsdom-constructor.md

resource-loading.md

virtual-console.md

window-dom-apis.md

index.md

tile.json