@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
375 lines (374 loc) • 16.6 kB
JavaScript
import { newE2EPage } from "@stencil/core/testing";
import { html } from "../../tests/utils";
import { CSS as PICK_LIST_ITEM_CSS } from "../calcite-pick-list-item/resources";
export function keyboardNavigation(listType) {
const getFocusedItemValue = (page) => page.evaluate(() => document.activeElement.value);
describe("multi selection", () => {
it("can be navigated with up/down arrow keys", async () => {
const page = await newE2EPage({
html: `
<calcite-${listType}-list multiple>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
</calcite-${listType}-list>
`
});
const list = await page.find(`calcite-${listType}-list`);
await list.callMethod("setFocus");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("one");
});
});
describe("single selection", () => {
describe("with selected item", () => {
it("can be navigated with up/down arrow keys", async () => {
const page = await newE2EPage({
html: `
<calcite-${listType}-list>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two" selected></calcite-${listType}-list-item>
</calcite-${listType}-list>
`
});
const list = await page.find(`calcite-${listType}-list`);
await list.callMethod("setFocus");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("two");
});
});
describe("no selected item", () => {
it("can be navigated with up/down arrow keys", async () => {
const page = await newE2EPage({
html: `
<calcite-${listType}-list>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
</calcite-${listType}-list>
`
});
const list = await page.find(`calcite-${listType}-list`);
await list.callMethod("setFocus");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowDown");
expect(await getFocusedItemValue(page)).toEqual("one");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("two");
await list.press("ArrowUp");
expect(await getFocusedItemValue(page)).toEqual("one");
});
});
});
}
export function selectionAndDeselection(listType) {
describe("when multiple is false and a item is clicked", () => {
it("should emit an event with the last selected item data", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const item2 = await list.find("[value=two]");
const toggleSpy = await list.spyOnEvent("calciteListChange");
await item1.click();
await item2.click();
expect(toggleSpy).toHaveReceivedEventTimes(2);
});
});
describe("when multiple is true and a item is clicked", () => {
it("should emit an event with each selected item's data", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list multiple>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const item2 = await list.find("[value=two]");
const toggleSpy = await list.spyOnEvent("calciteListChange");
await item1.click();
await item2.click();
await item2.click(); // deselect
expect(toggleSpy).toHaveReceivedEventTimes(3);
});
});
describe("preselected items", () => {
it("should be included in the list of selected items", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list multiple>
<calcite-${listType}-list-item value="one" label="One" selected></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const numSelected = await page.evaluate(async (listType) => {
const list = document.querySelector(`calcite-${listType}-list`);
return (await list.getSelectedItems()).size;
}, listType);
expect(numSelected).toBe(1);
});
});
describe("shift click behavior", () => {
it("should multi-select", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list multiple>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="three" label="Three"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const item3 = await list.find("[value=three]");
await item1.click();
await page.keyboard.down("Shift");
await item3.click();
await page.keyboard.up("Shift");
const numSelected = await page.evaluate(async (listType) => {
const list = document.querySelector(`calcite-${listType}-list`);
return (await list.getSelectedItems()).size;
}, listType);
expect(numSelected).toBe(3);
});
it("should multi de-select", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list multiple>
<calcite-${listType}-list-item value="one" label="One" selected></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two" selected></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="three" label="Three" selected></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const item3 = await list.find("[value=three]");
await item1.click();
await page.keyboard.down("Shift");
await item3.click();
await page.keyboard.up("Shift");
const numSelected = await page.evaluate(async (type) => {
const domList = document.querySelector(`calcite-${type}-list`);
return (await domList.getSelectedItems()).size;
}, listType);
expect(numSelected).toBe(0);
});
});
describe("calciteListChange event", () => {
it("should fire event when a selection changed", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list>
<calcite-${listType}-list-item label="test" value="example"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const item = await page.find(`calcite-${listType}-list-item`);
await page.evaluate(() => {
document.addEventListener("calciteListChange", (event) => {
window.eventDetail = event.detail;
});
});
await item.click();
await page.waitForChanges();
const eventDetail = await page.evaluateHandle(() => {
const detail = window.eventDetail;
return {
size: detail.size,
hasItem: detail.has("example")
};
});
const properties = await eventDetail.getProperties();
expect(eventDetail).toBeDefined();
expect(properties.get("size")._remoteObject.value).toBe(1);
expect(properties.get("hasItem")._remoteObject.value).toBe(true);
});
});
describe("value changes after item is selected", () => {
it("should update the value in selectedValues map", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list>
<calcite-${listType}-list-item value="one" label="One" selected></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="two" label="Two" selected></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="three" label="Three" selected></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
await item1.click();
const hasValueOne = await page.evaluate(async (type) => {
const pageList = document.querySelector(`calcite-${type}-list`);
return (await pageList.getSelectedItems()).has("one");
}, listType);
expect(hasValueOne).toBe(true);
item1.setProperty("value", "four");
await page.waitForChanges();
const hasValues = await page.evaluate(async (type) => {
const pageList = document.querySelector(`calcite-${type}-list`);
const result = await pageList.getSelectedItems();
return {
four: result.has("four"),
one: result.has("one")
};
}, listType);
expect(hasValues.one).toBe(false);
expect(hasValues.four).toBe(true);
});
});
}
export function filterBehavior(listType) {
let page = null;
let item1;
let item2;
let item1Visible;
let item2Visible;
beforeEach(async () => {
page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list filter-enabled>
<calcite-${listType}-list-item value="1" label="One" description="uno"></calcite-${listType}-list-item>
<calcite-${listType}-list-item value="2" label="Two" description="dos"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
item1 = await page.find(`calcite-${listType}-list-item[value="1"]`);
item2 = await page.find(`calcite-${listType}-list-item[value="2"]`);
item1.setProperty("metadata", { category: "first" });
item2.setProperty("metadata", { category: "second" });
await page.waitForChanges();
await page.evaluate((listType) => {
window.filter = document
.querySelector(`calcite-${listType}-list`)
.shadowRoot.querySelector("calcite-filter");
const filter = window.filter;
window.filterInput = filter.shadowRoot.querySelector("input");
}, listType);
});
it("should match text in the label prop", async () => {
// Match first item
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "one";
filterInput.dispatchEvent(new Event("input"));
});
await item2.waitForNotVisible();
item1Visible = await item1.isVisible();
item2Visible = await item2.isVisible();
expect(item1Visible).toBe(true);
expect(item2Visible).toBe(false);
// Match second item
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "two";
filterInput.dispatchEvent(new Event("input"));
});
await item1.waitForNotVisible();
item1Visible = await item1.isVisible();
item2Visible = await item2.isVisible();
expect(item1Visible).toBe(false);
expect(item2Visible).toBe(true);
});
it("should match text in the description prop", async () => {
// Match first item
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "uno";
filterInput.dispatchEvent(new Event("input"));
});
await item2.waitForNotVisible();
item1Visible = await item1.isVisible();
item2Visible = await item2.isVisible();
expect(item1Visible).toBe(true);
expect(item2Visible).toBe(false);
// Match second item
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "dos";
filterInput.dispatchEvent(new Event("input"));
});
await item1.waitForNotVisible();
item1Visible = await item1.isVisible();
item2Visible = await item2.isVisible();
expect(item1Visible).toBe(false);
expect(item2Visible).toBe(true);
});
it("should match text in the metadata prop", async () => {
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "first";
filterInput.dispatchEvent(new Event("input"));
});
await item2.waitForNotVisible();
let item1Visible = await item1.isVisible();
let item2Visible = await item2.isVisible();
expect(item1Visible).toBe(true);
expect(item2Visible).toBe(false);
await page.evaluate(() => {
const filterInput = window.filterInput;
filterInput.value = "second";
filterInput.dispatchEvent(new Event("input"));
});
await item1.waitForNotVisible();
item1Visible = await item1.isVisible();
item2Visible = await item2.isVisible();
expect(item1Visible).toBe(false);
expect(item2Visible).toBe(true);
});
}
export function disabledStates(listType) {
it("disabled", async () => {
const page = await newE2EPage({
html: html `
<calcite-${listType}-list disabled>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
</calcite-${listType}-list>
`
});
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const toggleSpy = await list.spyOnEvent("calciteListChange");
await item1.click();
expect(toggleSpy).toHaveReceivedEventTimes(0);
});
it("loading", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-${listType}-list loading>
<calcite-${listType}-list-item value="one" label="One"></calcite-${listType}-list-item>
</calcite-${listType}-list>`);
const list = await page.find(`calcite-${listType}-list`);
const item1 = await list.find("[value=one]");
const toggleSpy = await list.spyOnEvent("calciteListChange");
await item1.click();
expect(toggleSpy).toHaveReceivedEventTimes(0);
});
}
export function itemRemoval(listType) {
it("handles removing items", async () => {
const page = await newE2EPage({
html: html `
<calcite-${listType}-list>
<calcite-${listType}-list-item value="remove-me" label="Remove me!" removable></calcite-${listType}-list-item>
</calcite-${listType}-list>
`
});
const list = await page.find(`calcite-${listType}-list`);
const removeItemSpy = await list.spyOnEvent("calciteListItemRemove");
const listChangeSpy = await list.spyOnEvent("calciteListChange");
await page.$eval(`calcite-${listType}-list-item`, (item, listType, selector) => {
listType === "pick"
? item.shadowRoot.querySelector(selector).click()
: item.shadowRoot
.querySelector("calcite-pick-list-item")
.shadowRoot.querySelector(selector)
.click();
}, listType, `.${PICK_LIST_ITEM_CSS.remove}`);
await page.waitForChanges();
expect(await page.find(`calcite-${listType}-list-item`)).toBeNull();
expect(removeItemSpy).toHaveReceivedEventTimes(1);
expect(listChangeSpy).toHaveReceivedEventTimes(1);
});
}