Skip to content

Commit 3ae9d12

Browse files
jvigliottaakhenry
authored andcommitted
modified the sanitizeForSerialization method to remove unnecessary re… (#7950)
modified the sanitizeForSerialization method to remove unnecessary recursion, update e2e test to CORRECTLY test the functionality
1 parent f890be6 commit 3ae9d12

File tree

2 files changed

+43
-56
lines changed

2 files changed

+43
-56
lines changed

e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js

+27-40
Original file line numberDiff line numberDiff line change
@@ -599,46 +599,33 @@ test.describe('Display Layout', () => {
599599

600600
// Verify filtering is working correctly
601601

602-
// Create a promise that resolves when we've seen enough new rows added
603-
const rowsMutationPromise = page.evaluate(() => {
604-
return new Promise((resolve) => {
605-
const targetTable = document.querySelector(
606-
'table[aria-label="Table Filter Off Value table content"]'
607-
);
608-
const config = { childList: true, subtree: true };
609-
let changeCount = 0;
610-
const requiredChanges = 20; // Number of changes to wait for
611-
612-
const observer = new MutationObserver((mutations) => {
613-
mutations.forEach((mutation) => {
614-
if (mutation.type === 'childList') {
615-
// Count added nodes
616-
changeCount += mutation.addedNodes.length;
617-
}
618-
});
619-
620-
// Check if the required number of changes has been met
621-
if (changeCount >= requiredChanges) {
622-
observer.disconnect(); // Disconnect observer after the required changes
623-
resolve();
624-
}
625-
});
626-
627-
observer.observe(targetTable, config);
628-
});
629-
});
630-
631-
await rowsMutationPromise;
632-
633-
// Check ON table doesn't have any OFF values
634-
await expect(tableFilterOn.locator('td[title="OFF"]')).toHaveCount(0);
635-
const onCount = await tableFilterOn.locator('td[title="ON"]').count();
636-
await expect(onCount).toBeGreaterThan(0);
637-
638-
// Check OFF table doesn't have any ON values
639-
await expect(tableFilterOff.locator('td[title="ON"]')).toHaveCount(0);
640-
const offCount = await tableFilterOff.locator('td[title="OFF"]').count();
641-
await expect(offCount).toBeGreaterThan(0);
602+
// Check that no filtered values appear for at least 2 seconds
603+
const VERIFICATION_TIME = 2000; // 2 seconds
604+
const CHECK_INTERVAL = 100; // Check every 100ms
605+
606+
// Create a promise that will check for filtered values periodically
607+
const checkForCorrectValues = new Promise((resolve, reject) => {
608+
const interval = setInterval(async () => {
609+
const offCount = await tableFilterOn.locator('td[title="OFF"]').count();
610+
const onCount = await tableFilterOff.locator('td[title="ON"]').count();
611+
if (offCount > 0 || onCount > 0) {
612+
clearInterval(interval);
613+
reject(
614+
new Error(
615+
`Found ${offCount} OFF and ${onCount} ON values when expecting 0 OFF and 0 ON`
616+
)
617+
);
618+
}
619+
}, CHECK_INTERVAL);
620+
621+
// After VERIFICATION_TIME, if no filtered values were found, resolve successfully
622+
setTimeout(() => {
623+
clearInterval(interval);
624+
resolve();
625+
}, VERIFICATION_TIME);
626+
});
627+
628+
await expect(checkForCorrectValues).resolves.toBeUndefined();
642629
});
643630
});
644631

src/api/telemetry/TelemetryAPI.js

+16-16
Original file line numberDiff line numberDiff line change
@@ -254,34 +254,34 @@ export default class TelemetryAPI {
254254
* Sanitizes objects for consistent serialization by:
255255
* 1. Removing non-plain objects (class instances) and functions
256256
* 2. Sorting object keys alphabetically to ensure consistent ordering
257-
* 3. Recursively processing nested objects
258-
*
259-
* Note: When used as a JSON.stringify replacer, this function will process objects
260-
* twice - once for the initial sorting and again when JSON.stringify processes the
261-
* sorted result. This is acceptable for small options objects, which is the
262-
* intended use case.
263257
*/
264258
sanitizeForSerialization(key, value) {
265259
// Handle null and primitives directly
266260
if (value === null || typeof value !== 'object') {
267261
return value;
268262
}
269263

270-
// Remove functions and non-plain objects by returning undefined
271-
if (typeof value === 'function' || Object.getPrototypeOf(value) !== Object.prototype) {
264+
// Remove functions and non-plain objects (except arrays)
265+
if (
266+
typeof value === 'function' ||
267+
(Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value))
268+
) {
272269
return undefined;
273270
}
274271

275-
// Handle plain objects
276-
const sortedObject = {};
277-
const keys = Object.keys(value).sort();
278-
for (const objectKey of keys) {
279-
const itemValue = value[objectKey];
280-
const sanitizedValue = this.sanitizeForSerialization(objectKey, itemValue);
281-
sortedObject[objectKey] = sanitizedValue;
272+
// For plain objects, just sort the keys
273+
if (!Array.isArray(value)) {
274+
const sortedObject = {};
275+
const sortedKeys = Object.keys(value).sort();
276+
277+
sortedKeys.forEach((objectKey) => {
278+
sortedObject[objectKey] = value[objectKey];
279+
});
280+
281+
return sortedObject;
282282
}
283283

284-
return sortedObject;
284+
return value;
285285
}
286286

287287
/**

0 commit comments

Comments
 (0)