Phase 2c: ResizeObserver-Shim verbessern — Callback-Unterstützung (E5 fix) #43

Closed
opened 2026-06-18 06:17:58 +00:00 by Artur · 1 comment
Owner

Problembeschreibung

Test E5 ("ResizeObserver — wird im useEffect erstellt") schlägt fehl. Der aktuelle ResizeObserver-Shim in src/observers/ ist ein reines noop — er erstellt sich selbst, feuert aber nie Callbacks. React-Komponenten die useEffect mit ResizeObserver verwenden, erwarten dass der Observer tatsächlich callback-basiert arbeitet.

Ursache

Aktueller ResizeObserver (vereinfacht):

class ResizeObserver {
  constructor(callback) {} // callback wird nie aufgerufen
  observe(target) {}
  unobserve(target) {}
  disconnect() {}
}

React erwartet dass observe() initial einen Callback mit contentRect feuert, ähnlich wie ein realer Browser. Ohne das bleibt die Komponente im "loading"-Zustand.

Lösungsansätze

Option A: Timer-basierter Shim (empfohlen)

ResizeObserver feuert Callbacks asynchron via requestAnimationFrame (oder setTimeout als Fallback):

class ResizeObserver {
  private callback: ResizeObserverCallback;
  private observed: Set<Element> = new Set();
  
  constructor(callback: ResizeObserverCallback) { ... }
  private schedule() { requestAnimationFrame(() => this.flush()); }
  private flush() {
    const entries = [...this.observed].map(el => ({
      target: el,
      contentRect: el.getBoundingClientRect(),
    }));
    this.callback(entries, this);
    this.schedule();
  }
  observe(target: Element) { this.observed.add(target); }
  unobserve(target: Element) { this.observed.delete(target); }
  disconnect() { this.observed.clear(); }
}

Option B: Manuelles Trigger-System

ResizeObserver feuert nur bei explizitem page.triggerResize() — besser für deterministische Tests.

Akzeptanzkriterien

  • E5 Test läuft durch: ResizeObserver erstellt im useEffect feuert Callback
  • contentRect liefert sinnvolle Default-Werte (width/height/x/y)
  • disconnect() entfernt Elemente aus der Observe-Liste
  • Keine Regression: keine zusätzlichen Timer-Leaks
  • Bestehende 1422 Tests bleiben grün

Betroffene Dateien

  • src/observers/resize-observer.ts (oder equivalent)
  • tests/interaction/react-comprehensive.test.ts (E5)
  • tests/unit/observers.test.ts (neue Tests)

Cross-Referenzen

  • E5 (einer der 4 pre-existing failures)
  • #10 (Observer Layer)
## Problembeschreibung Test E5 ("ResizeObserver — wird im useEffect erstellt") schlägt fehl. Der aktuelle ResizeObserver-Shim in `src/observers/` ist ein reines noop — er erstellt sich selbst, feuert aber nie Callbacks. React-Komponenten die `useEffect` mit ResizeObserver verwenden, erwarten dass der Observer tatsächlich callback-basiert arbeitet. ## Ursache Aktueller ResizeObserver (vereinfacht): ``` class ResizeObserver { constructor(callback) {} // callback wird nie aufgerufen observe(target) {} unobserve(target) {} disconnect() {} } ``` React erwartet dass `observe()` initial einen Callback mit `contentRect` feuert, ähnlich wie ein realer Browser. Ohne das bleibt die Komponente im "loading"-Zustand. ## Lösungsansätze ### Option A: Timer-basierter Shim (empfohlen) ResizeObserver feuert Callbacks asynchron via requestAnimationFrame (oder setTimeout als Fallback): ```typescript class ResizeObserver { private callback: ResizeObserverCallback; private observed: Set<Element> = new Set(); constructor(callback: ResizeObserverCallback) { ... } private schedule() { requestAnimationFrame(() => this.flush()); } private flush() { const entries = [...this.observed].map(el => ({ target: el, contentRect: el.getBoundingClientRect(), })); this.callback(entries, this); this.schedule(); } observe(target: Element) { this.observed.add(target); } unobserve(target: Element) { this.observed.delete(target); } disconnect() { this.observed.clear(); } } ``` ### Option B: Manuelles Trigger-System ResizeObserver feuert nur bei explizitem `page.triggerResize()` — besser für deterministische Tests. ## Akzeptanzkriterien - [ ] E5 Test läuft durch: ResizeObserver erstellt im useEffect feuert Callback - [ ] contentRect liefert sinnvolle Default-Werte (width/height/x/y) - [ ] disconnect() entfernt Elemente aus der Observe-Liste - [ ] Keine Regression: keine zusätzlichen Timer-Leaks - [ ] Bestehende 1422 Tests bleiben grün ## Betroffene Dateien - `src/observers/resize-observer.ts` (oder equivalent) - `tests/interaction/react-comprehensive.test.ts` (E5) - `tests/unit/observers.test.ts` (neue Tests) ## Cross-Referenzen - E5 (einer der 4 pre-existing failures) - #10 (Observer Layer)
Author
Owner

Superseded by Phase 1 (Quick API Fixes) im neuen Action Plan. ResizeObserver wird zusammen mit anderen API-Fixes angegangen.

Superseded by Phase 1 (Quick API Fixes) im neuen Action Plan. ResizeObserver wird zusammen mit anderen API-Fixes angegangen.
Artur closed this issue 2026-06-18 07:12:24 +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#43
No description provided.