* feat: persist AI conversations and add chat history Store transcripts and attachment previews in IndexedDB, separate conversation history from transport lifetime, and add document-aware switching with shared Storybook coverage. Preserve interrupted activity and guard stale writes and async switches. * test: group chat history tests by domain * feat: simplify chat history navigation and diagnostics Use a compact header with searchable document-scoped history and a correctly anchored conversation menu. Move diagnostic copying into the menu with copy-result feedback, and separate Storybook fixtures from composition. * fix: address chat history review findings * test: cover harness shutdown and restored chat scrolling * fix: preserve Portless proxy port in MCP routes * docs: clarify UI animation conventions * feat: configure reasoning display and animate disclosure * fix: separate transcript following from reasoning disclosure * fix: restore selected chat after document recovery * refactor: separate chat history persistence and sessions * style: format reasoning story imports
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
import { expect, test } from '#tests/helpers/chat/fixture'
|
|
|
|
test('composer enables submission only for non-empty input', async ({ configuredChat: chat }) => {
|
|
await expect(chat.sendButton).toBeDisabled()
|
|
await chat.input.fill('Make a red rectangle')
|
|
await expect(chat.sendButton).toBeEnabled()
|
|
})
|
|
|
|
test('composer grows with multiline input', async ({ configuredChat: chat }) => {
|
|
await chat.input.fill('First line')
|
|
const initialHeight = (await chat.input.boundingBox())?.height ?? 0
|
|
await chat.input.fill(Array.from({ length: 8 }, (_, index) => `Line ${index + 1}`).join('\n'))
|
|
await expect
|
|
.poll(async () => (await chat.input.boundingBox())?.height ?? 0)
|
|
.toBeGreaterThan(initialHeight)
|
|
})
|
|
|
|
test('Shift+Enter inserts a line break without submitting', async ({ configuredChat: chat }) => {
|
|
await chat.input.fill('First line')
|
|
await chat.input.press('Shift+Enter')
|
|
await chat.input.type('Second line')
|
|
|
|
await expect(chat.input).toHaveValue('First line\nSecond line')
|
|
await expect(chat.page.getByText('First line', { exact: true })).toBeHidden()
|
|
})
|
|
|
|
test('Enter submits and clears input', async ({ configuredChat: chat }) => {
|
|
await chat.submit('Hello there')
|
|
|
|
await expect(chat.userMessage()).toHaveText('Hello there')
|
|
await expect(chat.input).toHaveValue('')
|
|
})
|