Skip to content

Commit 96913d6

Browse files
committed
test: Storybook tests WIP
1 parent 17b027f commit 96913d6

File tree

5 files changed

+89
-32
lines changed

5 files changed

+89
-32
lines changed

tools/server/webui/src/lib/components/app/chat/ChatScreen/ChatScreen.svelte

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import { processFilesToChatUploaded } from '$lib/utils/process-uploaded-files';
44
import { serverStore } from '$lib/stores/server.svelte';
55
import { isFileTypeSupported } from '$lib/constants/supported-file-types';
6-
import {
7-
filterFilesByModalities,
8-
generateModalityErrorMessage
9-
} from '$lib/utils/modality-file-validation';
6+
import { filterFilesByModalities } from '$lib/utils/modality-file-validation';
107
import { supportsVision, supportsAudio, serverError, serverLoading } from '$lib/stores/server.svelte';
118
import { ChatForm, ChatScreenHeader, ChatMessages, ServerInfo, ServerErrorSplash, ServerLoadingSplash } from '$lib/components/app';
129
import {

tools/server/webui/src/stories/ChatForm.stories.svelte

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,45 @@
136136
/>
137137

138138

139+
<Story
140+
name="AudioModality"
141+
args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]' }}
142+
play={async ({ canvas, userEvent }) => {
143+
mockServerProps(mockConfigs.audioOnly);
144+
145+
await waitFor(() => {
146+
const fileInput = document.querySelector('input[type="file"]');
147+
const acceptAttr = fileInput?.getAttribute('accept');
148+
return acceptAttr;
149+
});
150+
151+
// Test initial file input state (should accept audio but not images)
152+
const fileInput = document.querySelector('input[type="file"]');
153+
const acceptAttr = fileInput?.getAttribute('accept');
154+
console.log(acceptAttr);
155+
await expect(fileInput).toHaveAttribute('accept');
156+
await expect(acceptAttr).not.toContain('image/');
157+
await expect(acceptAttr).toContain('audio/');
158+
159+
const fileUploadButton = canvas.getByText('Attach files');
160+
await userEvent.click(fileUploadButton);
161+
162+
// Test that record button is enabled (audio support)
163+
const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1];
164+
await expect(recordButton).not.toBeDisabled();
165+
166+
// Test that Images button is disabled (no vision support)
167+
const imagesButton = document.querySelector('.images-button');
168+
await expect(imagesButton).toHaveAttribute('data-disabled');
169+
170+
// Test that Audio button is enabled (audio support)
171+
const audioButton = document.querySelector('.audio-button');
172+
await expect(audioButton).not.toHaveAttribute('data-disabled');
173+
174+
console.log('✅ Audio modality: Audio/Recording enabled, Images disabled');
175+
}}
176+
/>
177+
139178
<Story
140179
name="FileAttachments"
141180
args={{

tools/server/webui/src/stories/ChatHeader.stories.svelte

Lines changed: 0 additions & 14 deletions
This file was deleted.

tools/server/webui/src/stories/ChatMessage.stories.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import ChatMessage from '$lib/components/app/chat/ChatMessages/ChatMessage.svelte';
44
55
const { Story } = defineMeta({
6-
title: 'Components/ChatMessage',
6+
title: 'Components/ChatScreen/ChatMessage',
77
component: ChatMessage,
88
parameters: {
99
layout: 'centered'

tools/server/webui/src/stories/ChatSidebar.stories.svelte

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<script module lang="ts">
22
import { defineMeta } from '@storybook/addon-svelte-csf';
33
import ChatSidebar from '$lib/components/app/chat/ChatSidebar/ChatSidebar.svelte';
4+
import type { DatabaseConversation } from '$lib/types/database.d.ts';
5+
import { waitFor, within, expect } from 'storybook/internal/test';
6+
import { screen } from 'storybook/test';
47
58
const { Story } = defineMeta({
69
title: 'Components/ChatSidebar',
@@ -45,25 +48,57 @@
4548
];
4649
</script>
4750

48-
<Story name="Default">
49-
<div class="bg-background h-screen w-80 border-r">
51+
<Story
52+
asChild
53+
name="Default"
54+
play={async ({ canvas }) => {
55+
const { chatStore } = await import('$lib/stores/chat.svelte');
56+
57+
waitFor(() => setTimeout(() => {
58+
chatStore.conversations = mockConversations;
59+
}, 0));
60+
}}
61+
>
62+
<div class="bg-background h-screen w-[18rem]">
63+
5064
<ChatSidebar />
5165
</div>
5266
</Story>
5367

54-
<Story
68+
<Story
69+
asChild
5570
name="SearchActive"
56-
play={async ({ canvasElement }) => {
57-
// Wait for component to mount
58-
await new Promise(resolve => setTimeout(resolve, 100));
71+
play={async ({ userEvent, canvasElement }) => {
72+
let canvas = within(canvasElement);
73+
const { chatStore } = await import('$lib/stores/chat.svelte');
5974

60-
// Find and interact with search input
61-
const searchInput = canvasElement.querySelector('input[placeholder*="Search"]') as HTMLInputElement;
62-
if (searchInput) {
63-
searchInput.focus();
64-
searchInput.value = 'Python';
65-
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
66-
}
75+
waitFor(() => setTimeout(() => {
76+
chatStore.conversations = mockConversations;
77+
}, 0));
78+
79+
const searchTrigger = screen.getByText('Search conversations');
80+
userEvent.click(searchTrigger);
81+
82+
// canvas = within(canvasElement);
83+
84+
// const searchInput = canvas.getAllByPlaceholderText('Search conversations...');
85+
86+
console.log(canvasElement);
87+
88+
// await expect(canvas.getByRole('textbox')).toBeInTheDocument();
89+
}}
90+
>
91+
<div class="bg-background h-screen w-[18rem]">
92+
<ChatSidebar />
93+
</div>
94+
</Story>
95+
96+
<Story
97+
name="Empty"
98+
play={async ({ canvas }) => {
99+
// Mock empty conversations store
100+
const { chatStore } = await import('$lib/stores/chat.svelte');
101+
chatStore.conversations = [];
67102
}}
68103
>
69104
<div class="bg-background h-screen w-80 border-r">

0 commit comments

Comments
 (0)