From 2d556bb93c57825cdb46526a3bfe6c88ea74d0bc Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Sat, 29 Nov 2025 02:36:41 +0100 Subject: [PATCH] test: Fix Storybook mocks --- .../webui/src/stories/ChatForm.stories.svelte | 32 ++++++++----------- .../src/stories/ChatSidebar.stories.svelte | 1 - .../src/stories/fixtures/storybook-mocks.ts | 31 ++++++++++++++++++ 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/tools/server/webui/src/stories/ChatForm.stories.svelte b/tools/server/webui/src/stories/ChatForm.stories.svelte index 82848e4fbf..9856bf7c92 100644 --- a/tools/server/webui/src/stories/ChatForm.stories.svelte +++ b/tools/server/webui/src/stories/ChatForm.stories.svelte @@ -70,17 +70,19 @@ await expect(acceptAttr).not.toContain('image/'); await expect(acceptAttr).not.toContain('audio/'); + // Open file attachments dropdown const fileUploadButton = canvas.getByText('Attach files'); - await userEvent.click(fileUploadButton); - const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1]; + // Check dropdown menu items are disabled (no modalities) const imagesButton = document.querySelector('.images-button'); const audioButton = document.querySelector('.audio-button'); - await expect(recordButton).toBeDisabled(); await expect(imagesButton).toHaveAttribute('data-disabled'); await expect(audioButton).toHaveAttribute('data-disabled'); + + // Close dropdown by pressing Escape + await userEvent.keyboard('{Escape}'); }} /> @@ -97,13 +99,10 @@ const acceptAttr = fileInput?.getAttribute('accept'); console.log('Vision modality accept attr:', acceptAttr); + // Open file attachments dropdown const fileUploadButton = canvas.getByText('Attach files'); await userEvent.click(fileUploadButton); - // Test that record button is disabled (no audio support) - const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1]; - await expect(recordButton).toBeDisabled(); - // Test that Images button is enabled (vision support) const imagesButton = document.querySelector('.images-button'); await expect(imagesButton).not.toHaveAttribute('data-disabled'); @@ -112,11 +111,10 @@ const audioButton = document.querySelector('.audio-button'); await expect(audioButton).toHaveAttribute('data-disabled'); - // Fix for dropdown menu side effect - const body = document.querySelector('body'); - if (body) body.style.pointerEvents = 'all'; + // Close dropdown by pressing Escape + await userEvent.keyboard('{Escape}'); - console.log('✅ Vision modality: Images enabled, Audio/Recording disabled'); + console.log('✅ Vision modality: Images enabled, Audio disabled'); }} /> @@ -131,13 +129,10 @@ const acceptAttr = fileInput?.getAttribute('accept'); console.log('Audio modality accept attr:', acceptAttr); + // Open file attachments dropdown const fileUploadButton = canvas.getByText('Attach files'); await userEvent.click(fileUploadButton); - // Test that record button is enabled (audio support) - const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1]; - await expect(recordButton).not.toBeDisabled(); - // Test that Images button is disabled (no vision support) const imagesButton = document.querySelector('.images-button'); await expect(imagesButton).toHaveAttribute('data-disabled'); @@ -146,11 +141,10 @@ const audioButton = document.querySelector('.audio-button'); await expect(audioButton).not.toHaveAttribute('data-disabled'); - // Fix for dropdown menu side effect - const body = document.querySelector('body'); - if (body) body.style.pointerEvents = 'all'; + // Close dropdown by pressing Escape + await userEvent.keyboard('{Escape}'); - console.log('✅ Audio modality: Audio/Recording enabled, Images disabled'); + console.log('✅ Audio modality: Audio enabled, Images disabled'); }} /> diff --git a/tools/server/webui/src/stories/ChatSidebar.stories.svelte b/tools/server/webui/src/stories/ChatSidebar.stories.svelte index baa1bec7ea..42cea8783c 100644 --- a/tools/server/webui/src/stories/ChatSidebar.stories.svelte +++ b/tools/server/webui/src/stories/ChatSidebar.stories.svelte @@ -3,7 +3,6 @@ import ChatSidebar from '$lib/components/app/chat/ChatSidebar/ChatSidebar.svelte'; import { waitFor } from 'storybook/test'; import { screen } from 'storybook/test'; - import type { DatabaseConversation } from '$lib/types'; const { Story } = defineMeta({ title: 'Components/ChatSidebar', diff --git a/tools/server/webui/src/stories/fixtures/storybook-mocks.ts b/tools/server/webui/src/stories/fixtures/storybook-mocks.ts index 35c98be308..c40a74655a 100644 --- a/tools/server/webui/src/stories/fixtures/storybook-mocks.ts +++ b/tools/server/webui/src/stories/fixtures/storybook-mocks.ts @@ -1,10 +1,15 @@ import { serverStore } from '$lib/stores/server.svelte'; +import { modelsStore } from '$lib/stores/models.svelte'; /** * Mock server properties for Storybook testing * This utility allows setting mock server configurations without polluting production code */ export function mockServerProps(props: Partial): void { + // Reset any pointer-events from previous tests (dropdown cleanup) + const body = document.querySelector('body'); + if (body) body.style.pointerEvents = ''; + // Directly set the props for testing purposes (serverStore as unknown as { props: ApiLlamaCppServerProps }).props = { model_path: props.model_path || 'test-model', @@ -14,6 +19,32 @@ export function mockServerProps(props: Partial): void { }, ...props } as ApiLlamaCppServerProps; + + // Set router mode role so activeModelId can be set + (serverStore as unknown as { props: ApiLlamaCppServerProps }).props.role = 'ROUTER'; + + // Also mock modelsStore methods for modality checking + const vision = props.modalities?.vision ?? false; + const audio = props.modalities?.audio ?? false; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (modelsStore as any).modelSupportsVision = () => vision; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (modelsStore as any).modelSupportsAudio = () => audio; + + // Mock models list with a test model so activeModelId can be resolved + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (modelsStore as any).models = [ + { + id: 'test-model', + name: 'Test Model', + model: 'test-model' + } + ]; + + // Mock selectedModelId + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (modelsStore as any).selectedModelId = 'test-model'; } /**