Summary
npm test emits a console.error from React for src/__tests__/useCollaboration.test.ts:
console.error
An update to TestComponent inside a test was not wrapped in act(...).
...
104 | ws.onclose = () => {
105 | if (intentRef.current === 'disconnect') {
> 106 | setStatus('disconnected')
The suite still passes, but this is the only console.error in the whole run, so it's worth cleaning up before it masks a real one.
Root cause
The test double MockWebSocket.close() schedules onclose via queueMicrotask:
close() {
this.readyState = 3
queueMicrotask(() => { this.onclose?.() })
}
When the hook tears down / disconnects, that microtask runs outside any act() boundary, so the setStatus('disconnected') state update in useCollaboration.ts:106 is unwrapped.
Suggested fix
Flush the microtask inside act() so the state update is wrapped, e.g.:
await act(async () => {
ws.close()
await Promise.resolve() // let the queued microtask run inside act
})
or have the test fire fireClose() (synchronous) inside act() instead of relying on the queueMicrotask path, where the disconnect timing isn't what's under test.
Repro
npm test -- --ci 2>&1 | grep -A2 "not wrapped in act"
Environment
- Branch:
dev (reproduced on claude/testing-process-tester-rules-olTVy, docs-only branch — not introduced by it)
- Node 22, jest 29, @testing-library/react 16, React 19
https://claude.ai/code/session_01Rf9F7stxAk2WxNavwsH4Ku
Summary
npm testemits aconsole.errorfrom React forsrc/__tests__/useCollaboration.test.ts:The suite still passes, but this is the only
console.errorin the whole run, so it's worth cleaning up before it masks a real one.Root cause
The test double
MockWebSocket.close()schedulesoncloseviaqueueMicrotask:When the hook tears down / disconnects, that microtask runs outside any
act()boundary, so thesetStatus('disconnected')state update inuseCollaboration.ts:106is unwrapped.Suggested fix
Flush the microtask inside
act()so the state update is wrapped, e.g.:or have the test fire
fireClose()(synchronous) insideact()instead of relying on thequeueMicrotaskpath, where the disconnect timing isn't what's under test.Repro
Environment
dev(reproduced onclaude/testing-process-tester-rules-olTVy, docs-only branch — not introduced by it)https://claude.ai/code/session_01Rf9F7stxAk2WxNavwsH4Ku