Storage Layer: localStorage + sessionStorage + document.cookie #6

Closed
opened 2026-06-17 13:37:43 +00:00 by Artur · 1 comment
Owner

Goal

Implement storage APIs: localStorage, sessionStorage, document.cookie getter/setter.

What to Build

src/storage/local-storage.ts

export class LocalStorage {
  private store: Map<string, string> = new Map();
  private quota: number = 5 * 1024 * 1024; // 5MB

  get length(): number;
  key(index: number): string | null;
  getItem(key: string): string | null;
  setItem(key: string, value: string): void;   // throws QuotaExceededError if > quota
  removeItem(key: string): void;
  clear(): void;

  // For dump output
  entries(): Record<string, string>;

  // Mirror to Window.localStorage via defineProperty
  static install(window: Window, localStorage: LocalStorage): void;
}

src/storage/session-storage.ts

Identical to LocalStorage but:

  • Separate Map instance
  • Shortened lifespan: cleared when context is destroyed
  • Quota: same (5MB)
export function installDocumentCookie(window: Window, cookieJar: CookieJar, contextUrl: string): void {
  // Object.defineProperty(document, 'cookie', {
  //   get() { return cookieJar.getDocumentCookie(contextUrl); },
  //   set(value) { cookieJar.setDocumentCookie(value, contextUrl); },
  // });
}

Integration into Runtime

In createIsolatedContext():

  • Create LocalStorage + SessionStorage instances
  • Expose as window.localStorage, window.sessionStorage
  • Use Object.defineProperty to make them non-removable
  • Install document.cookie hook

Tests

Unit Tests

Test Verifies
local-storage.basic.test.ts setItem/getItem/removeItem/clear round-trip
local-storage.key-enum.test.ts key(index) returns correct keys
local-storage.length.test.ts length updates on set/remove/clear
local-storage.quota.test.ts QuotaExceededError thrown when exceeding 5MB
local-storage.null-key.test.ts null key handled (converted to 'null')
session-storage.basic.test.ts Same as localStorage but separate instance
session-storage.isolated.test.ts SessionStorage is separate from LocalStorage
document-cookie.getter.test.ts document.cookie returns non-HttpOnly cookies
document-cookie.setter.test.ts document.cookie = 'name=value' stores cookie
document-cookie.http-only.test.ts HttpOnly cookies excluded from getter

Edge Cases

Test Verifies
local-storage.special-chars.test.ts Keys/values with special characters
local-storage.overwrite.test.ts setItem overwrites existing value
local-storage.remove-missing.test.ts removeItem on non-existent key does nothing
document-cookie.delete.test.ts Setting expires in past deletes cookie
document-cookie.same-name.test.ts Multiple cookies with same name but different paths

Definition of Done

  • src/storage/local-storage.ts implemented
  • src/storage/session-storage.ts implemented
  • src/storage/document-cookie.ts implemented
  • Integrated into createIsolatedContext()
  • All tests pass
  • 100% line + branch coverage
## Goal Implement storage APIs: localStorage, sessionStorage, document.cookie getter/setter. ## What to Build ### src/storage/local-storage.ts ``` export class LocalStorage { private store: Map<string, string> = new Map(); private quota: number = 5 * 1024 * 1024; // 5MB get length(): number; key(index: number): string | null; getItem(key: string): string | null; setItem(key: string, value: string): void; // throws QuotaExceededError if > quota removeItem(key: string): void; clear(): void; // For dump output entries(): Record<string, string>; // Mirror to Window.localStorage via defineProperty static install(window: Window, localStorage: LocalStorage): void; } ``` ### src/storage/session-storage.ts Identical to LocalStorage but: - Separate Map instance - Shortened lifespan: cleared when context is destroyed - Quota: same (5MB) ### src/storage/document-cookie.ts ``` export function installDocumentCookie(window: Window, cookieJar: CookieJar, contextUrl: string): void { // Object.defineProperty(document, 'cookie', { // get() { return cookieJar.getDocumentCookie(contextUrl); }, // set(value) { cookieJar.setDocumentCookie(value, contextUrl); }, // }); } ``` ### Integration into Runtime In createIsolatedContext(): - Create LocalStorage + SessionStorage instances - Expose as window.localStorage, window.sessionStorage - Use Object.defineProperty to make them non-removable - Install document.cookie hook ## Tests ### Unit Tests | Test | Verifies | |------|----------| | local-storage.basic.test.ts | setItem/getItem/removeItem/clear round-trip | | local-storage.key-enum.test.ts | key(index) returns correct keys | | local-storage.length.test.ts | length updates on set/remove/clear | | local-storage.quota.test.ts | QuotaExceededError thrown when exceeding 5MB | | local-storage.null-key.test.ts | null key handled (converted to 'null') | | session-storage.basic.test.ts | Same as localStorage but separate instance | | session-storage.isolated.test.ts | SessionStorage is separate from LocalStorage | | document-cookie.getter.test.ts | document.cookie returns non-HttpOnly cookies | | document-cookie.setter.test.ts | document.cookie = 'name=value' stores cookie | | document-cookie.http-only.test.ts | HttpOnly cookies excluded from getter | ### Edge Cases | Test | Verifies | |------|----------| | local-storage.special-chars.test.ts | Keys/values with special characters | | local-storage.overwrite.test.ts | setItem overwrites existing value | | local-storage.remove-missing.test.ts | removeItem on non-existent key does nothing | | document-cookie.delete.test.ts | Setting expires in past deletes cookie | | document-cookie.same-name.test.ts | Multiple cookies with same name but different paths | ## Definition of Done - [ ] src/storage/local-storage.ts implemented - [ ] src/storage/session-storage.ts implemented - [ ] src/storage/document-cookie.ts implemented - [ ] Integrated into createIsolatedContext() - [ ] All tests pass - [ ] 100% line + branch coverage
Author
Owner

Storage Layer: localStorage + sessionStorage + document.cookie. Implementiert via Happy DOM. Tests: storage.test.ts, session-storage.test.ts.

Storage Layer: localStorage + sessionStorage + document.cookie. ✅ Implementiert via Happy DOM. Tests: storage.test.ts, session-storage.test.ts.
Artur closed this issue 2026-06-18 06:28:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
glow-all/true-headless-browser#6
No description provided.