Files
wehub-resource-sync 1b8708893a
Security Scan / tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:12:26 +08:00

125 lines
4.6 KiB
JavaScript

import { test, expect } from './coverage-fixtures.js'
test.describe('Traces - Error Display', () => {
test.beforeEach(async ({ page }) => {
// Mock API traces with sample data so the table renders
await page.route('**/api/traces', (route) => {
route.fulfill({
contentType: 'application/json',
body: JSON.stringify([
{
request: { method: 'POST', path: '/v1/chat/completions' },
response: { status: 200 },
error: null,
},
]),
})
})
// Mock backend traces with sample data
await page.route('**/api/backend-traces', (route) => {
route.fulfill({
contentType: 'application/json',
body: JSON.stringify([
{
type: 'model_load',
timestamp: Date.now() * 1_000_000,
model_name: 'mock-model',
summary: 'Loaded model',
duration: 500_000_000,
error: null,
},
]),
})
})
await page.goto('/app/traces')
await expect(page.locator('text=Tracing is')).toBeVisible({ timeout: 10_000 })
})
test('API traces tab has Result column header', async ({ page }) => {
// API tab is active by default
await expect(page.locator('th', { hasText: 'Result' })).toBeVisible()
})
test('backend traces tab shows model_load type if present', async ({ page }) => {
// Switch to backend traces tab
await page.locator('button', { hasText: 'Backend Traces' }).click()
// The table should be visible with Type column
await expect(page.locator('th', { hasText: 'Type' })).toBeVisible()
})
})
// Pin the BackendTraceDetail expansion path for a vector_store trace —
// the type that surfaces the router's embedding-cache plumbing. The
// row click triggers the detail render, which exercises typeBadgeStyle
// (with the new vector_store badge color), the DataFields component
// (op / outcome / vector_dim / similarity), and the "View backend
// logs" link that resolves to the store namespace. Without this spec
// the new color entry plus the data-field render branches stay
// uncovered, dragging UI line coverage below the regression gate.
test.describe('Traces - vector_store backend trace detail', () => {
test.beforeEach(async ({ page }) => {
await page.route('**/api/traces', (route) => {
route.fulfill({ contentType: 'application/json', body: '[]' })
})
await page.route('**/api/backend-traces', (route) => {
route.fulfill({
contentType: 'application/json',
body: JSON.stringify([
{
type: 'vector_store',
timestamp: '2026-05-28T13:56:25.558Z',
model_name: 'router-cache-smart-router',
backend: 'local-store',
summary: 'search hit (sim=0.989)',
duration: 160_000_000,
error: '',
data: {
op: 'search',
outcome: 'hit',
vector_dim: 768,
similarity: 0.9899752140045166,
},
},
{
type: 'vector_store',
timestamp: '2026-05-28T13:49:07.545Z',
model_name: 'router-cache-smart-router',
backend: 'local-store',
summary: 'search miss',
duration: 100_000_000,
error: '',
data: {
op: 'search',
outcome: 'miss',
vector_dim: 768,
},
},
]),
})
})
await page.goto('/app/traces')
await expect(page.locator('text=Tracing is')).toBeVisible({ timeout: 10_000 })
await page.locator('button', { hasText: 'Backend Traces' }).click()
})
test('renders type badge and expands data fields on row click', async ({ page }) => {
// The vector_store badge appears in the type column.
await expect(page.locator('td span', { hasText: 'vector_store' }).first()).toBeVisible()
// Clicking the first row expands BackendTraceDetail, which renders
// the four data fields. Use the first row's "search hit" summary
// as the anchor to disambiguate from the miss row below.
await page.locator('tr', { hasText: 'search hit' }).first().click()
// DataFields renders op/outcome/vector_dim/similarity as label/value pairs.
// 'hit' appears as the rendered outcome value.
await expect(page.locator('text=outcome').first()).toBeVisible()
await expect(page.locator('text=hit').first()).toBeVisible()
// The model_name → /app/backend-logs link is the BackendTraceDetail
// affordance for jumping to logs for the store namespace.
await expect(page.locator('a', { hasText: 'View backend logs' })).toBeVisible()
})
})