Files
LocalAI/core/http/react-ui/e2e/backend-logs.spec.js
T
localai-org-maint-botandEttore Di Giacinto f041bee1cb fix(ui): complete node operation journeys (#12070)
Worker setup now uses a focused drawer without interrupting fleet
monitoring. Both generated worker commands retain their NATS settings.

Log views preserve their launch context and show one-based replica
labels. Bulk controls disclose selections outside the current view.

Assisted-by: Codex:gpt-5 Playwright ESLint

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
2026-09-27 03:05:13 +00:00

87 lines
3.3 KiB
JavaScript

import { test, expect } from './coverage-fixtures.js'
test.describe('Backend Logs', () => {
test('model detail page shows title', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('.page-title')).toContainText('mock-model')
})
test('no back arrow link on detail page', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('a[href="/app/backend-logs"]')).not.toBeVisible()
})
test('filter buttons are visible', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('button', { hasText: 'All' })).toBeVisible()
await expect(page.locator('button', { hasText: 'stdout' })).toBeVisible()
await expect(page.locator('button', { hasText: 'stderr' })).toBeVisible()
})
test('filter buttons toggle active state', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
const allBtn = page.locator('button', { hasText: 'All' })
const stdoutBtn = page.locator('button', { hasText: 'stdout' })
// All is active by default
await expect(allBtn).toHaveClass(/btn-primary/)
// Click stdout
await stdoutBtn.click()
await expect(stdoutBtn).toHaveClass(/btn-primary/)
await expect(allBtn).not.toHaveClass(/btn-primary/)
})
test('export button is present', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('button', { hasText: 'Export' })).toBeVisible()
})
test('auto-scroll checkbox is present', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('text=Auto-scroll')).toBeVisible()
})
test('clear button is present', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
await expect(page.locator('button', { hasText: 'Clear' })).toBeVisible()
})
test('details toggle button is present and toggles', async ({ page }) => {
await page.goto('/app/backend-logs/mock-model')
// "Text only" button visible by default (details are shown)
const toggleBtn = page.locator('button', { hasText: 'Text only' })
await expect(toggleBtn).toBeVisible()
// Click to hide details
await toggleBtn.click()
// Button label changes to "Show details"
await expect(page.locator('button', { hasText: 'Show details' })).toBeVisible()
})
test('distributed resolver displays zero-based replica indexes as one-based labels', async ({ page }) => {
await page.route('**/api/nodes', route => route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 'worker-1', name: 'Worker 1' }]),
}))
await page.route('**/api/nodes/worker-1/models', route => route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ model_name: 'llama', replica_index: 0, state: 'loaded' },
{ model_name: 'llama', replica_index: 1, state: 'loaded' },
]),
}))
await page.goto('/app/backend-logs/llama')
await expect(page.getByText('worker-1 · replica 1 · loaded')).toBeVisible()
await expect(page.getByText('worker-1 · replica 2 · loaded')).toBeVisible()
await expect(page.locator('a[href="/app/node-backend-logs/worker-1/llama"]')).toHaveCount(2)
})
})