@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
165 lines (123 loc) • 5.46 kB
JavaScript
import {
getDocument,
getWindow,
getDocumentFragmentFromString,
waitForCustomElement,
} from "../../../source/dom/util.mjs";
import {getContainingDocument} from "../../../source/dom/util.mjs";
import {initJSDOM} from "../../util/jsdom.mjs";
import {expect} from "chai"
describe('DOM', function () {
before(async function () {
initJSDOM();
})
describe('getDocument()', function () {
it('should return document object', function () {
let d = getDocument();
expect(typeof d).is.equal('object');
});
});
describe('getWindow()', function () {
it('should return document object', function () {
let d = getWindow();
expect(typeof d).is.equal('object');
});
});
describe('getDocumentFragmentFromString()', function () {
[
['<div></div>'],
['<div><div>2</div></div>'],
['<div><div>2</div>', '<div><div>2</div></div>'], // test invalid html
].forEach(function (data) {
let a = data.shift()
let b = data.shift()
if (!b) b = a;
it('should return documentFragment object ' + a, function () {
let fragment = getDocumentFragmentFromString(a);
expect(fragment).to.be.instanceOf(DocumentFragment);
var div = document.createElement('div');
div.appendChild(fragment.cloneNode(true));
expect(div.innerHTML).to.be.equal(b);
});
});
});
describe('getContainingDocument', () => {
let jsDomDocument;
beforeEach(() => {
jsDomDocument = getDocument();
});
//
// afterEach(() => {
// dom.window.close();
// });
it('should throw an error when called with an invalid argument', () => {
expect(() => getContainingDocument(null)).to.throw('Invalid argument. Expected an HTMLElement.');
});
it('should return the correct containing document for an element in the main document', () => {
const element = jsDomDocument.createElement('div');
const containingDocument = getContainingDocument(element);
expect(containingDocument).to.null;
});
it('should return the correct containing document for an element inside a shadow root', () => {
const host = jsDomDocument.createElement('div');
const shadowRoot = host.attachShadow({ mode: 'open' });
const element = jsDomDocument.createElement('span');
shadowRoot.appendChild(element);
const containingDocument = getContainingDocument(element);
expect(containingDocument).to.not.null;
});
it('should return the correct containing document for an element inside a nested shadow root', () => {
const outerHost = jsDomDocument.createElement('div');
const outerShadowRoot = outerHost.attachShadow({ mode: 'open' });
const innerHost = jsDomDocument.createElement('div');
outerShadowRoot.appendChild(innerHost);
const innerShadowRoot = innerHost.attachShadow({ mode: 'open' });
const element = jsDomDocument.createElement('span');
innerShadowRoot.appendChild(element);
const containingDocument = getContainingDocument(element);
expect(containingDocument).to.not.null;
});
it('should return null when the element is not attached to any document', () => {
const detachedElement = jsDomDocument.createElement('div');
detachedElement.remove();
const containingDocument = getContainingDocument(detachedElement);
expect(containingDocument).to.be.null;
});
});
describe('waitForCustomElement()', () => {
it('should resolve for a specific instance once defined', async () => {
const tagName = `test-tabs-${Date.now()}`;
const element = document.createElement(tagName);
document.body.appendChild(element);
const promise = waitForCustomElement(element, { method: 'ping' });
class TestTabs extends HTMLElement {
ping() {
return 'pong';
}
}
customElements.define(tagName, TestTabs);
const ready = await promise;
expect(ready).to.equal(element);
expect(ready.ping()).to.equal('pong');
});
it('should wait for a readyCheck condition', async () => {
const tagName = `test-ready-${Date.now()}`;
const element = document.createElement(tagName);
document.body.appendChild(element);
const promise = waitForCustomElement(element, {
readyCheck: (el) => el.hasAttribute('data-ready'),
});
class TestReady extends HTMLElement {
connectedCallback() {
setTimeout(() => {
this.setAttribute('data-ready', 'true');
}, 0);
}
}
customElements.define(tagName, TestReady);
const ready = await promise;
expect(ready).to.equal(element);
expect(ready.getAttribute('data-ready')).to.equal('true');
});
});
});