EGamalielGZ
EGamalielGZ•3d ago

document is not defined error while testing preact hooks

Currently I'm developing a preact hooks library. When I try to run a simple test using deno test, it throws me the next error:
error: ReferenceError: document is not defined
error: ReferenceError: document is not defined
Here is the code of the test I'm doing and the deno.json at root and workspace Code:
import { renderHook } from "@testing-library/preact";
import { useFetch } from "@/hooks/use-fetch.ts";
import { expect } from "@std/expect";

Deno.test("Use fetch", () => {
const { result } = renderHook(()=> useFetch("https://jsonplaceholder.typicode.com/todos/1"))
expect(result.current.data).not.toEqual(null);
});
import { renderHook } from "@testing-library/preact";
import { useFetch } from "@/hooks/use-fetch.ts";
import { expect } from "@std/expect";

Deno.test("Use fetch", () => {
const { result } = renderHook(()=> useFetch("https://jsonplaceholder.typicode.com/todos/1"))
expect(result.current.data).not.toEqual(null);
});
deno.json (root)
{
"workspace": [
"./packages/pretch-core",
"./packages/pretch-preact",
"./packages/pretch-react"
],
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"dom.asynciterable",
"deno.ns"
],
"jsx": "react-jsx",
"jsxImportSource": "preact"
},
"lint": {
"rules": {
"include": [
"no-console",
"ban-types",
"camelcase",
"verbatim-module-syntax"
]
}
},
"exclude": [
".git",
".vscode"
],
"imports": {
"@std/expect": "jsr:@std/expect@^1.0.5",
"@testing-library/dom": "npm:@testing-library/dom@^10.4.0"
}
}
{
"workspace": [
"./packages/pretch-core",
"./packages/pretch-preact",
"./packages/pretch-react"
],
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"dom.asynciterable",
"deno.ns"
],
"jsx": "react-jsx",
"jsxImportSource": "preact"
},
"lint": {
"rules": {
"include": [
"no-console",
"ban-types",
"camelcase",
"verbatim-module-syntax"
]
}
},
"exclude": [
".git",
".vscode"
],
"imports": {
"@std/expect": "jsr:@std/expect@^1.0.5",
"@testing-library/dom": "npm:@testing-library/dom@^10.4.0"
}
}
deno.json (workspace)
{
"name": "@prefetch/preact",
"version": "0.1.2",
"tasks": {
"doc": "deno doc --html --name='Pretch' src"
},
"imports": {
"@preact/signals": "npm:@preact/signals@^1.3.0",
"@std/assert": "jsr:@std/assert@1",
"preact": "npm:preact@^10.24.1",
"@/": "./",
"@std/expect": "jsr:@std/expect@^1.0.5",
"@testing-library/preact": "npm:@testing-library/preact@^3.2.4"
},
"exports": {
".": "./mod.ts"
}
}
{
"name": "@prefetch/preact",
"version": "0.1.2",
"tasks": {
"doc": "deno doc --html --name='Pretch' src"
},
"imports": {
"@preact/signals": "npm:@preact/signals@^1.3.0",
"@std/assert": "jsr:@std/assert@1",
"preact": "npm:preact@^10.24.1",
"@/": "./",
"@std/expect": "jsr:@std/expect@^1.0.5",
"@testing-library/preact": "npm:@testing-library/preact@^3.2.4"
},
"exports": {
".": "./mod.ts"
}
}
6 Replies
bartlomieju
bartlomieju•3d ago
@marvinh. can you please take a look?
marvinh.
marvinh.•3d ago
The way the @testing-library/preact works is that it expects to be run inside an environment where a subset of the DOM APIs are available. The idea behind it is that you're asserting against the rendered result. By default, server runtimes don't ship with the DOM API as it's something mostly for users. This means you need to include a library like happy-dom, deno_dom, linkedom or JSDom to polyfill that. Adding any of these libraries and setting up the document global according to their documentation will resolve the issue.
bartlomieju
bartlomieju•3d ago
FYI I opened https://github.com/denoland/deno/pull/26218 to enhance the error with suggestion
GitHub
fix: Add hint for missing document global in terminal error by ba...
This came up on Discord as a question so I thought it's worth adding a hint for this as it might be a common pitfall.
EGamalielGZ
EGamalielGZ•2d ago
Ok, that make sense. In that case, please can you provide an example, or proceed with the PR that @bartlomieju did to help others that know this (in the error message or the documentation) at least as a suggestion?
marvinh.
marvinh.•2d ago
Sure, copy & pasting the example on how to use JSDOM straight out of the readme gives you this:
import { renderHook } from "@testing-library/preact";
import { useFetch } from "@/hooks/use-fetch.ts";
import { expect } from "@std/expect";

+ import { JSDOM } from "npm:jsdom";
+ const { document } = (new JSDOM("")).window;
+ (globalThis as any).document = document;

Deno.test("Use fetch", () => {
const { result } = renderHook(()=> useFetch("https://jsonplaceholder.typicode.com/todos/1"))
expect(result.current.data).not.toEqual(null);
});
import { renderHook } from "@testing-library/preact";
import { useFetch } from "@/hooks/use-fetch.ts";
import { expect } from "@std/expect";

+ import { JSDOM } from "npm:jsdom";
+ const { document } = (new JSDOM("")).window;
+ (globalThis as any).document = document;

Deno.test("Use fetch", () => {
const { result } = renderHook(()=> useFetch("https://jsonplaceholder.typicode.com/todos/1"))
expect(result.current.data).not.toEqual(null);
});
EGamalielGZ
EGamalielGZ•2d ago
Thanks for helping 😄