Add resumable admin deep search

This commit is contained in:
Jonathan Sykes
2026-10-14 01:47:35 +08:00
parent ca10fe6486
commit 58d0e6f140
12 changed files with 600 additions and 22 deletions

View File

@@ -0,0 +1,38 @@
const { test, expect } = require('@playwright/test');
test('admin deep-search tab estimates, starts, controls and shows persisted progress', async ({ page }) => {
page.on('pageerror', error => console.error('pageerror:', error.message));
const state = { jobs: [], events: [] };
await page.route('**/api/**', async route => {
const req = route.request(), url = new URL(req.url());
let body = { ok: true };
if (url.pathname === '/api/admin/me') body = { enabled: true, admin: true };
else if (url.pathname === '/api/admin/media') body = { ok: true, media: [] };
else if (url.pathname === '/api/uploads') body = { ok: true, uploads: [] };
else if (url.pathname === '/api/admin/deep-search/estimate') body = { ok: true, plan: ['worship', 'worship live'], queries: 2, estimatedMinutes: 1, indexSize: 1240, dailyRemaining: 999 };
else if (url.pathname === '/api/admin/deep-search/start') {
state.events.push('start'); state.jobs = [{ id: 'deep-1', status: 'running', plan: ['worship', 'worship live'], options: {}, queriesDone: 1, queriesTotal: 2, current: 'worship live', newVideos: 24, totalIndexSize: 1264, etaMs: 12000, errors: [], log: [{ at: Date.now(), message: 'Saved 24 results' }] }];
body = { ok: true, id: 'deep-1' };
} else if (url.pathname === '/api/admin/deep-search/jobs') body = { ok: true, indexSize: 1264, jobs: state.jobs };
else if (/\/api\/admin\/deep-search\/deep-1\/(pause|resume|cancel)$/.test(url.pathname)) {
const action = url.pathname.split('/').at(-1); state.events.push(action);
state.jobs[0].status = action === 'pause' ? 'paused' : action === 'resume' ? 'running' : 'cancelled';
body = { ok: true, status: state.jobs[0].status };
}
await route.fulfill({ contentType: 'application/json', body: JSON.stringify(body) });
});
await page.goto('/admin.html#deep-search');
await expect(page.locator('#deepSearchForm')).toBeVisible();
await expect(page.locator('#deepSeeds')).toHaveValue(/worship/);
await page.locator('#deepEstimate').click();
await expect(page.locator('#deepEstimateText')).toContainText('2 unique queries');
await page.locator('#deepStart').click();
await expect(page.locator('.deep-job')).toContainText('1/2 queries');
await page.locator('[data-deep-action="pause"]').click();
await expect(page.locator('.deep-job')).toContainText('Paused');
await page.locator('[data-deep-action="resume"]').click();
await expect(page.locator('.deep-job')).toContainText('Running');
await page.locator('[data-deep-action="cancel"]').click();
await expect(page.locator('.deep-job')).toContainText('Cancelled');
expect(state.events).toEqual(['start', 'pause', 'resume', 'cancel']);
});