Skip to content

Commit 1c8cec6

Browse files
fix: properly mock window.location in JSDOM environment
Use JSDOM's ability to delete non-configurable properties to create a proper window.location mock. This approach works reliably across different CI environments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 7c0f654 commit 1c8cec6

File tree

1 file changed

+22
-29
lines changed

1 file changed

+22
-29
lines changed

client/src/components/__tests__/AuthDebugger.test.tsx

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -84,38 +84,31 @@ Object.defineProperty(window, "sessionStorage", {
8484
value: sessionStorageMock,
8585
});
8686

87-
// Mock window.location in a way that works in all environments
88-
const mockLocation: Partial<Location> = {
87+
// In JSDOM, we can delete window.location even though it's non-configurable
88+
// This is a quirk of JSDOM that we can use to our advantage
89+
delete (window as { location?: Location }).location;
90+
91+
// Create a mock location object that tracks href changes
92+
interface MockLocation extends Partial<Location> {
93+
_href: string;
94+
}
95+
96+
const mockLocation: MockLocation = {
8997
origin: "http://localhost:3000",
98+
_href: "",
99+
get href() {
100+
return this._href;
101+
},
102+
set href(value: string) {
103+
this._href = value;
104+
},
105+
assign: jest.fn(),
106+
reload: jest.fn(),
107+
replace: jest.fn(),
90108
};
91109

92-
// Use global to access window in a type-safe way
93-
const globalWindow = global as unknown as Window & typeof globalThis;
94-
95-
// Try to delete first, then redefine
96-
try {
97-
delete (globalWindow as { location?: Location }).location;
98-
Object.defineProperty(globalWindow, "location", {
99-
value: mockLocation,
100-
writable: true,
101-
configurable: true,
102-
});
103-
} catch {
104-
// If that fails, try to just override the origin property
105-
try {
106-
Object.defineProperty(globalWindow.location, "origin", {
107-
value: "http://localhost:3000",
108-
writable: true,
109-
configurable: true,
110-
});
111-
} catch {
112-
// As a last resort, mock what we need for the tests
113-
jest.spyOn(window, "location", "get").mockReturnValue({
114-
...window.location,
115-
origin: "http://localhost:3000",
116-
});
117-
}
118-
}
110+
// Assign the mock to window.location
111+
(window as { location: Location }).location = mockLocation as Location;
119112

120113
describe("AuthDebugger", () => {
121114
const defaultAuthState = EMPTY_DEBUGGER_STATE;

0 commit comments

Comments
 (0)