import { mount } from "@vue/test-utils"; import ProgressBar from "./progress-bar.vue"; jest.mock("@/constants/progress-bar-mapper", () => ({ getProgressBarPercentage: jest.fn(), })); import { getProgressBarPercentage } from "@/constants/progress-bar-mapper"; describe("progress-bar.vue", () => { beforeEach(() => { jest.useFakeTimers(); getProgressBarPercentage.mockReset(); }); afterEach(() => { jest.clearAllTimers(); jest.useRealTimers(); }); it("renders with correct initial progress", async () => { getProgressBarPercentage.mockReturnValueOnce(30); const wrapper = mount(ProgressBar, { props: { page: "page1" }, }); // Immediately after mount, width should be lastProgress (0) expect(wrapper.find(".progress-bar-inner").attributes("style")).toContain("width: 0%"); // Advance timer to trigger animation jest.runAllTimers(); await wrapper.vm.$nextTick(); expect(wrapper.find(".progress-bar-inner").attributes("style")).toContain("width: 30%"); }); it("animates to new progress when page prop changes", async () => { getProgressBarPercentage.mockReturnValueOnce(30); const wrapper = mount(ProgressBar, { props: { page: "page1" }, }); jest.runAllTimers(); await wrapper.vm.$nextTick(); expect(wrapper.find(".progress-bar-inner").attributes("style")).toContain("width: 30%"); getProgressBarPercentage.mockReturnValueOnce(60); await wrapper.setProps({ page: "page2" }); // Before timer, still old value expect(wrapper.find(".progress-bar-inner").attributes("style")).toContain("width: 30%"); jest.runAllTimers(); await wrapper.vm.$nextTick(); expect(wrapper.find(".progress-bar-inner").attributes("style")).toContain("width: 60%"); }); it("clears timeout on unmount", async () => { getProgressBarPercentage.mockReturnValueOnce(50); const wrapper = mount(ProgressBar, { props: { page: "page1" }, }); const clearTimeoutSpy = jest.spyOn(window, "clearTimeout"); wrapper.unmount(); expect(clearTimeoutSpy).toHaveBeenCalled(); clearTimeoutSpy.mockRestore(); }); }); const mockMixin = { methods: { getProgress: jest.fn(), }, };