fix(02-07): loading overlay can never wedge the Chat/AIUI UI permanently
Demo images / Build & push demo images (push) Failing after 2m12s

Belt-and-suspenders fix on top of AIUI's own root-cause fix (the
archyBridge origin bug, fixed in the AIUI repo): the archy-side loading
overlay now gets pointer-events:none (it has no interactive content of
its own, so it should never have blocked clicks reaching the iframe
underneath) and a bounded 8s timeout that unconditionally hides it if
no 'ready' message ever arrives — regardless of AIUI/backend state.
The timeout only dismisses the overlay; it does not fabricate a
successful connection, so the connected indicator still reflects
reality.

Two new tests in chatAiuiEmbed.test.ts cover the timeout firing at
exactly 8s and not firing prematurely.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-07-30 20:19:28 -04:00
co-authored by Claude Fable 5
parent 08ee5ed036
commit faf4a75ddf
2 changed files with 71 additions and 2 deletions
@@ -142,4 +142,42 @@ describe('Chat / AIUI embed URL stability + D-14 defaults (02-07)', () => {
expect(wrapper.find('.chat-loading').exists()).toBe(false)
wrapper.unmount()
})
// Belt-and-suspenders backstop added after live testing found the overlay
// could wedge the UI when the 'ready' handshake never arrives (a real bug,
// separately fixed at its root cause in AIUI's archyBridge.ts) — this
// proves the archy side never depends on that fix alone.
it('dismisses the loading overlay after a bounded timeout even if no ready message ever arrives', async () => {
vi.useFakeTimers()
try {
const { wrapper } = mountChatInKeepAlive()
expect(wrapper.find('.chat-loading').exists()).toBe(true)
await vi.advanceTimersByTimeAsync(7999)
expect(wrapper.find('.chat-loading').exists()).toBe(true)
await vi.advanceTimersByTimeAsync(1)
expect(wrapper.find('.chat-loading').exists()).toBe(false)
// The connection indicator must NOT falsely report connected — the
// timeout only dismisses the blocking overlay, it does not fabricate
// a successful handshake.
expect(wrapper.find('[title="chat.aiuiConnected"]').exists()).toBe(false)
wrapper.unmount()
} finally {
vi.useRealTimers()
}
})
it('does not dismiss the loading overlay before the timeout elapses', async () => {
vi.useFakeTimers()
try {
const { wrapper } = mountChatInKeepAlive()
await vi.advanceTimersByTimeAsync(4000)
expect(wrapper.find('.chat-loading').exists()).toBe(true)
wrapper.unmount()
} finally {
vi.useRealTimers()
}
})
})