openhands / __tests__ /vitest-setup-progress-event.test.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
c0af099 verified
Raw History Blame Contribute Delete
2.56 kB
import { describe, expect, it } from "vitest";
/**
* Regression test for the `ReferenceError: ProgressEvent is not defined`
* unhandled rejection that intermittently failed whole CI runs
* (all tests green, exit code 1).
*
* MSW's XMLHttpRequest interceptor evaluates the bare `ProgressEvent`
* identifier inside async response callbacks. Vitest's jsdom teardown does
* `keys.forEach((key) => delete global[key])`, so any *own* property named
* `ProgressEvent` — jsdom's, or a polyfill a setup file installed — is gone
* once the environment for a test file is torn down. A callback that settles
* after that point then throws.
*
* `vitest.setup.ts` therefore keeps a fallback on `globalThis`'s prototype
* chain, which `delete` cannot reach. This test performs exactly the deletion
* teardown performs and asserts the identifier still resolves.
*/
describe("ProgressEvent fallback in vitest.setup.ts", () => {
it("resolves the bare identifier after teardown deletes the own property", () => {
const live = Object.getOwnPropertyDescriptor(globalThis, "ProgressEvent");
expect(live).toBeDefined();
// What vitest's jsdom teardown does to every jsdom key.
delete (globalThis as { ProgressEvent?: unknown }).ProgressEvent;
try {
// Before the fix this is "undefined", and the construction below throws
// ReferenceError — the exact failure seen in CI.
expect(typeof ProgressEvent).toBe("function");
const event = new ProgressEvent("error", {
lengthComputable: true,
loaded: 3,
total: 7,
});
expect(event).toBeInstanceOf(Event);
expect(event.type).toBe("error");
expect(event.lengthComputable).toBe(true);
expect(event.loaded).toBe(3);
expect(event.total).toBe(7);
} finally {
if (live) Object.defineProperty(globalThis, "ProgressEvent", live);
}
});
it("prefers jsdom's own ProgressEvent while the environment is alive", () => {
// The own property shadows the prototype fallback, so nothing observes the
// stand-in until teardown removes jsdom's class.
expect(
Object.getOwnPropertyDescriptor(globalThis, "ProgressEvent"),
).toBeDefined();
expect(new ProgressEvent("progress").type).toBe("progress");
});
it("does not add ProgressEvent to plain objects", () => {
// The fallback lives on globalThis's own prototype chain, which in Node is
// not Object.prototype — so it must not leak onto ordinary objects.
expect("ProgressEvent" in {}).toBe(false);
});
});