Files
MajoorWaldi-ComfyUI-Majoor-…/ui/tests/header_section_mfv_button.vitest.ts
T
Ewald 85a82f130a test: migrate ui/tests from .mjs to .ts
- Rename 132 *.vitest.mjs -> *.vitest.ts
- Rename vitest.setup.mjs -> vitest.setup.ts
- Rename helpers/vitestEnvironment.mjs -> vitestEnvironment.ts
- Delete settings_store.test.mjs (Node test runner, superseded by .vitest.ts)
- Fix .mjs imports in vitest.setup.ts and grid_loader_adaptive_paging.vitest.ts

Config updates:
- vitest.config.mjs: setupFiles, include, coverage.include -> .ts
- tsconfig.test.json: new dedicated config for test files (strict:false)
- knip.json: update project pattern for tests
- package.json: add typecheck:tests script (audit-only)
2026-05-26 13:04:05 +02:00

152 lines
4.8 KiB
TypeScript

// @vitest-environment happy-dom
import { mount } from "@vue/test-utils";
import { reactive, nextTick } from "vue";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const panelStore = reactive({
sort: "mtime_desc",
scope: "output",
viewScope: "output",
similarResults: [],
similarTitle: "",
});
vi.mock("../stores/usePanelStore.js", () => ({
usePanelStore: () => panelStore,
}));
vi.mock("../api/client.js", () => ({
get: vi.fn(async () => ({ ok: false })),
getWatcherStatus: vi.fn(async () => ({ ok: true, data: { enabled: true } })),
toggleWatcher: vi.fn(async () => ({ ok: true })),
}));
vi.mock("../app/i18n.js", () => ({
t: (key, fallback) => fallback || key,
}));
vi.mock("../app/versionCheck.js", () => ({
VERSION_UPDATE_EVENT: "mjr:version-update",
getStoredVersionUpdateState: () => ({ available: false }),
}));
vi.mock("../app/events.js", () => ({
EVENTS: {
MFV_TOGGLE: "mjr:mfv-toggle",
MFV_VISIBILITY_CHANGED: "mjr:mfv-visibility-changed",
},
}));
const openMajoorSettingsMock = vi.fn();
vi.mock("../app/openMajoorSettings.js", () => ({
openMajoorSettings: openMajoorSettingsMock,
}));
vi.mock("../utils/tooltipShortcuts.js", () => ({
setTooltipHint: (el, label, hint) => {
if (!el) return;
const full = hint ? `${label} (${hint})` : label;
el.setAttribute("title", full);
el.setAttribute("aria-label", full);
},
}));
const MButtonStub = {
props: {
severity: String,
text: Boolean,
rounded: Boolean,
},
inheritAttrs: false,
template: '<button v-bind="$attrs"><slot /></button>',
};
const STUB_COMPONENTS = {
MButton: MButtonStub,
SearchBar: { template: "<div><slot /></div>" },
SortPopover: { template: "<div />" },
FilterPopover: { template: "<div />" },
CollectionsPopover: { template: "<div />" },
PinnedFoldersPopover: { template: "<div />" },
CustomRootsPopover: { template: "<div />" },
MessagePopover: { template: "<div />" },
};
async function flushMountedState() {
await nextTick();
await Promise.resolve();
await nextTick();
}
describe("HeaderSection MFV button", () => {
beforeEach(() => {
document.body.innerHTML = "";
});
afterEach(() => {
document.body.innerHTML = "";
vi.restoreAllMocks();
});
it("applies the active class when MFV visibility changes", async () => {
const mod = await import("../vue/components/panel/HeaderSection.vue");
const wrapper = mount(mod.default, {
global: { stubs: STUB_COMPONENTS },
});
await flushMountedState();
const button = wrapper.element.querySelector(".mjr-am-header-tools > button.mjr-icon-btn");
const icon = button?.querySelector("i");
expect(button).toBeTruthy();
expect(icon?.className).toBe("pi pi-eye");
expect(button.getAttribute("title")).toContain("Majoor Floating Viewer");
expect(button.classList.contains("mjr-mfv-btn-active")).toBe(false);
window.dispatchEvent(
new CustomEvent("mjr:mfv-visibility-changed", { detail: { visible: true } }),
);
await flushMountedState();
expect(button.classList.contains("mjr-mfv-btn-active")).toBe(true);
wrapper.unmount();
});
it("starts active when the floating viewer is already visible in the DOM", async () => {
const liveViewer = document.createElement("div");
liveViewer.className = "mjr-mfv is-visible";
document.body.appendChild(liveViewer);
const mod = await import("../vue/components/panel/HeaderSection.vue");
const wrapper = mount(mod.default, {
global: { stubs: STUB_COMPONENTS },
});
await flushMountedState();
const button = wrapper.element.querySelector(".mjr-am-header-tools > button.mjr-icon-btn");
const icon = button?.querySelector("i");
expect(button).toBeTruthy();
expect(icon?.className).toBe("pi pi-eye");
expect(button.classList.contains("mjr-mfv-btn-active")).toBe(true);
wrapper.unmount();
});
it("opens Majoor settings from the header gear button", async () => {
const mod = await import("../vue/components/panel/HeaderSection.vue");
const wrapper = mount(mod.default, {
global: { stubs: STUB_COMPONENTS },
});
await flushMountedState();
const button = wrapper.element.querySelector(".mjr-settings-shortcut-btn");
expect(button).toBeTruthy();
expect(button?.querySelector("i")?.className).toBe("pi pi-cog");
await button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
expect(openMajoorSettingsMock).toHaveBeenCalledTimes(1);
wrapper.unmount();
});
});