diff --git a/dashboard/tests/e2e/chat-message.spec.ts b/dashboard/tests/e2e/chat-message.spec.ts deleted file mode 100644 index 494ca8c6..00000000 --- a/dashboard/tests/e2e/chat-message.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -/// -import { test, expect } from "@playwright/test"; -import { waitForTopologyLoaded } from "../helpers/wait-for-ready"; - -test.describe("Chat Message Flow", () => { - // This test suite requires a running instance - // It will launch one if needed - - test("should send a chat message and receive a response", async ({ - page, - }) => { - // Skip in CI - requires launching an instance and downloading a model - test.skip(!!process.env.CI, "Skipped in CI - requires model download"); - test.setTimeout(600000); // 10 minutes - - await page.goto("/"); - await waitForTopologyLoaded(page); - - // Check if we already have a running instance with chat available - const chatInput = page.locator('[data-testid="chat-input"]'); - let hasChatReady = await chatInput - .isVisible({ timeout: 5000 }) - .catch(() => false); - - // Check if there's a ready instance (use first() in case multiple exist) - const readyIndicator = page.locator("text=READY").first(); - let hasReady = await readyIndicator - .isVisible({ timeout: 2000 }) - .catch(() => false); - - if (!hasReady) { - // Need to launch an instance first - const modelDropdown = page.locator('[data-testid="model-dropdown"]'); - await expect(modelDropdown).toBeVisible({ timeout: 15000 }); - - // Wait for placement previews - await page.waitForTimeout(3000); - - const launchButton = page - .locator('[data-testid="launch-button"]:not([disabled])') - .first(); - let hasLaunchButton = await launchButton - .isVisible({ timeout: 10000 }) - .catch(() => false); - - if (!hasLaunchButton) { - // Select a model - prefer Qwen3-0.6B-4bit (smallest) - await modelDropdown.click(); - await page.waitForTimeout(500); - - const qwenOption = page - .locator('[data-testid="model-option"]', { - hasText: /qwen.*0\.6b.*4bit/i, - }) - .first(); - const hasQwen = await qwenOption - .isVisible({ timeout: 2000 }) - .catch(() => false); - - if (hasQwen) { - await qwenOption.click(); - } else { - const modelOption = page - .locator('[data-testid="model-option"]:not([disabled])') - .first(); - await expect(modelOption).toBeVisible({ timeout: 5000 }); - await modelOption.click(); - } - - await expect(launchButton).toBeVisible({ timeout: 30000 }); - } - - // Launch the instance - await launchButton.click(); - - // Wait for instance to be ready - await expect(readyIndicator).toBeVisible({ timeout: 300000 }); // 5 min for download - } - - // Now we should have a running instance - wait for chat input to be available - await expect(chatInput).toBeVisible({ timeout: 30000 }); - - // Type a simple message - await chatInput.fill("What is 2+2? Reply with just the number."); - - // Click send button - const sendButton = page.locator('[data-testid="send-button"]'); - await expect(sendButton).toBeVisible(); - await sendButton.click(); - - // Wait for user message to appear - const userMessage = page.locator('[data-testid="user-message"]'); - await expect(userMessage).toBeVisible({ timeout: 10000 }); - - // Wait for assistant response - const assistantMessage = page.locator('[data-testid="assistant-message"]'); - await expect(assistantMessage).toBeVisible({ timeout: 120000 }); // 2 min for response - - // Verify we got some response text - const responseText = await assistantMessage.textContent(); - expect(responseText).toBeTruthy(); - expect(responseText!.length).toBeGreaterThan(0); - }); -}); diff --git a/dashboard/tests/e2e/launch-instance.spec.ts b/dashboard/tests/e2e/launch-instance.spec.ts deleted file mode 100644 index be33ff9a..00000000 --- a/dashboard/tests/e2e/launch-instance.spec.ts +++ /dev/null @@ -1,124 +0,0 @@ -/// -import { test, expect } from "@playwright/test"; -import { waitForTopologyLoaded } from "../helpers/wait-for-ready"; - -test.describe("Launch Model Instance", () => { - test.beforeEach(async ({ page }) => { - await page.goto("/"); - await waitForTopologyLoaded(page); - }); - - test("should display topology graph on page load", async ({ page }) => { - const topologyGraph = page.locator('[data-testid="topology-graph"]'); - await expect(topologyGraph).toBeVisible(); - }); - - test("should display model dropdown on welcome page", async ({ page }) => { - const modelDropdown = page.locator('[data-testid="model-dropdown"]'); - await expect(modelDropdown).toBeVisible({ timeout: 15000 }); - }); - - test("should display model cards when model is selected", async ({ - page, - }) => { - const modelDropdown = page.locator('[data-testid="model-dropdown"]'); - await expect(modelDropdown).toBeVisible({ timeout: 15000 }); - - // Wait for API to respond with placement previews - await page.waitForTimeout(5000); - - // Check if launch button is visible (indicates model card is showing) - const launchButton = page.locator('[data-testid="launch-button"]').first(); - let hasLaunchButton = await launchButton - .isVisible({ timeout: 5000 }) - .catch(() => false); - - if (!hasLaunchButton) { - // No model selected yet - click dropdown and select one - await modelDropdown.click(); - await page.waitForTimeout(1000); - - const modelOption = page - .locator('[data-testid="model-option"]:not([disabled])') - .first(); - await expect(modelOption).toBeVisible({ timeout: 5000 }); - - await modelOption.click(); - await page.waitForTimeout(3000); - } - - await expect(launchButton).toBeVisible({ timeout: 30000 }); - }); - - test("should launch a model instance", async ({ page }) => { - // Skip in CI - requires downloading a model which is too slow - test.skip(!!process.env.CI, "Skipped in CI - requires model download"); - test.setTimeout(300000); // 5 minutes - - const modelDropdown = page.locator('[data-testid="model-dropdown"]'); - await expect(modelDropdown).toBeVisible({ timeout: 15000 }); - - // Wait for placement previews to load - await page.waitForTimeout(3000); - - // Check if launch button is visible - const launchButton = page - .locator('[data-testid="launch-button"]:not([disabled])') - .first(); - let hasLaunchButton = await launchButton - .isVisible({ timeout: 10000 }) - .catch(() => false); - - if (!hasLaunchButton) { - // Select a model first - prefer Qwen3-0.6B (smallest) - await modelDropdown.click(); - await page.waitForTimeout(500); - - // Try to find Qwen3-0.6B-4bit specifically (smallest model), otherwise take first available - const qwenOption = page - .locator('[data-testid="model-option"]', { - hasText: /qwen.*0\.6b.*4bit/i, - }) - .first(); - const hasQwen = await qwenOption - .isVisible({ timeout: 2000 }) - .catch(() => false); - - if (hasQwen) { - await qwenOption.click(); - } else { - const modelOption = page - .locator('[data-testid="model-option"]:not([disabled])') - .first(); - await expect(modelOption).toBeVisible({ timeout: 5000 }); - await modelOption.click(); - } - - await expect(launchButton).toBeVisible({ timeout: 30000 }); - } - - // Click launch - await launchButton.click(); - - // Wait for instance to start - could be downloading, loading, or ready - await expect(async () => { - const isDownloading = await page - .locator("text=DOWNLOADING") - .first() - .isVisible(); - const isReady = await page.locator("text=READY").first().isVisible(); - const isLoading = await page.locator("text=LOADING").first().isVisible(); - const hasLaunching = await launchButton - .textContent() - .then((t) => t?.includes("LAUNCHING")); - expect( - isDownloading || isReady || isLoading || hasLaunching, - ).toBeTruthy(); - }).toPass({ timeout: 30000 }); - - // Wait for instance to be fully ready (this may take a while if downloading) - await expect(page.locator("text=READY").first()).toBeVisible({ - timeout: 240000, - }); // 4 min for download - }); -}); diff --git a/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-empty-chromium-darwin.png b/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-empty-chromium-darwin.png index 60937c23..59dabeb9 100644 Binary files a/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-empty-chromium-darwin.png and b/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-empty-chromium-darwin.png differ diff --git a/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-with-text-chromium-darwin.png b/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-with-text-chromium-darwin.png index ee67f60c..ddb4325a 100644 Binary files a/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-with-text-chromium-darwin.png and b/dashboard/tests/visual/chat-interface.spec.ts-snapshots/chat-input-with-text-chromium-darwin.png differ diff --git a/dashboard/tests/visual/homepage.spec.ts-snapshots/topology-graph-chromium-darwin.png b/dashboard/tests/visual/homepage.spec.ts-snapshots/topology-graph-chromium-darwin.png index 7ddaf996..9a64d4a6 100644 Binary files a/dashboard/tests/visual/homepage.spec.ts-snapshots/topology-graph-chromium-darwin.png and b/dashboard/tests/visual/homepage.spec.ts-snapshots/topology-graph-chromium-darwin.png differ