From 382ba0a6d47567fe769a5c548a192fea6d1a8edf Mon Sep 17 00:00:00 2001 From: Test Date: Sat, 7 Mar 2026 01:58:08 +0100 Subject: [PATCH] test: add Playwright smoke test for wikilink rendering in AI chat Update mock agent response to include [[wikilinks]] for testing. Add smoke test verifying wikilinks render as clickable elements with correct text, attributes, and styling. Co-Authored-By: Claude Opus 4.6 --- src/utils/ai-agent.test.ts | 2 +- src/utils/ai-agent.ts | 2 +- .../smoke/ai-chat-wikilink-clickable.spec.ts | 46 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/smoke/ai-chat-wikilink-clickable.spec.ts diff --git a/src/utils/ai-agent.test.ts b/src/utils/ai-agent.test.ts index 859d1f98..72ebdc2c 100644 --- a/src/utils/ai-agent.test.ts +++ b/src/utils/ai-agent.test.ts @@ -50,7 +50,7 @@ describe('streamClaudeAgent', () => { // Wait for the setTimeout mock response await new Promise(r => setTimeout(r, 400)) - expect(onText).toHaveBeenCalledWith(expect.stringContaining('Claude CLI')) + expect(onText).toHaveBeenCalledWith(expect.stringContaining('Build Laputa App')) expect(onDone).toHaveBeenCalled() expect(onError).not.toHaveBeenCalled() expect(onToolStart).not.toHaveBeenCalled() diff --git a/src/utils/ai-agent.ts b/src/utils/ai-agent.ts index 8706218d..b873b378 100644 --- a/src/utils/ai-agent.ts +++ b/src/utils/ai-agent.ts @@ -58,7 +58,7 @@ export async function streamClaudeAgent( ): Promise { if (!isTauri()) { setTimeout(() => { - callbacks.onText('AI Agent requires the Claude CLI. Install it and run the native app.') + callbacks.onText('This note is related to [[Build Laputa App]] and [[Matteo Cellini]]. The AI Agent requires the Claude CLI for full functionality.') callbacks.onDone() }, 300) return diff --git a/tests/smoke/ai-chat-wikilink-clickable.spec.ts b/tests/smoke/ai-chat-wikilink-clickable.spec.ts new file mode 100644 index 00000000..9c56bccd --- /dev/null +++ b/tests/smoke/ai-chat-wikilink-clickable.spec.ts @@ -0,0 +1,46 @@ +import { test, expect } from '@playwright/test' +import { sendShortcut } from './helpers' + +test.describe('AI chat wikilink rendering', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/') + await page.waitForTimeout(500) + }) + + test('[[Note]] in AI response renders as clickable wikilink', async ({ page }) => { + // Select a note first so the AI panel has context + const noteItem = page.locator('.app__note-list .cursor-pointer').first() + await noteItem.click() + await page.waitForTimeout(500) + + // Open AI Chat with Ctrl+I + await sendShortcut(page, 'i', ['Control']) + await expect(page.getByTestId('ai-panel')).toBeVisible({ timeout: 3000 }) + + // Send a message to get a mock response containing wikilinks + const input = page.locator('input[placeholder*="Ask"]') + await input.fill('Tell me about this note') + await page.getByTestId('agent-send').click() + + // Wait for mock response (contains [[Build Laputa App]] and [[Matteo Cellini]]) + const wikilink = page.locator('.chat-wikilink').first() + await expect(wikilink).toBeVisible({ timeout: 5000 }) + + // Verify wikilink text and attributes + await expect(wikilink).toHaveText('Build Laputa App') + await expect(wikilink).toHaveAttribute('data-wikilink-target', 'Build Laputa App') + await expect(wikilink).toHaveAttribute('role', 'link') + + // Verify second wikilink + const secondWikilink = page.locator('.chat-wikilink').nth(1) + await expect(secondWikilink).toHaveText('Matteo Cellini') + + // Verify multiple wikilinks rendered + const allWikilinks = page.locator('.chat-wikilink') + await expect(allWikilinks).toHaveCount(2) + + // Verify wikilink has pointer cursor (is styled as clickable) + const cursor = await wikilink.evaluate(el => getComputedStyle(el).cursor) + expect(cursor).toBe('pointer') + }) +})