Files
ytplayer/tests/admin-bulk-lyrics.spec.js
2026-10-14 02:36:30 +08:00

44 lines
3.0 KiB
JavaScript

const { test, expect } = require('@playwright/test');
test('library selection queues LRCLIB, Whisper, LRC export and revision-backed clear jobs', async ({ page }) => {
const calls = []; let latestJob = null;
await page.route('**/api/**', async route => {
const request = route.request(), url = new URL(request.url());
let body = { ok: true };
if (url.pathname === '/api/admin/me') body = { ok: true, enabled: true, admin: true };
if (url.pathname === '/api/uploads') body = { ok: true, uploads: [] };
if (url.pathname === '/api/admin/lyrics/bulk/library') body = { ok: true, total: 2, limit: 50, offset: 0, songs: [
{ id: 'dQw4w9WgXcQ', title: 'Amazing grace', channel: 'Choir', lines: 4, cacheStatus: 'ready' },
{ id: 'jNQXAC9IVRw', title: 'Saved song', channel: 'Band', lines: 0, cacheStatus: 'failed' },
] };
if (url.pathname === '/api/admin/lyrics/jobs' && request.method() === 'GET') body = { ok: true, jobs: latestJob ? [latestJob] : [] };
if (url.pathname === '/api/admin/lyrics/jobs' && request.method() === 'POST') {
const payload = request.postDataJSON(); calls.push(payload);
latestJob = { id: `job-${calls.length}`, action: payload.action, status: 'complete', state: { done: payload.ids?.length || 2, total: payload.ids?.length || 2, results: [{ id: 'dQw4w9WgXcQ', ok: true, message: 'Done' }], fileReady: payload.action === 'export' } };
body = { ok: true, job: latestJob };
}
if (url.pathname === '/api/admin/lyrics/jobs/job-1/pause' || url.pathname.endsWith('/resume') || url.pathname.endsWith('/cancel')) body = { ok: true, status: 'paused' };
await route.fulfill({ contentType: 'application/json', body: JSON.stringify(body) });
});
page.on('dialog', dialog => dialog.accept());
await page.goto('/admin.html#library');
await expect(page.locator('#bulkLibraryTable')).toContainText('Amazing grace');
await page.locator('#bulkSelectAll').check(); await page.locator('#bulkAction').selectOption('lrclib'); await page.locator('#bulkStart').click();
await expect.poll(() => calls.length).toBe(1);
expect(calls[0]).toMatchObject({ action: 'lrclib', allFiltered: true, query: '' });
await page.locator('#bulkLibraryTable [data-bulk-song="dQw4w9WgXcQ"]').check();
await page.locator('#bulkAction').selectOption('whisper'); await page.locator('#bulkStart').click();
await expect.poll(() => calls.length).toBe(2); expect(calls[1].action).toBe('whisper');
await page.locator('#bulkLibraryTable [data-bulk-song="jNQXAC9IVRw"]').check();
await page.locator('#bulkAction').selectOption('export'); await page.locator('#bulkStart').click();
await expect.poll(() => calls.length).toBe(3); expect(calls[2].action).toBe('export');
await expect(page.locator('#bulkJobs a[href*="/export"]')).toBeVisible();
await page.locator('#bulkLibraryTable [data-bulk-song="dQw4w9WgXcQ"]').check();
await page.locator('#bulkAction').selectOption('clear'); await page.locator('#bulkStart').click();
await expect.poll(() => calls.length).toBe(4); expect(calls[3]).toMatchObject({ action: 'clear', confirmClear: true });
});