This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js

344 lines
8.0 KiB
JavaScript

import { click, fillIn, triggerEvent } from "@ember/test-helpers";
import { exists, query, queryAll } from "discourse/tests/helpers/qunit-helpers";
import { isEmpty } from "@ember/utils";
import { moduleForComponent } from "ember-qunit";
function checkSelectKitIsNotExpanded(selector) {
if (query(selector).classList.contains("is-expanded")) {
// eslint-disable-next-line no-console
console.warn("You expected select-kit to be collapsed but it is expanded.");
}
}
function checkSelectKitIsNotCollapsed(selector) {
if (!query(selector).classList.contains("is-expanded")) {
// eslint-disable-next-line no-console
console.warn("You expected select-kit to be expanded but it is collapsed.");
}
}
async function expandSelectKit(selector) {
checkSelectKitIsNotExpanded(selector);
return await click(`${selector} .select-kit-header`);
}
async function collapseSelectKit(selector) {
checkSelectKitIsNotCollapsed(selector);
return await click(`${selector} .select-kit-header`);
}
async function selectKitFillInFilter(filter, selector) {
checkSelectKitIsNotCollapsed(selector);
await fillIn(
`${selector} .filter-input`,
query(`${selector} .filter-input`).value + filter
);
}
async function selectKitEmptyFilter(selector) {
checkSelectKitIsNotCollapsed(selector);
await fillIn(`${selector} .filter-input`, "");
}
async function selectKitSelectRowByValue(value, selector) {
checkSelectKitIsNotCollapsed(selector);
await click(`${selector} .select-kit-row[data-value='${value}']`);
}
async function selectKitSelectRowByName(name, selector) {
checkSelectKitIsNotCollapsed(selector);
await click(`${selector} .select-kit-row[data-name='${name}']`);
}
async function selectKitSelectNoneRow(selector) {
checkSelectKitIsNotCollapsed(selector);
await click(`${selector} .select-kit-row.none`);
}
async function selectKitSelectRowByIndex(index, selector) {
checkSelectKitIsNotCollapsed(selector);
await click(queryAll(`${selector} .select-kit-row`)[index]);
}
async function keyboardHelper(value, target, selector) {
target = query(selector).querySelector(target || ".filter-input");
if (value === "selectAll") {
// special casing the only one not working with triggerEvent
// eslint-disable-next-line no-undef
const event = jQuery.Event("keydown");
event.key = "A";
event.keyCode = 65;
event.metaKey = true;
$(target).trigger(event);
} else {
const mapping = {
enter: { key: "Enter", keyCode: 13 },
backspace: { key: "Backspace", keyCode: 8 },
escape: { key: "Escape", keyCode: 27 },
down: { key: "ArrowDown", keyCode: 40 },
up: { key: "ArrowUp", keyCode: 38 },
tab: { key: "Tab", keyCode: 9 },
};
await triggerEvent(
target,
"keydown",
mapping[value.toLowerCase()] || {
key: value,
keyCode: value.charCodeAt(0),
}
);
}
}
function rowHelper(row) {
return {
name() {
return row.getAttribute("data-name");
},
icon() {
return row.querySelector(".d-icon");
},
title() {
return row.getAttribute("title");
},
label() {
return row.querySelector(".name").innerText.trim();
},
value() {
const value = row?.getAttribute("data-value");
return isEmpty(value) ? null : value;
},
exists() {
return exists(row);
},
el() {
return row;
},
};
}
function headerHelper(header) {
return {
value() {
const value = header.getAttribute("data-value");
return isEmpty(value) ? null : value;
},
name() {
return header.getAttribute("data-name");
},
label() {
return header.innerText
.trim()
.replace(/(^[\s\u200b]*|[\s\u200b]*$)/g, "");
},
icon() {
return header.querySelector(".d-icon");
},
title() {
return header.querySelector(".selected-name").getAttribute("title");
},
el() {
return header;
},
};
}
function filterHelper(filter) {
return {
icon() {
return filter.querySelector(".d-icon");
},
exists() {
return exists(filter);
},
value() {
return filter.querySelector("input").value;
},
el() {
return filter;
},
};
}
export default function selectKit(selector) {
selector = selector || ".select-kit";
return {
async expand() {
await expandSelectKit(selector);
},
async collapse() {
await collapseSelectKit(selector);
},
async selectRowByIndex(index) {
await selectKitSelectRowByIndex(index, selector);
},
async selectRowByValue(value) {
await selectKitSelectRowByValue(value, selector);
},
async selectKitSelectRowByName(name) {
await selectKitSelectRowByName(name, selector);
},
async selectRowByName(name) {
await selectKitSelectRowByName(name, selector);
},
async selectNoneRow() {
await selectKitSelectNoneRow(selector);
},
async fillInFilter(filter) {
await selectKitFillInFilter(filter, selector);
},
async emptyFilter() {
await selectKitEmptyFilter(selector);
},
async keyboard(value, target) {
await keyboardHelper(value, target, selector);
},
isExpanded() {
return query(selector).classList.contains("is-expanded");
},
isFocused() {
return query(selector).classList.contains("is-focused");
},
isHidden() {
return query(selector).classList.contains("is-hidden");
},
isDisabled() {
return query(selector).classList.contains("is-disabled");
},
header() {
return headerHelper(query(selector).querySelector(".select-kit-header"));
},
filter() {
return filterHelper(query(selector).querySelector(".select-kit-filter"));
},
rows() {
return query(selector).querySelectorAll(".select-kit-row");
},
displayedContent() {
return [...this.rows()].map((row) => ({
name: row.getAttribute("data-name"),
id: row.getAttribute("data-value"),
}));
},
rowByValue(value) {
return rowHelper(
query(selector).querySelector(`.select-kit-row[data-value="${value}"]`)
);
},
rowByName(name) {
return rowHelper(
query(selector).querySelector(`.select-kit-row[data-name="${name}"]`)
);
},
rowByIndex(index) {
return rowHelper(
query(selector).querySelector(
`.select-kit-row:nth-of-type(${index + 1})`
)
);
},
el() {
return query(selector);
},
noneRow() {
return rowHelper(query(selector).querySelector(".select-kit-row.none"));
},
validationMessage() {
const validationMessage = query(selector).querySelector(
".validation-message"
);
if (validationMessage) {
return validationMessage.innerHTML.trim();
} else {
return null;
}
},
selectedRow() {
return rowHelper(
query(selector).querySelector(".select-kit-row.is-selected")
);
},
highlightedRow() {
return rowHelper(
query(selector).querySelector(".select-kit-row.is-highlighted")
);
},
async deselectItemByValue(value) {
await click(`${selector} .selected-content [data-value="${value}"]`);
},
async deselectItemByName(name) {
await click(`${selector} .selected-content [data-name="${name}"]`);
},
exists() {
return exists(selector);
},
};
}
export function testSelectKitModule(moduleName, options = {}) {
moduleForComponent(`select-kit/${moduleName}`, {
integration: true,
beforeEach() {
this.set("subject", selectKit());
options.beforeEach?.call(this);
},
afterEach() {
options.afterEach?.call(this);
},
});
}
export const DEFAULT_CONTENT = [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" },
];
export function setDefaultState(ctx, value, options = {}) {
const properties = Object.assign(
{
value,
onChange: (v) => {
ctx.set("value", v);
},
},
options || {}
);
ctx.setProperties(properties);
}