A spinner on the feed being checked, not toasts; check only your own feeds
The scan's events reach everyone, so every browser showed "<feed>: N new" and "Scanning…" toasts, and refreshed, for everyone's feeds. Now a feed's row, and its folder's, carries a spinner between feed_start and its done, skip or error; the list refreshes only for the reader's own feeds; the scan toasts are gone, and "Downloaded" is said only for a file on screen. "Check every feed" from the web UI sent a scan of every feed on the server. Command::Fetch takes an optional `feeds` list -- those feeds and the feeds inside any OPML among them -- and the web fills it with the asker's subscriptions. The schedule and the CLI send none, meaning every feed. Closes #37. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1299,3 +1299,43 @@ test('a pinned feed, even one from inside a folder, goes to the top of the list'
|
||||
await expect(page.locator('.feed.pinned')).toHaveCount(0);
|
||||
await expect(page.locator('.feed.child', { hasText: name })).toHaveCount(1);
|
||||
});
|
||||
|
||||
test('a feed being checked shows a spinner on its row, and no toast', async ({ page }) => {
|
||||
const row = page.locator('#feedlist .feed', { hasText: 'Test Show' });
|
||||
await expect(row).toBeVisible();
|
||||
await page.evaluate(() => setScanning('test-show', true));
|
||||
await expect(row).toHaveClass(/\bscanning\b/);
|
||||
await page.evaluate(() => setScanning('test-show', false));
|
||||
await expect(row).not.toHaveClass(/\bscanning\b/);
|
||||
// Checking every feed says so on the rows, not in a toast (issue #37).
|
||||
await page.locator('#scanAll').click();
|
||||
await page.waitForTimeout(1500);
|
||||
await expect(page.locator('.toast', { hasText: /Scanning|Checking| new/ })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('"check every feed" checks only the feeds of the person asking', async ({ browser }) => {
|
||||
// piper, made in an earlier test, subscribes to Test Show alone.
|
||||
const ctx = await browser.newContext();
|
||||
const piper = await ctx.newPage();
|
||||
await piper.goto('/login');
|
||||
await piper.locator('#name').fill('piper');
|
||||
await piper.locator('#pw').fill('piperpassword');
|
||||
await piper.locator('button[type=submit]').click();
|
||||
await expect(piper.locator('#feedlist .feed', { hasText: 'Test Show' })).toBeVisible({ timeout: 20_000 });
|
||||
const mine = await piper.evaluate(() => S.feeds.map(f => f.id));
|
||||
// Listen as the page does, then ask.
|
||||
await piper.evaluate(() => {
|
||||
window.started = []; window.done = false;
|
||||
const es = new EventSource('/api/events');
|
||||
es.onmessage = m => { const ev = JSON.parse(m.data);
|
||||
if (ev.ev === 'feed_start') window.started.push(ev.feed);
|
||||
if (ev.ev === 'scan_done') window.done = true; };
|
||||
});
|
||||
await piper.waitForTimeout(500);
|
||||
await piper.locator('#scanAll').click();
|
||||
await expect.poll(() => piper.evaluate(() => window.done), { timeout: 30_000 }).toBe(true);
|
||||
const started = await piper.evaluate(() => window.started);
|
||||
expect(started.length, 'something was checked').toBeGreaterThan(0);
|
||||
for (const id of started) expect(mine, `${id} is not one of piper's feeds`).toContain(id);
|
||||
await ctx.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user