UNPKG

@shopware-ag/meteor-component-library

Version:

The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).

196 lines (148 loc) 5.59 kB
import { mount } from "@vue/test-utils"; import MtFloatingUi from "./mt-floating-ui.vue"; import flushPromises from "flush-promises"; // mock resizeOvserver global.ResizeObserver = class ResizeObserver { observe() { // do nothing } unobserve() { // do nothing } disconnect() { // do nothing } }; function createWrapper() { return mount(MtFloatingUi, { attachTo: document.getElementById("appWrapper")!, slots: { trigger: `<div id="triggerSlotContent">Slot content for "trigger" slot</div>`, default: `<div id="defaultSlotContent">Slot content for "default" slot</div>`, }, props: { isOpened: false, }, }); } describe("mt-floating-ui", () => { let wrapper: undefined | ReturnType<typeof createWrapper>; // create app wrapper let appWrapper = document.createElement("div"); appWrapper.setAttribute("id", "appWrapper"); document.body.appendChild(appWrapper); beforeEach(async () => { if (wrapper) { wrapper.unmount(); } await flushPromises(); document.body.innerHTML = '<div id="app"></div>'; appWrapper = document.createElement("div"); appWrapper.setAttribute("id", "appWrapper"); document.body.appendChild(appWrapper); }); it("should render the component", () => { wrapper = createWrapper(); expect(wrapper.vm).toBeTruthy(); }); it("should render the trigger slot", async () => { wrapper = createWrapper(); const triggerSlot = wrapper.find("#triggerSlotContent"); expect(triggerSlot.exists()).toBeTruthy(); expect(triggerSlot.text()).toBe('Slot content for "trigger" slot'); }); it("should not render the content when floating UI is closed", () => { wrapper = createWrapper(); const contentSlotContent = wrapper.find("#defaultSlotContent"); expect(contentSlotContent.exists()).toBeFalsy(); }); it("should render the content when floating UI gets opened", async () => { wrapper = createWrapper(); await wrapper.setProps({ isOpened: true, }); const contentSlotContent = document.querySelector("#defaultSlotContent"); expect(contentSlotContent).toBeTruthy(); expect(contentSlotContent?.textContent).toBe('Slot content for "default" slot'); }); it("should not render the arrow when prop is not set", () => { wrapper = createWrapper(); const arrow = wrapper.find(".mt-floating-ui__arrow"); expect(arrow.exists()).toBeFalsy(); }); it("should render the arrow when prop is set", async () => { wrapper = createWrapper(); await wrapper.setProps({ showArrow: true, isOpened: true, }); const arrow = document.querySelector(".mt-floating-ui__arrow"); expect(arrow).toBeTruthy(); }); it("should mount the floating ui to the document body", async () => { wrapper = createWrapper(); await wrapper.setProps({ isOpened: true, }); await flushPromises(); const floatingUi = document.querySelector(".mt-floating-ui"); const floatingUiContent = document.querySelector(".mt-floating-ui__content"); expect(document.querySelector("#appWrapper")!.contains(floatingUi)).toBeTruthy(); // won't get teleported, so it's still in the app wrapper expect(document.querySelector("#appWrapper")!.contains(floatingUiContent)).toBeFalsy(); // will get teleported to the body, so it's outside the app wrapper expect(floatingUiContent!.parentElement!.tagName).toBe("BODY"); }); it("should unmount the floating ui to the document body", async () => { wrapper = createWrapper(); await wrapper.setProps({ isOpened: true, }); wrapper.unmount(); await flushPromises(); const floatingUi = document.querySelector(".mt-floating-ui"); const floatingUiContent = document.querySelector(".mt-floating-ui__content"); expect(floatingUi).toBeNull(); expect(floatingUiContent).toBeNull(); }); it("should match reference width when matchReferenceWidth prop is true", async () => { wrapper = createWrapper(); // Set a specific width for the trigger element to test against const triggerElement = wrapper.find(".mt-floating-ui__trigger").element as HTMLElement; triggerElement.style.width = "200px"; // Mock getBoundingClientRect to return the expected width triggerElement.getBoundingClientRect = vi.fn(() => ({ width: 200, height: 50, top: 0, left: 0, bottom: 50, right: 200, x: 0, y: 0, toJSON: vi.fn(), })); await wrapper.setProps({ isOpened: true, matchReferenceWidth: true, }); await flushPromises(); // Give some time for floating-ui to compute await new Promise((resolve) => setTimeout(resolve, 50)); const floatingUiContent = document.querySelector(".mt-floating-ui__content") as HTMLElement; expect(floatingUiContent).toBeTruthy(); expect(floatingUiContent.style.width).toBe("200px"); }); it("should not set width when matchReferenceWidth prop is false or not set", async () => { wrapper = createWrapper(); // Set a specific width for the trigger element const triggerElement = wrapper.find(".mt-floating-ui__trigger").element as HTMLElement; triggerElement.style.width = "200px"; await wrapper.setProps({ isOpened: true, matchReferenceWidth: false, }); await flushPromises(); const floatingUiContent = document.querySelector(".mt-floating-ui__content") as HTMLElement; expect(floatingUiContent).toBeTruthy(); expect(floatingUiContent.style.width).toBe(""); }); });