Skip to content

Commit 2439176

Browse files
committed
timeout changed
1 parent eb05867 commit 2439176

4 files changed

Lines changed: 136 additions & 35 deletions

File tree

src/visualBuilder/__test__/hover/fields/all-hover.test.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { FieldSchemaMap } from "../../../utils/fieldSchemaMap";
3030
import { mockDomRect } from "./mockDomRect";
3131
import { waitFor } from "@testing-library/preact";
3232
import visualBuilderPostMessage from "../../../utils/visualBuilderPostMessage";
33+
import initUI from "../../../components";
3334

3435
vi.mock("../../../utils/visualBuilderPostMessage", async () => {
3536
const { getAllContentTypes } = await vi.importActual<
@@ -125,27 +126,48 @@ describe("When an element is hovered in visual builder mode", () => {
125126
});
126127

127128
beforeEach(() => {
128-
Config.reset();
129+
// Don't reset Config - it was set in beforeAll and VisualBuilder depends on it
130+
// Only ensure mode and enable are set correctly (in case they were changed)
129131
Config.set("mode", 2);
132+
Config.set("enable", true);
130133
mousemoveEvent = new Event("mousemove", {
131134
bubbles: true,
132135
cancelable: true,
133136
});
137+
138+
// Ensure VisualBuilder container exists - recreate if it was removed
139+
// This is critical in CI where the container might not persist between tests
140+
const visualBuilderContainer = document.querySelector(
141+
'[data-testid="visual-builder__container"]'
142+
);
143+
if (!visualBuilderContainer && visualBuilder) {
144+
// Container was removed or never created - recreate it
145+
initUI({
146+
resizeObserver: (visualBuilder as any).resizeObserver,
147+
});
148+
}
134149
});
135150

136151
afterEach(async () => {
137-
// Clear test-specific DOM elements but preserve VisualBuilder container
138-
// Remove all children of body except the visual builder container
152+
// Clear test-specific DOM elements but preserve VisualBuilder container and its children
139153
const body = document.body;
140154
const visualBuilderContainer = document.querySelector(
141155
'[data-testid="visual-builder__container"]'
142156
);
157+
143158
// Remove all body children except the visual builder container
144-
Array.from(body.children).forEach((child) => {
145-
if (child !== visualBuilderContainer) {
159+
// Use a snapshot to avoid issues with live NodeList
160+
const childrenToRemove = Array.from(body.children).filter(
161+
(child) => child !== visualBuilderContainer
162+
);
163+
childrenToRemove.forEach((child) => {
164+
try {
146165
body.removeChild(child);
166+
} catch (e) {
167+
// Ignore errors if child was already removed
147168
}
148169
});
170+
149171
// Reset VisualBuilder global state to ensure clean state between tests
150172
VisualBuilder.VisualBuilderGlobalState.value = {
151173
previousSelectedEditableDOM: null,

src/visualBuilder/__test__/hover/fields/group.test.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { mockDomRect } from "./mockDomRect";
1010
import { VisualBuilder } from "../../../index";
1111
import { screen } from "@testing-library/preact";
1212
import visualBuilderPostMessage from "../../../utils/visualBuilderPostMessage";
13+
import initUI from "../../../components";
1314

1415
vi.mock("../../../utils/visualBuilderPostMessage", async () => {
1516
const { getAllContentTypes } = await vi.importActual<
@@ -88,28 +89,52 @@ describe("When an element is hovered in visual builder mode", () => {
8889
});
8990

9091
beforeEach(() => {
91-
Config.reset();
92+
// Don't reset Config - it was set in beforeAll and VisualBuilder depends on it
93+
// Only ensure mode and enable are set correctly (in case they were changed)
9294
Config.set("mode", 2);
95+
Config.set("enable", true);
9396
mousemoveEvent = new Event("mousemove", {
9497
bubbles: true,
9598
cancelable: true,
9699
});
100+
101+
// Ensure VisualBuilder container exists - recreate if it was removed
102+
// This is critical in CI where the container might not persist between tests
103+
const visualBuilderContainer = document.querySelector(
104+
'[data-testid="visual-builder__container"]'
105+
);
106+
if (!visualBuilderContainer && visualBuilder) {
107+
// Container was removed or never created - recreate it
108+
// Access the private resizeObserver through the VisualBuilder instance
109+
// We need to call initUI to recreate the container
110+
initUI({
111+
resizeObserver: (visualBuilder as any).resizeObserver,
112+
});
113+
}
97114
});
98115

99116
afterEach(() => {
100117
vi.clearAllMocks();
101-
// Clear test-specific DOM elements but preserve VisualBuilder container
102-
// Remove all children of body except the visual builder container
118+
// Clear test-specific DOM elements but preserve VisualBuilder container and its children
119+
// The VisualBuilder container contains: cursor, overlay-wrapper, focused-toolbar, hover-outline
103120
const body = document.body;
104121
const visualBuilderContainer = document.querySelector(
105122
'[data-testid="visual-builder__container"]'
106123
);
124+
107125
// Remove all body children except the visual builder container
108-
Array.from(body.children).forEach((child) => {
109-
if (child !== visualBuilderContainer) {
126+
// Use a snapshot to avoid issues with live NodeList
127+
const childrenToRemove = Array.from(body.children).filter(
128+
(child) => child !== visualBuilderContainer
129+
);
130+
childrenToRemove.forEach((child) => {
131+
try {
110132
body.removeChild(child);
133+
} catch (e) {
134+
// Ignore errors if child was already removed
111135
}
112136
});
137+
113138
// Reset VisualBuilder global state to ensure clean state between tests
114139
VisualBuilder.VisualBuilderGlobalState.value = {
115140
previousSelectedEditableDOM: null,
@@ -124,6 +149,18 @@ describe("When an element is hovered in visual builder mode", () => {
124149
referenceParentMap: {},
125150
isFocussed: false,
126151
};
152+
153+
// Ensure VisualBuilder container still exists after cleanup
154+
// If it was accidentally removed, it won't be recreated automatically
155+
const containerAfterCleanup = document.querySelector(
156+
'[data-testid="visual-builder__container"]'
157+
);
158+
if (!containerAfterCleanup && visualBuilder) {
159+
// Container was removed - this shouldn't happen, but if it does, log a warning
160+
console.warn(
161+
"VisualBuilder container was removed during test cleanup"
162+
);
163+
}
127164
});
128165

129166
afterAll(() => {

src/visualBuilder/__test__/hover/fields/single-line.test.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { FieldSchemaMap } from "../../../utils/fieldSchemaMap";
99
import { mockDomRect } from "./mockDomRect";
1010
import { screen } from "@testing-library/preact";
1111
import visualBuilderPostMessage from "../../../utils/visualBuilderPostMessage";
12+
import initUI from "../../../components";
1213

1314
vi.mock("../../../utils/visualBuilderPostMessage", async () => {
1415
const { getAllContentTypes } = await vi.importActual<
@@ -86,27 +87,48 @@ describe("When an element is hovered in visual builder mode", () => {
8687
});
8788

8889
beforeEach(() => {
89-
Config.reset();
90+
// Don't reset Config - it was set in beforeAll and VisualBuilder depends on it
91+
// Only ensure mode and enable are set correctly (in case they were changed)
9092
Config.set("mode", 2);
93+
Config.set("enable", true);
9194
mousemoveEvent = new Event("mousemove", {
9295
bubbles: true,
9396
cancelable: true,
9497
});
98+
99+
// Ensure VisualBuilder container exists - recreate if it was removed
100+
// This is critical in CI where the container might not persist between tests
101+
const visualBuilderContainer = document.querySelector(
102+
'[data-testid="visual-builder__container"]'
103+
);
104+
if (!visualBuilderContainer && visualBuilder) {
105+
// Container was removed or never created - recreate it
106+
initUI({
107+
resizeObserver: (visualBuilder as any).resizeObserver,
108+
});
109+
}
95110
});
96111

97112
afterEach(() => {
98-
// Clear test-specific DOM elements but preserve VisualBuilder container
99-
// Remove all children of body except the visual builder container
113+
// Clear test-specific DOM elements but preserve VisualBuilder container and its children
100114
const body = document.body;
101115
const visualBuilderContainer = document.querySelector(
102116
'[data-testid="visual-builder__container"]'
103117
);
118+
104119
// Remove all body children except the visual builder container
105-
Array.from(body.children).forEach((child) => {
106-
if (child !== visualBuilderContainer) {
120+
// Use a snapshot to avoid issues with live NodeList
121+
const childrenToRemove = Array.from(body.children).filter(
122+
(child) => child !== visualBuilderContainer
123+
);
124+
childrenToRemove.forEach((child) => {
125+
try {
107126
body.removeChild(child);
127+
} catch (e) {
128+
// Ignore errors if child was already removed
108129
}
109130
});
131+
110132
// Reset VisualBuilder global state to ensure clean state between tests
111133
VisualBuilder.VisualBuilderGlobalState.value = {
112134
previousSelectedEditableDOM: null,

src/visualBuilder/components/__test__/fieldToolbar.test.tsx

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,15 @@ describe("FieldToolbarComponent", () => {
115115
let mockEventDetails: VisualBuilderCslpEventDetails;
116116

117117
beforeAll(() => {
118-
// Mock FieldSchemaMap once for all tests
119-
vi.spyOn(FieldSchemaMap, "getFieldSchema").mockResolvedValue(
120-
mockMultipleLinkFieldSchema
118+
// Pre-cache field schema so getFieldSchema resolves synchronously from cache
119+
// This is much faster than async resolution
120+
// Use the actual content_type_uid from mockMultipleFieldMetadata (empty string)
121+
FieldSchemaMap.setFieldSchema(
122+
mockMultipleFieldMetadata.content_type_uid || "",
123+
{
124+
[mockMultipleFieldMetadata.fieldPath]:
125+
mockMultipleLinkFieldSchema,
126+
}
121127
);
122128
});
123129

@@ -139,8 +145,15 @@ describe("FieldToolbarComponent", () => {
139145
isDisabled: false,
140146
reason: "",
141147
});
142-
vi.mocked(FieldSchemaMap.getFieldSchema).mockResolvedValue(
143-
mockMultipleLinkFieldSchema
148+
149+
// Ensure field schema is in cache for immediate resolution
150+
// Don't use vi.spyOn - let the actual getFieldSchema use the cache
151+
FieldSchemaMap.setFieldSchema(
152+
mockMultipleFieldMetadata.content_type_uid || "",
153+
{
154+
[mockMultipleFieldMetadata.fieldPath]:
155+
mockMultipleLinkFieldSchema,
156+
}
144157
);
145158
});
146159

@@ -161,7 +174,8 @@ describe("FieldToolbarComponent", () => {
161174
/>
162175
);
163176

164-
// Use queryByTestId + waitFor for faster detection (fails immediately if not found)
177+
// Wait for button to appear after async operations complete
178+
// FieldSchema is pre-cached, so it resolves immediately, but React still needs to render
165179
const moveLeftButton = await waitFor(
166180
() => {
167181
const button = container.querySelector(
@@ -170,7 +184,7 @@ describe("FieldToolbarComponent", () => {
170184
if (!button) throw new Error("Button not found");
171185
return button;
172186
},
173-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
187+
{ timeout: 500, interval: 10 } // Reduced timeout - cached schemas resolve immediately
174188
);
175189

176190
fireEvent.click(moveLeftButton);
@@ -189,7 +203,7 @@ describe("FieldToolbarComponent", () => {
189203
/>
190204
);
191205

192-
// Use queryByTestId + waitFor for faster detection
206+
// Wait for button to appear after async operations complete
193207
const moveRightButton = await waitFor(
194208
() => {
195209
const button = container.querySelector(
@@ -198,7 +212,7 @@ describe("FieldToolbarComponent", () => {
198212
if (!button) throw new Error("Button not found");
199213
return button;
200214
},
201-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
215+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
202216
);
203217

204218
fireEvent.click(moveRightButton);
@@ -217,7 +231,7 @@ describe("FieldToolbarComponent", () => {
217231
/>
218232
);
219233

220-
// Use queryByTestId + waitFor for faster detection
234+
// Wait for button to appear after async operations complete
221235
const deleteButton = await waitFor(
222236
() => {
223237
const button = container.querySelector(
@@ -226,7 +240,7 @@ describe("FieldToolbarComponent", () => {
226240
if (!button) throw new Error("Button not found");
227241
return button;
228242
},
229-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
243+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
230244
);
231245

232246
fireEvent.click(deleteButton);
@@ -255,6 +269,7 @@ describe("FieldToolbarComponent", () => {
255269

256270
// Wait for async operations to complete (fieldSchema and variantStatus)
257271
// The icon appears after both FieldSchemaMap.getFieldSchema() and getFieldVariantStatus() complete
272+
// Pre-cached field schema resolves immediately, but React still needs time to re-render
258273
await waitFor(
259274
() => {
260275
const icon = container.querySelector(
@@ -263,15 +278,19 @@ describe("FieldToolbarComponent", () => {
263278
if (!icon) throw new Error("Variant icon not found");
264279
expect(icon).toBeInTheDocument();
265280
},
266-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
281+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
267282
);
268283
});
269284

270285
describe("'Replace button' visibility for multiple file fields", () => {
271286
beforeEach(() => {
272-
// Override the mock for this describe block (must be beforeEach to override outer beforeEach)
273-
vi.mocked(FieldSchemaMap.getFieldSchema).mockResolvedValue(
274-
mockMultipleFileFieldSchema
287+
// Pre-cache file field schema for immediate resolution
288+
FieldSchemaMap.setFieldSchema(
289+
mockMultipleFieldMetadata.content_type_uid || "",
290+
{
291+
[mockMultipleFieldMetadata.fieldPath]:
292+
mockMultipleFileFieldSchema,
293+
}
275294
);
276295
});
277296

@@ -308,13 +327,13 @@ describe("FieldToolbarComponent", () => {
308327
'[data-testid="visual-builder__focused-toolbar__multiple-field-toolbar"]'
309328
);
310329
if (!toolbar) throw new Error("Toolbar not found");
311-
330+
312331
const replaceButton = container.querySelector(
313332
'[data-testid="visual-builder-replace-file"]'
314333
);
315334
expect(replaceButton).not.toBeInTheDocument();
316335
},
317-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
336+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
318337
);
319338
});
320339

@@ -345,10 +364,11 @@ describe("FieldToolbarComponent", () => {
345364
const replaceButton = container.querySelector(
346365
'[data-testid="visual-builder-replace-file"]'
347366
);
348-
if (!replaceButton) throw new Error("Replace button not found");
367+
if (!replaceButton)
368+
throw new Error("Replace button not found");
349369
expect(replaceButton).toBeInTheDocument();
350370
},
351-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
371+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
352372
);
353373
});
354374

@@ -408,7 +428,7 @@ describe("FieldToolbarComponent", () => {
408428
expect(replaceButton).toBeDisabled();
409429
}
410430
},
411-
{ timeout: 500, interval: 10 } // Reduced to 500ms - mocks resolve immediately
431+
{ timeout: 1000, interval: 20 } // Reduced timeout - cached schemas resolve immediately
412432
);
413433
});
414434
});

0 commit comments

Comments
 (0)