From e94c651aeae264da206365efa77b17f12a14d682 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Fri, 11 Oct 2019 14:10:22 -0700 Subject: [PATCH] feat: add browser context to server tests, improve errors --- src/__tests__/render.server.ts | 24 ++++++++++++++---------- src/index.ts | 5 +++++ src/shared.ts | 10 ++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/__tests__/render.server.ts b/src/__tests__/render.server.ts index e33716b..2d7cf7f 100644 --- a/src/__tests__/render.server.ts +++ b/src/__tests__/render.server.ts @@ -4,20 +4,24 @@ import LegacyCounter from "./fixtures/legacy-counter"; import Clickable from "./fixtures/clickable.marko"; import HelloName from "./fixtures/hello-name.marko"; -test("renders static content in a document without a browser context", async () => { +test("renders static content in a document with a browser context", async () => { const { getByText } = await render(Counter); - expect(getByText("Value: 0")).toHaveProperty( - ["ownerDocument", "defaultView"], - null - ); + expect( + expect(getByText("Value: 0")).toHaveProperty([ + "ownerDocument", + "defaultView" + ]) + ).not.toBeNull(); }); test("renders static content from a Marko 3 component", async () => { const { getByText } = await render(LegacyCounter); - expect(getByText("Value: 0")).toHaveProperty( - ["ownerDocument", "defaultView"], - null - ); + expect( + expect(getByText("Value: 0")).toHaveProperty([ + "ownerDocument", + "defaultView" + ]) + ).not.toBeNull(); }); test("fails when rerendering", async () => { @@ -41,6 +45,6 @@ test("fails when emitting events", async () => { await expect( fireEvent.click(getByText("Increment")) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unable to find the \\"window\\" object for the given node. fireEvent currently supports firing events on DOM nodes, document, and window. Please file an issue with the code that's causing you to see this error: https://github.com/testing-library/dom-testing-library/issues/new"` + `"Cannot fire events when testing on the server side. Please use @marko/testing-library in a browser environment."` ); }); diff --git a/src/index.ts b/src/index.ts index d5e103b..5ff732d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,7 +27,12 @@ export async function render( ) ) ); + + const { + window: { document } + } = new JSDOM(); const container = JSDOM.fragment(html); + document.adoptNode(container); (container as any).outerHTML = html; // Fixes prettyDOM for container return { diff --git a/src/shared.ts b/src/shared.ts index 418cf92..4bf3b62 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -45,6 +45,7 @@ export type FireObject = { }; export const fireEvent = (async (...params) => { + failIfNoWindow(); originalFireEvent(...params); await wait(); }) as FireFunction & FireObject; @@ -52,6 +53,7 @@ export const fireEvent = (async (...params) => { Object.keys(originalFireEvent).forEach((eventName: EventType) => { const fire = originalFireEvent[eventName]; fireEvent[eventName] = async (...params) => { + failIfNoWindow(); fire(...params); // TODO: this waits for a possible update using setTimeout(0) which should @@ -66,3 +68,11 @@ export type AsyncReturnValue< > = Parameters< NonNullable["then"]>[0]> >[0]; + +function failIfNoWindow() { + if (typeof window === "undefined") { + throw new Error( + "Cannot fire events when testing on the server side. Please use @marko/testing-library in a browser environment." + ); + } +}