From 4970c309c96cccf4203dcbc2c389fe9588bd1a07 Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Tue, 22 Nov 2022 15:52:54 -0500 Subject: [PATCH 01/11] working on a real printer --- __tests__/pretty-shadow-dom.test.tsx | 19 +- src/pretty-shadow-dom.ts | 334 +++++++++++++++++++++++---- 2 files changed, 301 insertions(+), 52 deletions(-) diff --git a/__tests__/pretty-shadow-dom.test.tsx b/__tests__/pretty-shadow-dom.test.tsx index ac34d92..49ce2fc 100644 --- a/__tests__/pretty-shadow-dom.test.tsx +++ b/__tests__/pretty-shadow-dom.test.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { render } from "@testing-library/react"; -import { Button, NestedShadowRoots } from "../components"; +import { Button, TripleShadowRoots } from "../components"; import { prettyShadowDOM, screen } from "../src/index"; test("Should strip style and script tags", () => { @@ -28,7 +28,7 @@ test("Should test shadow roots of passing in element", async () => { const str = prettyShadowDOM(button.getRootNode().host) as string; expect(str.includes("my-button")).toBe(true); - expect(str.includes("shadow-root")).toBe(true); + expect(str.includes("#shadowRoot")).toBe(true); expect(str.includes("body")).toBe(false); expect(str.includes("div")).toBe(false); }); @@ -38,8 +38,9 @@ test("Should render body if passed in", () => { const str = prettyShadowDOM(document.body) as string; + console.log(str) expect(str.includes("my-button")).toBe(true); - expect(str.includes("shadow-root")).toBe(true); + expect(str.includes("#shadowRoot")).toBe(true); expect(str.includes("body")).toBe(true); }); @@ -48,7 +49,17 @@ test("Should render HTML tag if passed in", () => { const str = prettyShadowDOM() as string; + console.log(str) expect(str.includes("my-button")).toBe(true); - expect(str.includes("shadow-root")).toBe(true); + expect(str.includes("#shadowRoot")).toBe(true); expect(str.includes("body")).toBe(true); }); + +test("It should render 3 shadow root instances", () => { + render() + const str = prettyShadowDOM() as string + + console.log(str) + + expect(str.includes("#shadowRoot")).toBe(true); +}) diff --git a/src/pretty-shadow-dom.ts b/src/pretty-shadow-dom.ts index c5fe0ae..cdeff4c 100644 --- a/src/pretty-shadow-dom.ts +++ b/src/pretty-shadow-dom.ts @@ -1,75 +1,313 @@ -import { prettyDOM } from "@testing-library/dom"; - /** * This is an extension of prettyDOM / logDOM that provides proper printing of shadow roots. + * Pulled from here: https://github.com/AriPerkkio/aria-live-capture/blob/85f1e4613bec443797097320ed5f2b9f733fc729/.storybook/pretty-dom-with-shadow-dom.ts */ +import { prettyDOM } from "@testing-library/dom"; +import type { Config, NewPlugin, Printer, Refs } from "pretty-format"; +import { getAllElementsAndShadowRoots } from "./deep-query-selectors"; + export function prettyShadowDOM( ...args: Parameters ): ReturnType { - const [element, maxLength, options] = args; - return prettyDOM(toJSDOM(element), maxLength, options); + const [dom, maxLength, options] = args; + + const plugin: NewPlugin = { + test: (val: any) => { + const bool = val?.constructor && testNode(val); + return bool; + }, + serialize, + }; + + return prettyDOM(dom, maxLength, { + ...options, + plugins: [plugin], + filterNode: () => true, + }); } -export function toJSDOM(element?: Element | Document | undefined): HTMLElement { - if (element == null) element = document.documentElement; +function escapeHTML(str: string): string { + return str.replace(//g, ">"); +} - let htmlString: string = ""; +// Return empty string if keys is empty. +function printProps( + keys: Array, + props: Record, + config: Config, + indentation: string, + depth: number, + refs: Refs, + printer: Printer +): string { + const indentationNext = indentation + config.indent; + const colors = config.colors; + return keys + .map((key) => { + const value = props[key]; + let printed = printer(value, config, indentationNext, depth, refs); - if ("outerHTML" in element) { - htmlString = element.outerHTML; - } + if (typeof value !== "string") { + if (printed.indexOf("\n") !== -1) { + printed = + config.spacingOuter + + indentationNext + + printed + + config.spacingOuter + + indentation; + } + printed = "{" + printed + "}"; + } - htmlString = processNodes(element, htmlString); + return ( + config.spacingInner + + indentation + + colors.prop.open + + key + + colors.prop.close + + "=" + + colors.value.open + + printed + + colors.value.close + ); + }) + .join(""); +} - // Remove Comment nodes - htmlString = htmlString.replace(//g, ""); +// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#node_type_constants +const NodeTypeTextNode = 3; - // Remove extraneous whitespace as it creates bloated printing - htmlString = htmlString.replace(/>\s+<"); +// Return empty string if children is empty. +const printChildren = ( + children: Array, + config: Config, + indentation: string, + depth: number, + refs: Refs, + printer: Printer +): string => + children + .map((child) => { + const printedChild = + typeof child === "string" + ? printText(child, config) + : printer(child, config, indentation, depth, refs); - const parser = new DOMParser(); - const dom = parser.parseFromString(htmlString, "text/html"); + if ( + printedChild === "" && + typeof child === "object" && + child !== null && + (child as Node).nodeType !== NodeTypeTextNode + ) { + // A plugin serialized this Node to '' meaning we should ignore it. + return ""; + } + return config.spacingOuter + indentation + printedChild; + }) + .join(""); - if ( - element instanceof Document || - element instanceof HTMLHtmlElement || - element instanceof HTMLBodyElement - ) { - return dom.body; - } +const printText = (text: string, config: Config): string => { + const contentColor = config.colors.content; + return contentColor.open + escapeHTML(text) + contentColor.close; +}; + +const printComment = (comment: string, config: Config): string => { + const commentColor = config.colors.comment; + return ( + commentColor.open + + "" + + commentColor.close + ); +}; + +// Separate the functions to format props, children, and element, +// so a plugin could override a particular function, if needed. +// Too bad, so sad: the traditional (but unnecessary) space +// in a self-closing tagColor requires a second test of printedProps. +const printElement = ( + type: string, + printedProps: string, + printedChildren: string, + hasShadowRoot: boolean, + config: Config, + indentation: string +): string => { + const tagColor = config.colors.tag; + const shadowRootMarkup = hasShadowRoot + ? `${config.spacingOuter + indentation} #shadow-root` + : ""; + + return ( + tagColor.open + + "<" + + type + + (printedProps && + tagColor.close + + printedProps + + config.spacingOuter + + indentation + + tagColor.open) + + (printedChildren + ? ">" + + shadowRootMarkup + + tagColor.close + + printedChildren + + config.spacingOuter + + indentation + + tagColor.open + + "" + + tagColor.close + ); +}; + +const printElementAsLeaf = (type: string, config: Config): string => { + const tagColor = config.colors.tag; + return ( + tagColor.open + + "<" + + type + + tagColor.close + + " …" + + tagColor.open + + " />" + + tagColor.close + ); +}; + +const ELEMENT_NODE = 1; +const TEXT_NODE = 3; +const COMMENT_NODE = 8; +const FRAGMENT_NODE = 11; + +const ELEMENT_REGEXP = /^((HTML|SVG)\w*)?Element$/; + +const testNode = (val: any) => { + const constructorName = val.constructor.name; + const { nodeType, tagName } = val; + const isCustomElement = + (typeof tagName === "string" && tagName.includes("-")) || + (typeof val.hasAttribute === "function" && val.hasAttribute("is")); + + return ( + (nodeType === ELEMENT_NODE && + (ELEMENT_REGEXP.test(constructorName) || isCustomElement)) || + (nodeType === TEXT_NODE && constructorName === "Text") || + (nodeType === COMMENT_NODE && constructorName === "Comment") || + (nodeType === FRAGMENT_NODE && constructorName === "DocumentFragment") + ); +}; + +type HandledType = Element | Text | Comment | DocumentFragment; - return dom.body.firstElementChild as HTMLElement; +function nodeIsText(node: HandledType): node is Text { + return node.nodeType === TEXT_NODE; } -function processNodes( - element: Element | Document | ShadowRoot, - stringBuffer: string = "", - nodes: Array = Array.from(element.children) -) { - if ("shadowRoot" in element && element.shadowRoot != null) { - nodes.unshift(element.shadowRoot); +function nodeIsComment(node: HandledType): node is Comment { + return node.nodeType === COMMENT_NODE; +} + +function nodeIsFragment(node: HandledType): node is DocumentFragment { + return node.nodeType === FRAGMENT_NODE; +} + +function serialize( + node: HandledType, + config: Config, + indentation: string, + depth: number, + refs: Refs, + printer: Printer +): string { + if (nodeIsText(node)) { + return printText(node.data, config); + } + + if (nodeIsComment(node)) { + return printComment(node.data, config); } - nodes.unshift(element); + const type = nodeIsFragment(node) + ? `DocumentFragment` + : node.tagName.toLowerCase(); - while (nodes.length > 0) { - const node = nodes.shift()!; - if (node && "shadowRoot" in node && node.shadowRoot != null) { - const outerHTML = node.outerHTML; + if (++depth > config.maxDepth) { + return printElementAsLeaf(type, config); + } - const shadowRootPseudoNode = document.createElement("shadow-root"); - shadowRootPseudoNode.innerHTML = node.shadowRoot.innerHTML; + const children = printChildren( + getChildren(node), + config, + indentation + config.indent, + depth, + refs, + printer + ); - const clonedNode = node.cloneNode(true) as Element; - clonedNode.insertAdjacentElement("afterbegin", shadowRootPseudoNode); + const hasShadowRoot = "shadowRoot" in node && node.shadowRoot != null; - stringBuffer = stringBuffer.replace(outerHTML, clonedNode.outerHTML); + return printElement( + type, + printProps( + nodeIsFragment(node) + ? [] + : Array.from(node.attributes) + .map((attr) => attr.name) + .sort(), + nodeIsFragment(node) + ? {} + : Array.from(node.attributes).reduce>( + (props, attribute) => { + props[attribute.name] = attribute.value; + return props; + }, + {} + ), + config, + indentation + config.indent, + depth, + refs, + printer + ), + children, + hasShadowRoot, + config, + indentation + ); +} - stringBuffer = stringBuffer.replace(outerHTML, node.outerHTML); - nodes.push(...Array.from(node.shadowRoot.children)); - } - nodes.push(...Array.from(node.children)); - } +function getChildren(node: Element | DocumentFragment, filterNode = () => true): Node[] { + return getAllChildNodes(node).filter(filterNode) +} + +function getAllChildNodes (node: Node | ShadowRoot | Element | DocumentFragment, finalNodes: (Node | Element)[] = []): Node[] { + const nodes = getChildNodes(node) + + nodes.forEach((childNode) => { + if (node == null) return + + finalNodes.push(childNode) + + if ("shadowRoot" in childNode && childNode.shadowRoot != null && childNode.shadowRoot.mode === "open") { + getAllChildNodes(childNode.shadowRoot, finalNodes) + } + + getAllChildNodes(childNode, finalNodes) + }) + + + return finalNodes as Node[] +} + +function getChildNodes (node: Element | Node): (Node | Element)[] { + if ("children" in node) { + return Array.prototype.slice.call(node.childNodes || node.children) + } - return stringBuffer; + return Array.prototype.slice.call(node.childNodes) } From 0b153dc8fe43d89fc6015658d8647b584af289d3 Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Sun, 27 Nov 2022 12:30:32 -0500 Subject: [PATCH 02/11] we feel real close --- __tests__/pretty-shadow-dom.test.tsx | 46 ++-- src/pretty-shadow-dom.ts | 350 +++++++++++++-------------- 2 files changed, 197 insertions(+), 199 deletions(-) diff --git a/__tests__/pretty-shadow-dom.test.tsx b/__tests__/pretty-shadow-dom.test.tsx index 49ce2fc..cca3427 100644 --- a/__tests__/pretty-shadow-dom.test.tsx +++ b/__tests__/pretty-shadow-dom.test.tsx @@ -1,17 +1,22 @@ import * as React from "react"; -import { render } from "@testing-library/react"; +import { prettyDOM, render } from "@testing-library/react"; import { Button, TripleShadowRoots } from "../components"; import { prettyShadowDOM, screen } from "../src/index"; test("Should strip style and script tags", () => { const div = document.createElement("div"); - div.innerHTML = ` - - - -
Hi
- `; - const str = prettyShadowDOM(div) as string; + + const comment = document.createComment("Comment") + const style = document.createElement("style") + style.innerHTML = `style {}` + const script = document.createElement("script") + script.innerHTML = `const script = null` + const otherDiv = document.createElement("div") + otherDiv.innerHTML = "Hi" + + div.append(comment, style, script, otherDiv) + + const str = prettyDOM(div) as string; expect(str.includes("Comment")).toBe(false); expect(str.includes("style")).toBe(false); @@ -25,10 +30,11 @@ test("Should test shadow roots of passing in element", async () => { const button = await screen.findByShadowRole("button"); // @ts-expect-error - const str = prettyShadowDOM(button.getRootNode().host) as string; + let str = prettyShadowDOM(button.getRootNode().host) as string; + expect(str.includes("my-button")).toBe(true); - expect(str.includes("#shadowRoot")).toBe(true); + expect(str.includes("ShadowRoot")).toBe(true); expect(str.includes("body")).toBe(false); expect(str.includes("div")).toBe(false); }); @@ -38,22 +44,22 @@ test("Should render body if passed in", () => { const str = prettyShadowDOM(document.body) as string; - console.log(str) + // console.log(str) expect(str.includes("my-button")).toBe(true); - expect(str.includes("#shadowRoot")).toBe(true); + expect(str.includes("ShadowRoot")).toBe(true); expect(str.includes("body")).toBe(true); }); -test("Should render HTML tag if passed in", () => { - render( +  + 0 + " + `) }); test("Should render body if passed in", () => { @@ -47,10 +54,24 @@ test("Should render body if passed in", () => { const str = prettyShadowDOM(document.body) as string; - // console.log(str) expect(str.includes("my-button")).toBe(true); expect(str.includes("ShadowRoot")).toBe(true); expect(str.includes("body")).toBe(true); + + expect(str).toMatchInlineSnapshot(` + " + 
 +  +  +  +  + 0 +  + 
 + " + `) }); test("Should render HTML tag if passed in", () => { @@ -61,12 +82,86 @@ test("Should render HTML tag if passed in", () => { expect(str.includes("my-button")).toBe(true); expect(str.includes("ShadowRoot")).toBe(true); expect(str.includes("body")).toBe(true); + + expect(str).toMatchInlineSnapshot(` + " + 
 +  +  +  +  + 0 +  + 
 + " + `) }); test("It should render 3 shadow root instances", () => { render(); const str = prettyShadowDOM() as string; - // console.log(str) expect(str.includes("ShadowRoot")).toBe(true); + + expect(str).toMatchInlineSnapshot(` + " + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  + 
 + 
 +  +  + 
 +  +  + 
 +  +  + 
 + 
 + 
 + " + `) }); From beb40f4b4187d57ed8ac5b26915537aed03e0a0f Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 28 Nov 2022 09:49:02 -0500 Subject: [PATCH 08/11] add inline snapshots --- __tests__/screenDebug.test.tsx | 249 ++++++++++++++++++++++++++------- src/log-shadow-dom.ts | 14 +- src/pretty-shadow-dom.ts | 13 +- 3 files changed, 216 insertions(+), 60 deletions(-) diff --git a/__tests__/screenDebug.test.tsx b/__tests__/screenDebug.test.tsx index dec9ed7..91f6912 100644 --- a/__tests__/screenDebug.test.tsx +++ b/__tests__/screenDebug.test.tsx @@ -8,12 +8,12 @@ import { import { prettyShadowDOM, screen } from "../src/index"; beforeEach(() => { - // jest.spyOn(console, 'log').mockImplementation(() => {}) + jest.spyOn(console, 'log').mockImplementation(() => {}) }); afterEach(() => { - // // @ts-expect-error - // console.log.mockRestore() + // @ts-expect-error + console.log.mockRestore() }); /* @see https://github.com/KonnorRogers/shadow-dom-testing-library/issues/33#issuecomment-1306593757 */ @@ -28,19 +28,148 @@ test("Should not modify the original dom", () => { expect(originalHTML).toEqual(document.body.innerHTML); }); -test.skip("Triple shadow roots", async () => { +test("Triple shadow roots", async () => { render(); screen.debug(); + expect(console.log).toHaveBeenCalledTimes(1) + + // @ts-expect-error + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` + " + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  + 
 + 
 +  +  + 
 +  +  + 
 +  +  + 
 + 
 + 
 +  + + /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 + 13 | + 14 | if (options == null) options = {} + > 15 | + | ^ + " + `) }); -test.skip("Double shadow root", async () => { +test("Double shadow root", async () => { render(); screen.debug(); + + expect(console.log).toHaveBeenCalledTimes(1) + + // @ts-expect-error + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` + " + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  + 
 + 
 +  +  + 
 + 
 + 
 +  + + /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 + 13 | + 14 | if (options == null) options = {} + > 15 | + | ^ + " + `) }); -test.skip("Single shadow root", async () => { +test("Single shadow root", async () => { render(
Start Slot
@@ -49,50 +178,70 @@ test.skip("Single shadow root", async () => {
); - // jest.spyOn(console, 'log').mockImplementation(() => { }) - screen.debug(); - // @TODO: this is supposed to work but doesnt... - // https://github.com/testing-library/dom-testing-library/blob/edffb7c5ec2e4afd7f6bedf842c669ddbfb73297/src/__tests__/pretty-dom.js#L61 - // expect(console.log).toHaveBeenCalledTimes(1) - // expect(console.log.mock.calls[0][0]).toEqual(` - // - //
- // - // - // - // - //
- // - //
- // - // - //
- //
- // Start Slot - //
- //
- // Default Slot - //
- //
- // End Slot - //
- //
- //
- // - // `) - // jest.resetAllMocks() + expect(console.log).toHaveBeenCalledTimes(1) + + // @ts-expect-error + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` + " + 
 +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  + 
 +  + Start Slot + 
 + 
 + Default Slot + 
 +  + End Slot +  +  +  +  + + /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 + 13 | + 14 | if (options == null) options = {} + > 15 | + | ^ + " + `) }); diff --git a/src/log-shadow-dom.ts b/src/log-shadow-dom.ts index e30d361..d76e501 100644 --- a/src/log-shadow-dom.ts +++ b/src/log-shadow-dom.ts @@ -1,9 +1,21 @@ import { logDOM } from "@testing-library/dom"; +import { createDOMElementFilter, filterCommentsAndDefaultIgnoreTagsTags } from "./pretty-shadow-dom"; +import type { NewPlugin } from "pretty-format"; export function logShadowDOM( ...args: Parameters ): ReturnType { - const [dom, maxLength, options] = args; + let [dom, maxLength, options] = args; + + const plugin: NewPlugin = createDOMElementFilter( + options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags + ); + + if (options == null) options = {} + + if (options.plugins == null) options.plugins = [] + + options.plugins.push(plugin) logDOM(dom, maxLength, options); } diff --git a/src/pretty-shadow-dom.ts b/src/pretty-shadow-dom.ts index c8db17c..03af677 100644 --- a/src/pretty-shadow-dom.ts +++ b/src/pretty-shadow-dom.ts @@ -10,15 +10,10 @@ export function prettyShadowDOM( options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags ); - if (options?.plugins) { - options.plugins.push(plugin); - } else { - if (options == null) { - options = {}; - } + if (options == null) options = {} + if (options.plugins == null) options.plugins = [] - options.plugins = [plugin]; - } + options.plugins.push(plugin); return prettyDOM(dom, maxLength, { ...options, @@ -30,7 +25,7 @@ function escapeHTML(str: string): string { return str.replace(//g, ">"); } -function filterCommentsAndDefaultIgnoreTagsTags(value: Node) { +export function filterCommentsAndDefaultIgnoreTagsTags(value: Node) { return ( value.nodeType !== COMMENT_NODE && (value.nodeType !== ELEMENT_NODE || From 9f5b13e6acd6ffa1ddca4cc3179275c514efb19d Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 28 Nov 2022 10:16:06 -0500 Subject: [PATCH 09/11] add inline snapshots --- __tests__/pretty-shadow-dom.test.tsx | 15 +- __tests__/screenDebug.test.tsx | 211 ++------------------------- src/log-shadow-dom.ts | 3 - 3 files changed, 29 insertions(+), 200 deletions(-) diff --git a/__tests__/pretty-shadow-dom.test.tsx b/__tests__/pretty-shadow-dom.test.tsx index 7a7b23e..90696b1 100644 --- a/__tests__/pretty-shadow-dom.test.tsx +++ b/__tests__/pretty-shadow-dom.test.tsx @@ -1,8 +1,21 @@ import * as React from "react"; import { prettyDOM, render } from "@testing-library/react"; -import { Button, TripleShadowRoots } from "../components"; +import { Button, Duplicates, TripleShadowRoots } from "../components"; import { prettyShadowDOM, screen } from "../src/index"; +/* @see https://github.com/KonnorRogers/shadow-dom-testing-library/issues/33#issuecomment-1306593757 */ +test("Should not modify the original dom", () => { + render(); + const originalHTML = document.body.innerHTML; + expect(document.querySelector("shadow-root")).toBe(null); + + prettyShadowDOM(document.body); + + expect(document.querySelector("shadow-root")).toBe(null); + expect(originalHTML).toEqual(document.body.innerHTML); +}); + + test("Should strip style and script tags", () => { const div = document.createElement("div"); diff --git a/__tests__/screenDebug.test.tsx b/__tests__/screenDebug.test.tsx index 91f6912..a6a8423 100644 --- a/__tests__/screenDebug.test.tsx +++ b/__tests__/screenDebug.test.tsx @@ -1,14 +1,25 @@ import React from "react"; +import { getUserCodeFrame } from "@testing-library/dom/dist/get-user-code-frame" import { render } from "@testing-library/react"; import { Duplicates, NestedShadowRoots, TripleShadowRoots, } from "../components"; -import { prettyShadowDOM, screen } from "../src/index"; +import { screen } from "../src/index"; + beforeEach(() => { jest.spyOn(console, 'log').mockImplementation(() => {}) + jest.mocked(getUserCodeFrame).mockImplementation( + () => `"/home/konnor/projects/sample-error/error-example.js:7:14 + 5 | document.createTextNode('Hello World!') + 6 | ) + > 7 | screen.debug() + | ^ + " + ` + ) }); afterEach(() => { @@ -16,18 +27,6 @@ afterEach(() => { console.log.mockRestore() }); -/* @see https://github.com/KonnorRogers/shadow-dom-testing-library/issues/33#issuecomment-1306593757 */ -test("Should not modify the original dom", () => { - render(); - const originalHTML = document.body.innerHTML; - expect(document.querySelector("shadow-root")).toBe(null); - - prettyShadowDOM(document.body); - - expect(document.querySelector("shadow-root")).toBe(null); - expect(originalHTML).toEqual(document.body.innerHTML); -}); - test("Triple shadow roots", async () => { render(); @@ -35,72 +34,7 @@ test("Triple shadow roots", async () => { expect(console.log).toHaveBeenCalledTimes(1) // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` - " - 
 -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  - 
 - 
 -  -  - 
 -  -  - 
 -  -  - 
 - 
 - 
 -  - - /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 - 13 | - 14 | if (options == null) options = {} - > 15 | - | ^ - " - `) + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() }); test("Double shadow root", async () => { @@ -111,62 +45,7 @@ test("Double shadow root", async () => { expect(console.log).toHaveBeenCalledTimes(1) // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` - " - 
 -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  - 
 - 
 -  -  - 
 - 
 - 
 -  - - /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 - 13 | - 14 | if (options == null) options = {} - > 15 | - | ^ - " - `) + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() }); test("Single shadow root", async () => { @@ -183,65 +62,5 @@ test("Single shadow root", async () => { expect(console.log).toHaveBeenCalledTimes(1) // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(` - " - 
 -  -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  - 
 -  - Start Slot - 
 - 
 - Default Slot - 
 -  - End Slot -  -  -  -  - - /Users/konnorrogers/projects/oss/shadow-dom-testing-library/src/log-shadow-dom.ts:15:25 - 13 | - 14 | if (options == null) options = {} - > 15 | - | ^ - " - `) + expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() }); diff --git a/src/log-shadow-dom.ts b/src/log-shadow-dom.ts index d76e501..a04e534 100644 --- a/src/log-shadow-dom.ts +++ b/src/log-shadow-dom.ts @@ -10,11 +10,8 @@ export function logShadowDOM( const plugin: NewPlugin = createDOMElementFilter( options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags ); - if (options == null) options = {} - if (options.plugins == null) options.plugins = [] - options.plugins.push(plugin) logDOM(dom, maxLength, options); From 8a06ca3bb2d2d51b2691a08d20bcedf8bcd024bb Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 28 Nov 2022 10:36:42 -0500 Subject: [PATCH 10/11] finish work on a real print --- __tests__/screenDebug.test.tsx | 29 +++-------------------------- src/log-shadow-dom.ts | 1 + 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/__tests__/screenDebug.test.tsx b/__tests__/screenDebug.test.tsx index a6a8423..34365ff 100644 --- a/__tests__/screenDebug.test.tsx +++ b/__tests__/screenDebug.test.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { getUserCodeFrame } from "@testing-library/dom/dist/get-user-code-frame" import { render } from "@testing-library/react"; import { Duplicates, @@ -8,18 +7,9 @@ import { } from "../components"; import { screen } from "../src/index"; - beforeEach(() => { jest.spyOn(console, 'log').mockImplementation(() => {}) - jest.mocked(getUserCodeFrame).mockImplementation( - () => `"/home/konnor/projects/sample-error/error-example.js:7:14 - 5 | document.createTextNode('Hello World!') - 6 | ) - > 7 | screen.debug() - | ^ - " - ` - ) + jest.spyOn(screen, 'debug') }); afterEach(() => { @@ -32,20 +22,6 @@ test("Triple shadow roots", async () => { screen.debug(); expect(console.log).toHaveBeenCalledTimes(1) - - // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() -}); - -test("Double shadow root", async () => { - render(); - - screen.debug(); - - expect(console.log).toHaveBeenCalledTimes(1) - - // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() }); test("Single shadow root", async () => { @@ -61,6 +37,7 @@ test("Single shadow root", async () => { expect(console.log).toHaveBeenCalledTimes(1) + // This is kind of a silly testing, but its more about making sure we properly loaded our plugin. // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot() + expect(console.log.mock.calls[0][0]).toMatch(/ShadowRoot/) }); diff --git a/src/log-shadow-dom.ts b/src/log-shadow-dom.ts index a04e534..a05bc0b 100644 --- a/src/log-shadow-dom.ts +++ b/src/log-shadow-dom.ts @@ -10,6 +10,7 @@ export function logShadowDOM( const plugin: NewPlugin = createDOMElementFilter( options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags ); + if (options == null) options = {} if (options.plugins == null) options.plugins = [] options.plugins.push(plugin) From 5926bc01eb66a7c06ef28bbb32dec17ca965c109 Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 28 Nov 2022 11:02:19 -0500 Subject: [PATCH 11/11] prettier --- __tests__/pretty-shadow-dom.test.tsx | 9 ++++----- __tests__/screenDebug.test.tsx | 14 +++++++------- src/log-shadow-dom.ts | 11 +++++++---- src/pretty-shadow-dom.ts | 4 ++-- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/__tests__/pretty-shadow-dom.test.tsx b/__tests__/pretty-shadow-dom.test.tsx index 90696b1..7f657ce 100644 --- a/__tests__/pretty-shadow-dom.test.tsx +++ b/__tests__/pretty-shadow-dom.test.tsx @@ -15,7 +15,6 @@ test("Should not modify the original dom", () => { expect(originalHTML).toEqual(document.body.innerHTML); }); - test("Should strip style and script tags", () => { const div = document.createElement("div"); @@ -59,7 +58,7 @@ test("Should test shadow roots of passing in element", async () => {  0 " - `) + `); }); test("Should render body if passed in", () => { @@ -84,7 +83,7 @@ test("Should render body if passed in", () => {   " - `) + `); }); test("Should render HTML tag if passed in", () => { @@ -109,7 +108,7 @@ test("Should render HTML tag if passed in", () => {   " - `) + `); }); test("It should render 3 shadow root instances", () => { @@ -176,5 +175,5 @@ test("It should render 3 shadow root instances", () => {   " - `) + `); }); diff --git a/__tests__/screenDebug.test.tsx b/__tests__/screenDebug.test.tsx index 34365ff..af4f6e3 100644 --- a/__tests__/screenDebug.test.tsx +++ b/__tests__/screenDebug.test.tsx @@ -8,20 +8,20 @@ import { import { screen } from "../src/index"; beforeEach(() => { - jest.spyOn(console, 'log').mockImplementation(() => {}) - jest.spyOn(screen, 'debug') + jest.spyOn(console, "log").mockImplementation(() => {}); + jest.spyOn(screen, "debug"); }); afterEach(() => { // @ts-expect-error - console.log.mockRestore() + console.log.mockRestore(); }); test("Triple shadow roots", async () => { render(); screen.debug(); - expect(console.log).toHaveBeenCalledTimes(1) + expect(console.log).toHaveBeenCalledTimes(1); }); test("Single shadow root", async () => { @@ -35,9 +35,9 @@ test("Single shadow root", async () => { screen.debug(); - expect(console.log).toHaveBeenCalledTimes(1) + expect(console.log).toHaveBeenCalledTimes(1); - // This is kind of a silly testing, but its more about making sure we properly loaded our plugin. + // This is kind of a silly testing, but its more about making sure we properly loaded our plugin. // @ts-expect-error - expect(console.log.mock.calls[0][0]).toMatch(/ShadowRoot/) + expect(console.log.mock.calls[0][0]).toMatch(/ShadowRoot/); }); diff --git a/src/log-shadow-dom.ts b/src/log-shadow-dom.ts index a05bc0b..20fa5c3 100644 --- a/src/log-shadow-dom.ts +++ b/src/log-shadow-dom.ts @@ -1,5 +1,8 @@ import { logDOM } from "@testing-library/dom"; -import { createDOMElementFilter, filterCommentsAndDefaultIgnoreTagsTags } from "./pretty-shadow-dom"; +import { + createDOMElementFilter, + filterCommentsAndDefaultIgnoreTagsTags, +} from "./pretty-shadow-dom"; import type { NewPlugin } from "pretty-format"; export function logShadowDOM( @@ -11,9 +14,9 @@ export function logShadowDOM( options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags ); - if (options == null) options = {} - if (options.plugins == null) options.plugins = [] - options.plugins.push(plugin) + if (options == null) options = {}; + if (options.plugins == null) options.plugins = []; + options.plugins.push(plugin); logDOM(dom, maxLength, options); } diff --git a/src/pretty-shadow-dom.ts b/src/pretty-shadow-dom.ts index 03af677..713680e 100644 --- a/src/pretty-shadow-dom.ts +++ b/src/pretty-shadow-dom.ts @@ -10,8 +10,8 @@ export function prettyShadowDOM( options?.filterNode || filterCommentsAndDefaultIgnoreTagsTags ); - if (options == null) options = {} - if (options.plugins == null) options.plugins = [] + if (options == null) options = {}; + if (options.plugins == null) options.plugins = []; options.plugins.push(plugin);