@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
193 lines (163 loc) • 5.68 kB
JavaScript
import * as chai from "chai";
import { chaiDom } from "../../../util/chai-dom.mjs";
import { initJSDOM } from "../../../util/jsdom.mjs";
let expect = chai.expect;
chai.use(chaiDom);
let ChoiceCards;
function waitForCondition(check, { timeout = 4000, interval = 25 } = {}) {
return new Promise((resolve, reject) => {
const start = Date.now();
const poll = () => {
try {
if (check()) {
resolve();
return;
}
} catch (e) {
reject(e);
return;
}
if (Date.now() - start >= timeout) {
reject(new Error("Timed out while waiting for test condition."));
return;
}
setTimeout(poll, interval);
};
poll();
});
}
describe("ChoiceCards", function () {
before(function (done) {
initJSDOM()
.then(() => {
return import("element-internals-polyfill");
})
.then(() => {
return import("../../../../source/components/form/form.mjs");
})
.then(() => {
return import("../../../../source/components/form/choice-cards.mjs");
})
.then((m) => {
ChoiceCards = m["ChoiceCards"];
done();
})
.catch((e) => done(e));
});
beforeEach(() => {
document.getElementById("mocks").innerHTML = '<div id="test"></div>';
});
afterEach(() => {
document.getElementById("mocks").innerHTML = "";
});
it("creates a custom element instance", function () {
expect(document.createElement("monster-choice-cards")).is.instanceof(
ChoiceCards,
);
});
it("renders choice cards from items", function () {
const cards = document.createElement("monster-choice-cards");
cards.setItems([
{ value: "assets", label: "Project assets", icon: "project-assets" },
{ value: "api", label: "API collection", icon: "api-collection" },
]);
document.getElementById("test").appendChild(cards);
const choices = cards.shadowRoot.querySelectorAll(
'[data-monster-role="choice"]',
);
expect(choices.length).is.equal(2);
expect(choices[0].textContent).contains("Project assets");
expect(choices[1].textContent).contains("API collection");
});
it("renders custom card content from slots", function () {
const cards = document.createElement("monster-choice-cards");
cards.setItems([
{ value: "assets", label: "Project assets", contentSlot: "assets-card" },
{ value: "api", label: "API collection", contentSlot: "api-card" },
{ value: "manual", label: "Manual", contentSlot: "manual-card" },
]);
const assets = document.createElement("span");
assets.slot = "assets-card";
assets.textContent = "Custom assets content";
cards.appendChild(assets);
document.getElementById("test").appendChild(cards);
const choices = cards.shadowRoot.querySelectorAll(
'[data-monster-role="choice"]',
);
expect(choices.length).is.equal(3);
expect(
cards.shadowRoot
.querySelector('[data-choice-value="assets"] slot')
.getAttribute("name"),
).is.equal("assets-card");
});
it("selects a card and emits change events", function (done) {
const cards = document.createElement("monster-choice-cards");
cards.setItems([
{ value: "assets", label: "Project assets" },
{ value: "api", label: "API collection" },
]);
cards.addEventListener("monster-change", (event) => {
expect(event.detail.value).is.equal("api");
expect(cards.value).is.equal("api");
expect(
cards.shadowRoot
.querySelector('[data-choice-value="api"]')
.getAttribute("aria-checked"),
).is.equal("true");
done();
});
document.getElementById("test").appendChild(cards);
cards.shadowRoot.querySelector('[data-choice-value="api"]').click();
});
it("reads from and writes back to a form datasource", async function () {
this.timeout(6000);
document.getElementById("test").innerHTML = `
<monster-datasource-dom id="choice-ds">
<script type="application/json">
[
{
"source": "assets"
}
]
</script>
</monster-datasource-dom>
<monster-form
id="choice-form"
data-monster-option-datasource-selector="#choice-ds"
data-monster-option-mapping-data=""
data-monster-option-mapping-index="0"
>
<monster-choice-cards
id="choice-source"
data-monster-attributes="value path:data.source"
data-monster-bind="path:data.source"
data-monster-options='{
"items": [
{ "value": "assets", "label": "Assets", "contentSlot": "assets-card" },
{ "value": "api", "label": "API", "contentSlot": "api-card" }
]
}'
>
<span slot="assets-card">Assets</span>
<span slot="api-card">API</span>
</monster-choice-cards>
</monster-form>
`;
const datasource = document.getElementById("choice-ds");
const cards = document.getElementById("choice-source");
await waitForCondition(() => cards.value === "assets");
cards.select("api");
await waitForCondition(() => datasource.data?.[0]?.source === "api");
});
it("does not select disabled items", function () {
const cards = document.createElement("monster-choice-cards");
cards.setItems([
{ value: "assets", label: "Project assets" },
{ value: "api", label: "API collection", disabled: true },
]);
document.getElementById("test").appendChild(cards);
cards.select("api");
expect(cards.value).is.equal(null);
});
});