EGamalielGZ
EGamalielGZ•2mo 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•2mo ago
@marvinh. can you please take a look?
marvinh.
marvinh.•2mo 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•2mo 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
EGamalielGZOP•2mo 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.•2mo 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
EGamalielGZOP•2mo ago
Thanks for helping 😄