try_try_again
try_try_again

Reputation: 1

Front End Unit Tests in Deno Break when DOM is involved. TS2304 [ERROR]: Cannot find name 'HTMLElement'

I'm new to Typescript and Deno (mostly code in JS and Python) and I'm playing with writing front end typecscipt with Deno. I'm trying to use a compositional style I saw in this artlicle. One of my interfaces has an HTMLElement type in it like this:

export default interface HasElement {
  readonly element: HTMLElement;
}

The classes that implement this interface compile, and I can run resulting code in my browser, but if I attempt to run any unit tests using deno test I get an error error: TS2304 [ERROR]: Cannot find name 'HTMLElement'

I've heard that the DOM is not completely implemented in Deno so I guess I'll probably need to rely on mocking or dependency injection to test any code that makes use of this interface.

I know that most testing involving the DOM should be done with end-to-end testing with something like Selenium, but it almost seems inevitable that some of my front end unit tests are going to run the problem of HTMLElements not existing within Deno.

Does anyone have any experience with this issue? What kind of solution should I look into?

EDIT: Here's my tsconfig.json.

{
    "compilerOptions": {
        "lib": [ "dom", "deno.ns" ]
    }
}

Here's the tests that are failing: (I found this deno-dom-wasm library, but I'm not sure if its applicable to what I'm trying to do.)

import {
  DOMParser,
  Element,
} from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";

import FakeBase from "./components/FakeBase/FakeBase.ts";
import LoginOrganism from "./organisms/LoginOrganism/LoginOrganism.ts";
import App from "./App.ts";

Deno.test({
  name: "test App attaches to app div",
  fn: async () => {
    const html = await Deno.readTextFile("./src/index.html");
    const doc = new DOMParser().parseFromString(
      html,
      "text/html",
    )!;
    const appDiv = doc.getElementById("App") as Element;
    const fakeBase = new FakeBase(appDiv);

    const app = new App(fakeBase);
    const appElement = app.base.element;

    assertEquals(appDiv, appElement);
  },
});

Deno.test({
  name: "test Apps first child is LoginOrganism",
  fn: async () => {
    const html = await Deno.readTextFile("./src/index.html");
    const doc = new DOMParser().parseFromString(
      html,
      "text/html",
    )!;
    const appDiv = doc.getElementById("App") as Element;
    const fakeBase = new FakeBase(appDiv);

    const app = new App(fakeBase);

    const first_child = app.children[0] as LoginOrganism;

    assert(
      first_child instanceof LoginOrganism,
      `FIRST CHILD IS ${typeof first_child}`,
    );
  },
});

Upvotes: 0

Views: 765

Answers (2)

Steven Guerrero
Steven Guerrero

Reputation: 1056

Based in your answers below, I can see that you have a tsconfig.json, but you are not using it. Make sure you tell deno to pick the config with the --config flag

That being said, Deno does support using a TypeScript configuration file, though like the rest of Deno, the detection and use of use of a configuration file is not automatic. To use a TypeScript configuration file with Deno, you have to provide a path on the command line

deno run --config ./tsconfig.json main.ts

https://deno.land/manual/typescript/configuration

Upvotes: 0

evelynhathaway
evelynhathaway

Reputation: 1887

Do you have the DOM lib in your tsconfig.json? Deno does not implement the DOM, so you would need the TypeScript lib for types.

tsconfig.json

Partial TypeScript configuration snippet:

{
  // [Existing config ...]
  "compilerOptions": {
    "lib": [
      "dom"
    ]
  }
}

Upvotes: 0

Related Questions