Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
19b4c94
vitest 3
karancs06 Nov 5, 2025
7ee05ab
fix: update node version
karancs06 Nov 6, 2025
2571c6e
fix
karancs06 Nov 6, 2025
abed3ba
fix: before each
karancs06 Nov 7, 2025
5ad8e01
fix
karancs06 Nov 9, 2025
e87a0d0
fix: resolve remaining test timeouts in fieldToolbar and multipleElem…
karancs06 Nov 9, 2025
ca0e002
fix: resolve test timeouts by adding missing mocks for async operations
karancs06 Nov 10, 2025
91df460
fix: comprehensive mock improvements for CI reliability
karancs06 Nov 10, 2025
b1a5f13
perf: optimize multipleElementAddButton tests - remove unnecessary sl…
karancs06 Nov 10, 2025
1c4ae4c
new
karancs06 Nov 10, 2025
752a6ee
skipping failures
karancs06 Nov 10, 2025
733db90
optimizing in vitest 3
karancs06 Nov 13, 2025
ae9341c
unskipping
karancs06 Nov 13, 2025
2485734
feat: adding profiler
karancs06 Nov 17, 2025
a4eb480
fix: optimization
karancs06 Nov 17, 2025
6b54241
fix: field wrapper test
karancs06 Nov 18, 2025
a757294
increased timeout
karancs06 Nov 18, 2025
93e5d1d
fix: mocked waitforhoveroutline
karancs06 Nov 18, 2025
309fdd1
fix:field toolbar test
karancs06 Nov 18, 2025
848f151
fix:field toolbar test
karancs06 Nov 18, 2025
400c186
fix: unskipping
karancs06 Nov 18, 2025
d5b0e56
fix:increase timeout
karancs06 Nov 18, 2025
cf10a2c
fix:increase timeout
karancs06 Nov 18, 2025
07b8f14
fix:increase timeout
karancs06 Nov 18, 2025
8c87f98
fix: optimize optimized
karancs06 Nov 18, 2025
d6007d2
fix: merging all hover test
karancs06 Nov 18, 2025
04e2322
feat: timeout done
karancs06 Nov 18, 2025
2270b46
fix: passing all
karancs06 Nov 18, 2025
2eef616
fix: errors
karancs06 Nov 18, 2025
a27b5a8
fix: error
karancs06 Nov 18, 2025
c063f9d
coverage
karancs06 Nov 19, 2025
5ba51e7
optimze coverage
karancs06 Nov 19, 2025
e9efa71
some coverage files removed
karancs06 Nov 19, 2025
eb15491
removing unwanted changes
karancs06 Nov 19, 2025
92b6bf4
removing unwanted test changes
karancs06 Nov 19, 2025
ed05434
increased timeout
karancs06 Nov 19, 2025
3d91b56
removed redundant cases for hover and click
karancs06 Nov 21, 2025
9e6568c
fix: optimizing
karancs06 Nov 21, 2025
b548907
fix: changes
karancs06 Nov 26, 2025
abaec5b
fix: changes requested done
karancs06 Nov 26, 2025
954c478
fix
karancs06 Nov 27, 2025
7067f21
reporter fro ci removed
karancs06 Nov 27, 2025
1861f5f
test times reduced
karancs06 Nov 27, 2025
921a5b7
timeout increased
karancs06 Nov 27, 2025
21fa96f
new case added
karancs06 Nov 27, 2025
8e4955b
timeout reduced
karancs06 Nov 28, 2025
d310621
merge pass
karancs06 Dec 1, 2025
d8895b8
adding logs
karancs06 Dec 1, 2025
aa1f80f
removing .only
karancs06 Dec 1, 2025
28790e2
removing optimizing
karancs06 Dec 1, 2025
bada76e
optimizing
karancs06 Dec 1, 2025
4e4b477
modified act
karancs06 Dec 1, 2025
4b353d6
Revert "adding logs"
karancs06 Dec 1, 2025
76d3058
removing performance.now
karancs06 Dec 1, 2025
194bd99
remove skip
karancs06 Dec 2, 2025
a75562a
separate files
karancs06 Dec 2, 2025
9398aa0
field wrapper separate
karancs06 Dec 3, 2025
73684ef
fix: test cases
karancs06 Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:
- name: "Install Node"
uses: actions/setup-node@v4
with:
node-version: "21.x"
node-version: "22.x"
- name: "Install Deps"
run: npm install
- name: "Test"
run: npx vitest --coverage.enabled true
run: npm run test:coverage
- name: "Report Coverage"
# Set if: always() to also generate the report if tests are failing
# Only works if you set `reportOnFailure: true` in your vite config as specified above
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,10 @@ temp/

.DS_Store

# Test results and profiling reports
test-results.json
junit.xml
test-reports/
test-profile-report.json

# End of https://www.toptal.com/developers/gitignore/api/node,web,vscode
1,915 changes: 1,415 additions & 500 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"sideEffects": false,
"scripts": {
"build": "NODE_OPTIONS='--max-old-space-size=16384' tsup",
"test": "vitest",
"test": "vitest --run",
"test:watch": "vitest",
"test:once": "vitest run",
"test:coverage": "vitest --coverage",
"dev": "NODE_OPTIONS='--max-old-space-size=16384' tsup --watch",
Expand Down Expand Up @@ -57,8 +58,8 @@
"@types/react": "^18.2.57",
"@types/react-dom": "^18.2.19",
"@types/uuid": "^8.3.1",
"@vitest/coverage-v8": "^2.1.2",
"@vitest/ui": "^2.1.2",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"auto-changelog": "^2.5.0",
"esbuild-plugin-file-path-extensions": "^2.1.0",
"eslint": "^8.57.1",
Expand All @@ -77,7 +78,7 @@
"typedoc": "^0.25.13",
"typescript": "^5.4.5",
"typescript-eslint": "^8.5.0",
"vitest": "^2.1.0"
"vitest": "^3.2.4"
},
"repository": {
"type": "git",
Expand Down
132 changes: 108 additions & 24 deletions src/__test__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,62 +36,146 @@ export async function sleep(waitTimeInMs = 100): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, waitTimeInMs));
}

export const waitForHoverOutline = async () => {
await waitFor(() => {
const hoverOutline = document.querySelector(
"[data-testid='visual-builder__hover-outline'][style]"
);
expect(hoverOutline).not.toBeNull();
});
}
export const waitForBuilderSDKToBeInitialized = async (visualBuilderPostMessage: EventManager | undefined) => {
export const waitForHoverOutline = async (options?: {
timeout?: number;
interval?: number;
}) => {
// First, wait for the outline element to exist (faster check)
await waitFor(
() => {
const hoverOutline = document.querySelector(
"[data-testid='visual-builder__hover-outline']"
);
expect(hoverOutline).not.toBeNull();
},
{
timeout: options?.timeout ?? 2000,
interval: options?.interval ?? 5, // Faster polling: 5ms default
}
);

// Then wait for style attribute to be set (more specific check)
await waitFor(
() => {
const hoverOutline = document.querySelector(
"[data-testid='visual-builder__hover-outline']"
) as HTMLElement;
expect(hoverOutline).not.toBeNull();
// Check if style has meaningful values (not empty)
const hasStyle =
hoverOutline?.style &&
(hoverOutline.style.top ||
hoverOutline.style.left ||
hoverOutline.style.width ||
hoverOutline.style.height);
expect(hasStyle).toBeTruthy();
},
{
timeout: options?.timeout ?? 2000,
interval: options?.interval ?? 5, // Faster polling: 5ms default
}
);
};

export const waitForBuilderSDKToBeInitialized = async (
visualBuilderPostMessage: EventManager | undefined
) => {
await waitFor(() => {
expect(visualBuilderPostMessage?.send).toBeCalledWith(
VisualBuilderPostMessageEvents.INIT,
expect.any(Object)
);
});
}
};
interface WaitForClickActionOptions {
skipWaitForFieldType?: boolean;
}
export const triggerAndWaitForClickAction = async (visualBuilderPostMessage: EventManager | undefined, element: HTMLElement, {skipWaitForFieldType}: WaitForClickActionOptions = {}) => {
export const triggerAndWaitForClickAction = async (
visualBuilderPostMessage: EventManager | undefined,
element: HTMLElement,
{ skipWaitForFieldType }: WaitForClickActionOptions = {}
) => {
await waitForBuilderSDKToBeInitialized(visualBuilderPostMessage);
await act(async () => {
await fireEvent.click(element);
})
if(!skipWaitForFieldType) {
});
if (!skipWaitForFieldType) {
await waitFor(() => {
expect(element).toHaveAttribute("data-cslp-field-type")
})
expect(element).toHaveAttribute("data-cslp-field-type");
});
}
}
};
export const waitForToolbaxToBeVisible = async () => {
await waitFor(() => {
const toolbar = document.querySelector(
".visual-builder__focused-toolbar__field-label-container"
);
expect(toolbar).not.toBeNull();
});
}
};

export const waitForCursorToBeVisible = async (options?: {
timeout?: number;
interval?: number;
}) => {
await waitFor(
() => {
const customCursor = document.querySelector(
`[data-testid="visual-builder__cursor"]`
);
if (!customCursor) throw new Error("Cursor not found");
expect(customCursor.classList.contains("visible")).toBeTruthy();
},
{
timeout: options?.timeout ?? 2000, // Default 2s timeout for cursor to be visible
interval: options?.interval ?? 10, // Faster polling: 10ms default
}
);
};

export const waitForCursorIcon = async (
icon: string,
options?: { timeout?: number; interval?: number }
) => {
await waitFor(
() => {
const customCursor = document.querySelector(
`[data-testid="visual-builder__cursor"]`
);
if (!customCursor) throw new Error("Cursor not found");
expect(customCursor).toHaveAttribute("data-icon", icon);
},
{
timeout: options?.timeout ?? 1000, // Reduced from 2s to 1s - mocks resolve immediately
interval: options?.interval ?? 10, // Faster polling: 10ms default
}
);
};
const defaultRect = {
left: 10,
right: 20,
top: 10,
bottom: 20,
width: 10,
height: 5,
}
export const mockGetBoundingClientRect = (element: HTMLElement, rect = defaultRect) => {
vi.spyOn(element, "getBoundingClientRect").mockImplementation(() => rect as DOMRect);
}
};
export const mockGetBoundingClientRect = (
element: HTMLElement,
rect = defaultRect
) => {
vi.spyOn(element, "getBoundingClientRect").mockImplementation(
() => rect as DOMRect
);
};
export const getElementBytestId = (testId: string) => {
return document.querySelector(`[data-testid="${testId}"]`);
}
export const asyncRender: (componentChild: ComponentChild) => ReturnType<typeof render> = async (...args) => {
};
export const asyncRender: (
componentChild: ComponentChild
) => ReturnType<typeof render> = async (...args) => {
let returnValue: ReturnType<typeof render>;
await act(async () => {
returnValue = render(...args);
});
return returnValue;
}
};
63 changes: 46 additions & 17 deletions src/livePreview/__test__/live-preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import { act, fireEvent, waitFor } from "@testing-library/preact";
import crypto from "crypto";
import { vi } from "vitest";
import { sleep } from "../../__test__/utils";
import { getDefaultConfig } from "../../configManager/config.default";
import Config from "../../configManager/configManager";
import { PublicLogger } from "../../logger/logger";
Expand Down Expand Up @@ -54,12 +53,6 @@ const TITLE_CSLP_TAG = "content-type-1.entry-uid-1.en-us.field-title";
const DESC_CSLP_TAG = "content-type-2.entry-uid-2.en-us.field-description";
const LINK_CSLP_TAG = "content-type-3.entry-uid-3.en-us.field-link";

global.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));

describe("cslp tooltip", () => {
beforeEach(() => {
Config.reset();
Expand Down Expand Up @@ -349,13 +342,27 @@ describe("incoming postMessage", () => {
});

livePreviewPostMessage?.destroy({ soft: true });

// Track when INIT completes
let initCompleted = false;
livePreviewPostMessage?.on(
LIVE_PREVIEW_POST_MESSAGE_EVENTS.INIT,
mockLivePreviewInitEventListener
() => {
const result = mockLivePreviewInitEventListener();
initCompleted = true;
return result;
}
);

const livePreview = new LivePreview();
await sleep();

// Wait for INIT event to complete and event listeners to be registered
await waitFor(
() => {
expect(initCompleted).toBe(true);
},
{ timeout: 3000 }
);

// set user onChange function
const userOnChange = vi.fn();
Expand Down Expand Up @@ -386,7 +393,13 @@ describe("incoming postMessage", () => {
}

new LivePreview();
await sleep();

// Wait for async init event to be processed
await waitFor(() => {
expect(Config.get().stackDetails.contentTypeUid).toBe(
"contentTypeUid"
);
});

expect(Config.get().stackDetails).toMatchObject({
apiKey: "",
Expand All @@ -397,35 +410,51 @@ describe("incoming postMessage", () => {
});

test("should navigate forward, backward and reload page on history call", async () => {
// Track when INIT completes
let initCompleted = false;
livePreviewPostMessage?.destroy({ soft: true });
livePreviewPostMessage?.on(
LIVE_PREVIEW_POST_MESSAGE_EVENTS.INIT,
() => {
const result = mockLivePreviewInitEventListener();
initCompleted = true;
return result;
}
);

new LivePreview();
await sleep();

// Wait for INIT to complete and event listeners to be registered
await waitFor(
() => {
expect(initCompleted).toBe(true);
},
{ timeout: 3000 }
);

vi.spyOn(window.history, "forward");
vi.spyOn(window.history, "back");
vi.spyOn(window.history, "go").mockImplementation(() => {});

// for forward
livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
await livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
type: "forward",
} as HistoryLivePreviewPostMessageEventData);
await sleep(0);

expect(window.history.forward).toHaveBeenCalled();

// for back
livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
await livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
type: "backward",
} as HistoryLivePreviewPostMessageEventData);

await sleep(0);
expect(window.history.back).toHaveBeenCalled();

// for reload
livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
await livePreviewPostMessage?.send(LIVE_PREVIEW_POST_MESSAGE_EVENTS.HISTORY, {
type: "reload",
} as HistoryLivePreviewPostMessageEventData);

await sleep(0);
expect(window.history.go).toHaveBeenCalled();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ const VARIANT_TITLE_CSLP_TAG =
const DESC_CSLP_TAG = "content-type-2.entry-uid-2.en-us.field-description";
const LINK_CSLP_TAG = "content-type-3.entry-uid-3.en-us.field-link";

global.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));

describe("cslp tooltip", () => {
beforeEach(() => {
Config.reset();
Expand Down
6 changes: 0 additions & 6 deletions src/preview/__test__/contentstack-live-preview-HOC.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ Object.defineProperty(globalThis, "crypto", {
},
});

global.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));

describe("Live Preview HOC init", () => {
beforeEach(() => {
Config.reset();
Expand Down
Loading
Loading