mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-30 12:09:15 +00:00
ci(frontend): shim storage in test setup
Add a Vitest setup storage shim for localStorage and sessionStorage when Node/jsdom does not provide usable storage. This fixes the Node 26 frontend CI failures where tests accessed localStorage during setup.
This commit is contained in:
@@ -9,6 +9,67 @@ class MockResizeObserver {
|
|||||||
}
|
}
|
||||||
globalThis.ResizeObserver = globalThis.ResizeObserver ?? MockResizeObserver;
|
globalThis.ResizeObserver = globalThis.ResizeObserver ?? MockResizeObserver;
|
||||||
|
|
||||||
|
type StorageName = 'localStorage' | 'sessionStorage';
|
||||||
|
|
||||||
|
class TestStorage {
|
||||||
|
private readonly store = new Map<string, string>();
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this.store.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.store.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
getItem(key: string) {
|
||||||
|
return this.store.get(String(key)) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
key(index: number) {
|
||||||
|
return Array.from(this.store.keys())[index] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(key: string) {
|
||||||
|
this.store.delete(String(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(key: string, value: string) {
|
||||||
|
this.store.set(String(key), String(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUsableStorage(name: StorageName): Storage {
|
||||||
|
try {
|
||||||
|
const storage = window[name];
|
||||||
|
storage.setItem('__sencho_storage_probe__', '1');
|
||||||
|
storage.removeItem('__sencho_storage_probe__');
|
||||||
|
return storage;
|
||||||
|
} catch {
|
||||||
|
return new TestStorage() as Storage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function defineStorage(name: StorageName, storage: Storage) {
|
||||||
|
for (const target of [window, globalThis]) {
|
||||||
|
try {
|
||||||
|
Object.defineProperty(target, name, {
|
||||||
|
value: storage,
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
Reflect.set(target, name, storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
defineStorage('localStorage', getUsableStorage('localStorage'));
|
||||||
|
defineStorage('sessionStorage', getUsableStorage('sessionStorage'));
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof window !== 'undefined' && !window.matchMedia) {
|
if (typeof window !== 'undefined' && !window.matchMedia) {
|
||||||
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
|
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
|
||||||
matches: false,
|
matches: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user