Skip to content

Commit

Permalink
feat(semantic-dom-diff): diff Scoped Element tags correctly into Shad…
Browse files Browse the repository at this point in the history
…ow DOM snapshots

- Substituted every el.localName call with getLocalName in getDiffableHTML function
- Using data-tag-name instead to retrieve original tag name
- Update readme explanation and examples accordingly
- Adding a test for the new default functionality
  • Loading branch information
Daniel Vivar authored and manolakis committed Sep 11, 2020
1 parent 30df614 commit 4385957
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 3 deletions.
86 changes: 86 additions & 0 deletions packages/semantic-dom-diff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,89 @@ it('renders correctly', async () => {
});
});
```

**[Scoped elements](https://open-wc.org/scoped-elements/)**

You might want to ignore scoped elements when working with _Shadow DOM snapshots_, like so:

```js
import { MyButton } from '@somewhere/my-button';

class MyElement extends ScopedElementsMixin(LitElement) {
static get scopedElements() {
return {
'my-button': MyButton,
};
}
render() {
return html`
<p>Here's my button</p>
<my-button>Hey!</my-button>
`;
}
}

window.customElements.define('my-element', MyElement);

it('renders correctly', async () => {
const el = await fixture(`
<my-custom-element>
</my-custom-element>
`);

expect(el).shadowDom.to.equalSnapshot({
ignoreTags: [el.constructor.getScopedTagName('my-button', el.constructor.scopedElements)],
});
});
```

This example will save the following snapshot:

```html
<my-custom-element>
<p>
Here's my button
</p>
</my-custom-element>
```

However, what if you actually care about testing what goes into scoped elements?

In that case, scoped elements should not be ignored, but diffed in snapshots correctly with their original tag name instead. Our differ will take that into account when making Shadow DOM snapshots, by default. Following the previous example:

```js
it('renders correctly', async () => {
const el = await fixture(`
<my-custom-element>
</my-custom-element>
`);

expect(el).shadowDom.to.equalSnapshot();
});
```

This example will save this snapshot:

```html
<my-custom-element>
<p>
Here's my button
</p>
<my-button data-tag-name="my-button">
Hey!
</my-button>
</my-custom-element>
```

With the actual implementation of scoped elements, without ignoring its tags or if our differ wouldn't check them by default, the test snapshot would be produced with scoped element tags with different random numbers _every time_:

```html
<my-custom-element>
<p>
Here's my button
</p>
<my-button-23443 data-tag-name="my-button">
Hey!
</my-button-23443>
</my-custom-element>
```
13 changes: 10 additions & 3 deletions packages/semantic-dom-diff/get-diffable-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,16 @@ export function getDiffableHTML(html, options = {}) {
return attrStr;
}

/** @param {Element} el */
function getLocalName(el) {
// Use original tag if available via data-tag-name attribute (use-case for scoped elements)
// See packages/scoped-elements for more info
return el.getAttribute('data-tag-name') || el.localName;
}

/** @param {Element} el */
function printOpenElement(el) {
text += `${getIndentation()}<${el.localName}${getAttributesString(el)}>\n`;
text += `${getIndentation()}<${getLocalName(el)}${getAttributesString(el)}>\n`;
}

/** @param {Node} node */
Expand Down Expand Up @@ -207,11 +214,11 @@ export function getDiffableHTML(html, options = {}) {

/** @param {Element} el */
function printCloseElement(el) {
if (el.localName === 'diff-container' || VOID_ELEMENTS.includes(el.localName)) {
if (getLocalName(el) === 'diff-container' || VOID_ELEMENTS.includes(getLocalName(el))) {
return;
}

text += `${getIndentation()}</${el.localName}>\n`;
text += `${getIndentation()}</${getLocalName(el)}>\n`;
}

/** @param {Node} node */
Expand Down
26 changes: 26 additions & 0 deletions packages/semantic-dom-diff/test/get-diffable-html.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,32 @@ describe('getDiffableHTML()', () => {
'</div>\n',
);
});

it('scoped tags', () => {
const html = getDiffableHTML(
`
<scoped-element-123 data-tag-name="scoped-element">
</scoped-element-123>
<scoped-element>
</scoped-element>
<my-element-123>
</my-element-123>
<my-element>
</my-element>
`,
);

expect(html).to.equal(
'<scoped-element data-tag-name="scoped-element">\n' +
'</scoped-element>\n' +
'<scoped-element>\n' +
'</scoped-element>\n' +
'<my-element-123>\n' +
'</my-element-123>\n' +
'<my-element>\n' +
'</my-element>\n',
);
});
});

it('dom node as input', () => {
Expand Down

0 comments on commit 4385957

Please sign in to comment.