import {
render,
user,
getFormValues,
select,
expect,
describe,
it,
waitForEvent,
queryByRole,
trapEvents,
} from "../../utils/Test";
const getNth = (within: Element, nth: number) =>
select(within, `uwc-input:nth-child(${nth})`);
const getInput = (within: Element) => getNth(within, 1);
describe("uwc-input[type=radio]", () => {
it("should be possible to check by clicking on it", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.click(input);
expect(input.checked).to.eq(true);
});
it("should set [aria-checked] appropriately", () => {
const page = render();
const input = select(page, "uwc-input");
expect(input).to.have.attribute("aria-checked", "false");
input.checked = true;
expect(input).to.have.attribute("aria-checked", "true");
});
it("should not be possible to uncheck by clicking it again", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.click(input);
expect(input.checked).to.eq(true);
await user.click(input);
expect(input.checked).to.eq(true);
});
it("should be possible to uncheck by calling .clear()", () => {
const page = render(
,
);
const form = select(page, "form");
const input = select(page, "uwc-input");
expect(getFormValues(form)).to.deep.eq({ foo: "on" });
input.clear();
expect(getFormValues(form)).to.deep.eq({});
expect(input).to.include({ checked: false });
});
it("should uncheck other radio boxes with the same name", () => {
const page = render(
<>
>,
);
const first = select(page, "uwc-input:first-child");
const second = select(page, "uwc-input:last-child");
second.checked = true;
expect(first.checked).to.be.false;
expect(second.checked).to.be.true;
});
it("should still work if names include special characters except quotes", () => {
const page = render(
<>
>,
);
const first = select(page, "uwc-input:first-child");
const second = select(page, "uwc-input:last-child");
second.checked = true;
expect(first.checked).to.be.false;
expect(second.checked).to.be.true;
});
it("should not uncheck other radio boxes with the same name in a different form", () => {
const page = render(
<>
>,
);
const formA = select(page, "form:first-child");
const firstA = select(formA, "uwc-input:first-child");
const secondA = select(formA, "uwc-input:last-child");
const formB = select(page, "form:last-child");
const firstB = select(formB, "uwc-input:first-child");
const secondB = select(formB, "uwc-input:last-child");
secondB.checked = true;
expect(firstA.checked).to.be.true;
expect(secondA.checked).to.be.false;
expect(firstB.checked).to.be.false;
expect(secondB.checked).to.be.true;
});
it("should add its value to formdata", () => {
const page = render(
,
);
expect(getFormValues(select(page, "form"))).to.deep.eq({
foo: "A",
});
});
it("should add update formdata on re-select", async () => {
const page = render(
,
);
// click on second should set second value in form
const secondFormRadio = select(page, "uwc-input[value=baz]");
await user.click(secondFormRadio);
expect(getFormValues(select(page, "form"))).to.deep.eq({
foo: "baz",
});
// click on first should set first value in form
const firstFormRadio = select(page, "uwc-input[value=bar]");
await user.click(firstFormRadio);
expect(getFormValues(select(page, "form"))).to.deep.eq({
foo: "bar",
});
// now, re-selecting second should set second again
await user.click(secondFormRadio);
expect(getFormValues(select(page, "form"))).to.deep.eq({
foo: "baz",
});
});
it("should add 'on' to formdata when no value is specified", () => {
const page = render(
,
);
expect(getFormValues(select(page, "form"))).to.deep.eq({
foo: "on",
});
});
it("should set initially specified [checked] states to false on all but last if multiple exist", () => {
const page = render(
<>
>,
);
expect(getNth(page, 1)).to.include({ checked: false });
expect(getNth(page, 2)).to.include({ checked: false });
expect(getNth(page, 3)).to.include({ checked: true });
});
describe("change classes", () => {
it("should have class .pristine initially", () => {
const page = render();
expect(getInput(page)).to.not.have.class("touched");
expect(getInput(page)).to.not.have.class("changed");
expect(getInput(page)).to.have.class("pristine");
});
it("should have class .touched once clicked", async () => {
const page = render();
await user.click(getInput(page));
expect(getInput(page))
.to.have.class("touched")
.and.to.not.have.class("pristine");
});
it("should have class .changed once changed", async () => {
const page = render();
await user.click(getInput(page));
expect(getInput(page))
.to.have.class("changed")
.and.to.not.have.class("pristine");
});
});
describe("events", () => {
it("should dispatch focusin -> input -> change on click", async () => {
const page = render();
const input = select(page, "uwc-input");
const events = trapEvents(input, ["change", "input", "focusin"]);
await user.click(input);
expect(events.get().map((e) => e.type)).to.deep.eq([
"focusin",
"input",
"change",
]);
});
it("should not dispatch a change event when already checked", async () => {
const page = render();
const input = select(page, "uwc-input");
const waitForChange = waitForEvent(input, "change", { timeout: 10 });
await user.click(input);
await expect(waitForChange).to.eventually.be.rejected;
});
it("should emit a change event when changing back to it", async () => {
const page = render(
,
);
const first = select(page, "uwc-input:first-child");
const second = select(page, "uwc-input:last-child");
await user.click(second);
const waitForChange = waitForEvent(first, "change", { timeout: 5000 });
await user.click(first);
await expect(waitForChange).to.eventually.be.fulfilled;
});
it("should not change when .defaultPrevented", async () => {
const page = render(
,
);
const input = select(page, "uwc-input");
await user.click(input);
expect(input.checked).to.eq(false);
});
it("should not emit an event if checked via js", () => {
const page = render();
const events = trapEvents(page, []);
select(page, "uwc-input").checked = true;
expect(events.get()).to.deep.eq([]);
});
});
describe("[readonly]", () => {
it("should not be possible to change", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.click(input);
expect(input).to.include({ checked: false });
});
it("should add its value to formdata", () => {
const page = render(
,
);
expect(getFormValues(select(page, "form"))).to.deep.eq({ foo: "cheese" });
});
it("should not report invalid values", () => {
const page = render(
,
);
expect(select(page, "uwc-input").validity).to.include({ valid: true });
});
});
describe("[disabled]", () => {
it("should not be possible to change", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.click(input);
expect(input).to.include({ checked: false });
});
it("should not add its value to formdata", () => {
const page = render(
,
);
expect(getFormValues(select(page, "form"))).to.deep.eq({});
});
it("should not report invalid values", () => {
const page = render(
,
);
expect(select(page, "uwc-input").validity).to.include({ valid: true });
});
});
describe("a11y", () => {
it("should have role radio", () => {
const page = render();
expect(queryByRole(page, "radio")).to.not.be.null;
});
it("should be possible to focus with {Tab}", async () => {
const page = render();
await user.tab();
expect(document.activeElement).to.eq(select(page, "uwc-input"));
});
it("should be possible to check when focussed with { }", async () => {
const page = render();
await user.tab();
await user.keyboard(" ");
expect(select(page, "uwc-input")).to.include({ checked: true });
});
it("should be possible to move checked radio with arrow keys", async () => {
const page = render(
<>
>,
);
const assertIsNthChecked = (activeElement: number) => {
expect(getNth(page, 1)).to.include({ checked: 1 === activeElement });
expect(getNth(page, 2)).to.include({ checked: 2 === activeElement });
expect(getNth(page, 3)).to.include({ checked: 3 === activeElement });
expect(document.activeElement).to.eq(getNth(page, activeElement));
};
await user.tab();
await user.keyboard("{ArrowRight}");
assertIsNthChecked(2);
await user.keyboard("{ArrowDown}");
assertIsNthChecked(3);
await user.keyboard("{ArrowLeft}");
assertIsNthChecked(2);
await user.keyboard("{ArrowUp}");
assertIsNthChecked(1);
});
});
});