Skip to content

Commit

Permalink
[bugfix] 10226 - pretty-print not handling web components properly
Browse files Browse the repository at this point in the history
--added support for properly serializing/printing custom elements by pretty-print
  • Loading branch information
Maksym Cierżniak committed Jul 3, 2020
1 parent f7697e7 commit 58d47b7
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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/123))

### Chore & Maintenance

Expand Down
41 changes: 41 additions & 0 deletions packages/pretty-format/src/__tests__/DOMElement.test.ts
Expand Up @@ -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 = [
'<custom-element></custom-element>',
'<custom-extended-element></custom-extended-element>',
'<p is="custom-paragraph"></p>',
].join('');

expect(parent).toPrettyPrintTo(
[
'<div>',
' <custom-element />',
' <custom-extended-element />',
' <p',
' is="custom-paragraph"',
' />',
'</div>',
].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
Expand Down
22 changes: 13 additions & 9 deletions packages/pretty-format/src/plugins/DOMElement.ts
Expand Up @@ -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;

Expand Down

0 comments on commit 58d47b7

Please sign in to comment.