Merge pull request #2545 from PR0M3TH3AN/agents/daily/ci-health-2026-02-16-16510031680945290341

chore(ai): CI health fixes (test isolation)
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-02-15 21:55:25 -05:00
commit 3716ef4a4a
3 files changed
+83

No files matched your search

@@ -0,0 +1,31 @@
# CI Health Agent - Daily Run
**Date:** 2026-02-16
**Agent:** ci-health-agent
**Status:** Completed
## Summary
Performed a proactive health check on unit tests to identify and resolve global variable pollution risks. Since direct CI logs were inaccessible, the agent focused on local static analysis and runtime verification of test isolation.
## Changes
1. **Refactored `tests/ui/uploadModal-integration.test.mjs`**:
- Implemented logic to capture original global values (`window`, `document`, `fetch`, etc.) before tests run.
- Added robust restoration logic in the `after` hook to ensure these globals are reset or deleted, preventing side effects on subsequent tests.
2. **Refactored `tests/ui/storageService.test.mjs`**:
- Implemented capture and restore logic for globals including `indexedDB`, `IDBKeyRange`, and `crypto`.
- Added specific handling for `global.crypto` to respect its read-only nature (using `Object.defineProperty` if necessary) while ensuring clean state.
## Verification
Ran the affected tests locally to ensure they pass and verify the fix logic does not introduce regressions:
- `tests/ui/uploadModal-integration.test.mjs`: Passed
- `tests/ui/storageService.test.mjs`: Passed
- `npm run lint`: Passed
## Learnings
- `global.crypto` in Node.js 19+ is a read-only getter property. Restoration logic must account for this by either avoiding unnecessary writes or using `Object.defineProperty` to restore a value if it was successfully mocked.
- Proactive isolation of globals in tests using `jsdom` or manual polyfills is critical for preventing flaky tests in the shared Node.js process.
+29
View File
@@ -10,6 +10,7 @@ let PROVIDERS;
describe("StorageService", () => {
let dom;
const mockPubkey = "0000000000000000000000000000000000000000000000000000000000000001";
const originalGlobals = {};
// Mock Signer (NIP-04 style for simplicity)
// In a real app, this does ECIES. Here we just reverse string or something reversible for test speed/simplicity
@@ -34,6 +35,13 @@ describe("StorageService", () => {
};
before(async () => {
originalGlobals.window = global.window;
originalGlobals.indexedDB = global.indexedDB;
originalGlobals.globalThisIndexedDB = globalThis.indexedDB;
originalGlobals.IDBKeyRange = global.IDBKeyRange;
originalGlobals.globalThisIDBKeyRange = globalThis.IDBKeyRange;
originalGlobals.crypto = global.crypto;
dom = createUiDom();
// Polyfill Globals
@@ -66,6 +74,27 @@ describe("StorageService", () => {
after(() => {
if (dom) dom.cleanup();
if ('window' in originalGlobals) global.window = originalGlobals.window; else delete global.window;
if ('indexedDB' in originalGlobals) global.indexedDB = originalGlobals.indexedDB; else delete global.indexedDB;
if ('globalThisIndexedDB' in originalGlobals) globalThis.indexedDB = originalGlobals.globalThisIndexedDB; else delete globalThis.indexedDB;
if ('IDBKeyRange' in originalGlobals) global.IDBKeyRange = originalGlobals.IDBKeyRange; else delete global.IDBKeyRange;
if ('globalThisIDBKeyRange' in originalGlobals) globalThis.IDBKeyRange = originalGlobals.globalThisIDBKeyRange; else delete globalThis.IDBKeyRange;
if ('crypto' in originalGlobals) {
if (global.crypto !== originalGlobals.crypto) {
try {
global.crypto = originalGlobals.crypto;
} catch (e) {
// If read-only/getter, use defineProperty
Object.defineProperty(global, 'crypto', { value: originalGlobals.crypto, writable: true, configurable: true });
}
}
} else {
delete global.crypto;
}
});
// Since storageService is a singleton, state might persist.
+23
View File
@@ -5,6 +5,7 @@ import { createUiDom } from "./helpers/jsdom-test-helpers.mjs";
describe("UploadModal Integration", () => {
let dom;
let UploadModal;
const originalGlobals = {};
// Mock StorageService
const mockStorageService = {
@@ -77,6 +78,17 @@ describe("UploadModal Integration", () => {
`;
before(async () => {
// Capture original globals to restore later
originalGlobals.window = global.window;
originalGlobals.document = global.document;
originalGlobals.EventTarget = global.EventTarget;
originalGlobals.alert = global.alert;
originalGlobals.HTMLElement = global.HTMLElement;
originalGlobals.HTMLInputElement = global.HTMLInputElement;
originalGlobals.HTMLButtonElement = global.HTMLButtonElement;
originalGlobals.HTMLDivElement = global.HTMLDivElement;
originalGlobals.fetch = global.fetch;
dom = createUiDom();
global.window = dom.window;
global.document = dom.document;
@@ -106,6 +118,17 @@ describe("UploadModal Integration", () => {
after(() => {
if (dom) dom.cleanup();
// Restore globals
if ('window' in originalGlobals) global.window = originalGlobals.window; else delete global.window;
if ('document' in originalGlobals) global.document = originalGlobals.document; else delete global.document;
if ('EventTarget' in originalGlobals) global.EventTarget = originalGlobals.EventTarget; else delete global.EventTarget;
if ('alert' in originalGlobals) global.alert = originalGlobals.alert; else delete global.alert;
if ('HTMLElement' in originalGlobals) global.HTMLElement = originalGlobals.HTMLElement; else delete global.HTMLElement;
if ('HTMLInputElement' in originalGlobals) global.HTMLInputElement = originalGlobals.HTMLInputElement; else delete global.HTMLInputElement;
if ('HTMLButtonElement' in originalGlobals) global.HTMLButtonElement = originalGlobals.HTMLButtonElement; else delete global.HTMLButtonElement;
if ('HTMLDivElement' in originalGlobals) global.HTMLDivElement = originalGlobals.HTMLDivElement; else delete global.HTMLDivElement;
if ('fetch' in originalGlobals) global.fetch = originalGlobals.fetch; else delete global.fetch;
});
beforeEach(() => {