diff --git a/CHANGELOG.md b/CHANGELOG.md index e54f28c38b77..e2c3d6f74533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - `[jest-changed-files]` Use `git diff` instead of `git log` for `--changedSince` ([#10155](https://github.com/facebook/jest/pull/10155)) - `[jest-console]` Add missing console.timeLog for compatability with Node ([#10209](https://github.com/facebook/jest/pull/10209)) - `[jest-snapshot]` Strip added indentation for inline error snapshots ([#10217](https://github.com/facebook/jest/pull/10217)) +- `[pretty-print]` Added support for serializing custom elements (web components) ([#10217](https://github.com/facebook/jest/pull/10237)) ### Chore & Maintenance diff --git a/packages/pretty-format/src/__tests__/DOMElement.test.ts b/packages/pretty-format/src/__tests__/DOMElement.test.ts index b5e22f549c40..c913736c1779 100644 --- a/packages/pretty-format/src/__tests__/DOMElement.test.ts +++ b/packages/pretty-format/src/__tests__/DOMElement.test.ts @@ -344,6 +344,47 @@ Testing.`; ); }); + it('supports custom elements', () => { + const customElementCreated = jest.fn(); + class CustomElement extends HTMLElement { + constructor() { + super(); + customElementCreated(); + } + } + + class CustomParagraphElement extends HTMLParagraphElement {} + + class CustomExtendedElement extends CustomElement {} + + customElements.define('custom-element', CustomElement); + customElements.define('custom-extended-element', CustomExtendedElement); + customElements.define('custom-paragraph', CustomParagraphElement, { + extends: 'p', + }); + + const parent = document.createElement('div'); + parent.innerHTML = [ + '', + '', + '

', + ].join(''); + + expect(parent).toPrettyPrintTo( + [ + '
', + ' ', + ' ', + ' ', + '
', + ].join('\n'), + ); + + expect(customElementCreated).toHaveBeenCalled(); + }); + describe('matches constructor name of SVG elements', () => { // Too bad, so sad, element.constructor.name of SVG elements // is HTMLUnknownElement in jsdom v9 and v10 diff --git a/packages/pretty-format/src/plugins/DOMElement.ts b/packages/pretty-format/src/plugins/DOMElement.ts index daf8f9be721f..d4fcef908c29 100644 --- a/packages/pretty-format/src/plugins/DOMElement.ts +++ b/packages/pretty-format/src/plugins/DOMElement.ts @@ -23,17 +23,21 @@ const FRAGMENT_NODE = 11; const ELEMENT_REGEXP = /^((HTML|SVG)\w*)?Element$/; -const testNode = (nodeType: number, name: string) => - (nodeType === ELEMENT_NODE && ELEMENT_REGEXP.test(name)) || - (nodeType === TEXT_NODE && name === 'Text') || - (nodeType === COMMENT_NODE && name === 'Comment') || - (nodeType === FRAGMENT_NODE && name === 'DocumentFragment'); +const testNode = (val: any) => { + const constructorName = val.constructor.name; + const {nodeType} = val; + return ( + (nodeType === ELEMENT_NODE && ELEMENT_REGEXP.test(constructorName)) || + (nodeType === TEXT_NODE && constructorName === 'Text') || + (nodeType === COMMENT_NODE && constructorName === 'Comment') || + (nodeType === FRAGMENT_NODE && constructorName === 'DocumentFragment') || + // eslint-disable-next-line no-undef + val instanceof HTMLElement + ); +}; export const test: NewPlugin['test'] = (val: any) => - val && - val.constructor && - val.constructor.name && - testNode(val.nodeType, val.constructor.name); + val && val.constructor && val.constructor.name && testNode(val); type HandledType = Element | Text | Comment | DocumentFragment;