Skip to content
Merged
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
f4538fe
vitest 3
karancs06 Nov 5, 2025
1d2b774
fix: update node version
karancs06 Nov 6, 2025
152b036
fix
karancs06 Nov 6, 2025
d3b505b
fix: before each
karancs06 Nov 7, 2025
57cdb21
fix
karancs06 Nov 9, 2025
b998426
fix: resolve remaining test timeouts in fieldToolbar and multipleElem…
karancs06 Nov 9, 2025
5e54c5e
fix: resolve test timeouts by adding missing mocks for async operations
karancs06 Nov 10, 2025
25499a8
fix: comprehensive mock improvements for CI reliability
karancs06 Nov 10, 2025
a996578
perf: optimize multipleElementAddButton tests - remove unnecessary sl…
karancs06 Nov 10, 2025
4396907
new
karancs06 Nov 10, 2025
7b0e223
skipping failures
karancs06 Nov 10, 2025
1301aa5
optimizing in vitest 3
karancs06 Nov 13, 2025
4beb284
unskipping
karancs06 Nov 13, 2025
f8475a1
feat: adding profiler
karancs06 Nov 17, 2025
6e252ea
fix: optimization
karancs06 Nov 17, 2025
5182f1b
fix: field wrapper test
karancs06 Nov 18, 2025
174b03a
increased timeout
karancs06 Nov 18, 2025
d1c3bad
fix: mocked waitforhoveroutline
karancs06 Nov 18, 2025
f62d147
fix:field toolbar test
karancs06 Nov 18, 2025
4156f60
fix:field toolbar test
karancs06 Nov 18, 2025
67aa580
fix: unskipping
karancs06 Nov 18, 2025
062f4a8
fix:increase timeout
karancs06 Nov 18, 2025
ad194ec
fix:increase timeout
karancs06 Nov 18, 2025
60345f0
fix:increase timeout
karancs06 Nov 18, 2025
a8bcacf
fix: optimize optimized
karancs06 Nov 18, 2025
18c2759
fix: merging all hover test
karancs06 Nov 18, 2025
3ff4bce
feat: timeout done
karancs06 Nov 18, 2025
c78945f
fix: passing all
karancs06 Nov 18, 2025
d85deee
fix: errors
karancs06 Nov 18, 2025
4342743
fix: error
karancs06 Nov 18, 2025
0e10e22
coverage
karancs06 Nov 19, 2025
c44d4ee
optimze coverage
karancs06 Nov 19, 2025
98a4969
some coverage files removed
karancs06 Nov 19, 2025
751a16d
removing unwanted changes
karancs06 Nov 19, 2025
a774c44
removing unwanted test changes
karancs06 Nov 19, 2025
c3275f3
increased timeout
karancs06 Nov 19, 2025
d71b08a
removed redundant cases for hover and click
karancs06 Nov 21, 2025
9e1ace0
fix: optimizing
karancs06 Nov 21, 2025
bf95a82
fix: changes
karancs06 Nov 26, 2025
a05986a
fix: changes requested done
karancs06 Nov 26, 2025
8c402f5
fix
karancs06 Nov 27, 2025
b209e20
reporter fro ci removed
karancs06 Nov 27, 2025
f13ec46
test times reduced
karancs06 Nov 27, 2025
0c83b75
timeout increased
karancs06 Nov 27, 2025
978c553
new case added
karancs06 Nov 27, 2025
d6d13ab
timeout reduced
karancs06 Nov 28, 2025
72058e5
merge pass
karancs06 Dec 1, 2025
e07055e
adding logs
karancs06 Dec 1, 2025
674e804
removing .only
karancs06 Dec 1, 2025
5665340
removing optimizing
karancs06 Dec 1, 2025
f292989
optimizing
karancs06 Dec 1, 2025
f4e8564
modified act
karancs06 Dec 1, 2025
f96f178
Revert "adding logs"
karancs06 Dec 1, 2025
8e04734
removing performance.now
karancs06 Dec 1, 2025
528c40f
remove skip
karancs06 Dec 2, 2025
c8ad283
separate files
karancs06 Dec 2, 2025
065f76e
field wrapper separate
karancs06 Dec 3, 2025
92ed05a
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