26 lines
1.8 KiB
JavaScript
26 lines
1.8 KiB
JavaScript
const { test, expect } = require('@playwright/test');
|
|
|
|
test('backups lists integrity, previews diff, creates a snapshot and confirms restore', async ({ page }) => {
|
|
const calls = [];
|
|
await page.route('**/api/**', async route => {
|
|
const request = route.request(), url = new URL(request.url()); calls.push({ path: url.pathname, method: request.method() });
|
|
let body = { ok: true };
|
|
if (url.pathname === '/api/admin/me') body = { ok: true, enabled: true, admin: true };
|
|
if (url.pathname === '/api/admin/backups' && request.method() === 'GET') body = { ok: true, backups: [{ date: '2026-10-14', bytes: 1024, notes: 12, valid: true }] };
|
|
if (url.pathname === '/api/admin/backups/2026-10-14') body = { ok: true, diff: { changed: 2, added: 1, removed: 0, preview: [{ key: 'song:lyrics', change: 'changed' }] } };
|
|
if (url.pathname === '/api/admin/backups' && request.method() === 'POST') body = { ok: true, date: '2026-10-14', notes: 12 };
|
|
if (url.pathname.endsWith('/restore')) body = { ok: true, restored: 12, safetySnapshot: '/data/backups/snapshots/safety.json' };
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify(body) });
|
|
});
|
|
page.on('dialog', dialog => dialog.accept());
|
|
await page.goto('/admin.html#backups');
|
|
await expect(page.locator('#backupTable')).toContainText('Verified');
|
|
await expect(page.locator('#backupDiff')).toContainText('2 changed');
|
|
await expect(page.locator('a[href="/api/admin/backups/export/sqlite-dump"]')).toBeVisible();
|
|
await page.locator('#backupNow').click();
|
|
await expect(page.locator('#backupStatus')).toContainText('Saved 12 notes');
|
|
await page.locator('#backupRestore').click();
|
|
await expect.poll(() => calls.some(call => call.path.endsWith('/restore') && call.method === 'POST')).toBe(true);
|
|
await expect(page.locator('#backupStatus')).toContainText('Safety snapshot');
|
|
});
|