An open page takes up a new version by itself after a deploy (#388)
The live stream already came back after a deploy and the lists caught up, but the page kept running the script it had loaded, in a tab or the home-screen app, until reloaded by hand. Back after a drop, the page now asks for / again without the cache; another app.js named there is a new version. With nothing to lose it reloads, and the item that was open, carried across in sessionStorage whole since a read one is off the Unread list, is opened again. While an episode plays, a dialog is open, a search is set or a field is typed in, it offers a reload in a toast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -629,6 +629,53 @@ test('marking an OPML subscription read covers the feeds inside it', async ({ pa
|
||||
await expect(folder.locator('.badge')).toHaveText('0');
|
||||
});
|
||||
|
||||
// A deploy of ipx-web: the page asks for itself again after the live stream comes back (#388).
|
||||
// The new version is faked by answering / once with another app.js named in it.
|
||||
async function newVersionOnce(page) {
|
||||
await page.route(u => new URL(u).pathname === '/', async route => {
|
||||
const r = await route.fetch();
|
||||
await route.fulfill({ response: r, body: (await r.text()).replace(/\/app\.js\?v=[0-9a-f]+/, '/app.js?v=0000000000ff') });
|
||||
}, { times: 1 });
|
||||
}
|
||||
|
||||
test('a new version reloads the page and opens the item that was open, or offers a reload while a dialog is open', async ({ page }) => {
|
||||
await page.locator('.feed', { hasText: 'Test Show' }).click();
|
||||
await page.locator('.tabs button', { hasText: 'Unread' }).first().click();
|
||||
const first = page.locator('.ep').first();
|
||||
if (!(await first.count())) {
|
||||
// Earlier tests read everything; one unread item is enough.
|
||||
await page.locator('.tabs button', { hasText: 'All' }).first().click();
|
||||
await page.locator('.ep').first().locator('[data-a="read"]').click();
|
||||
await page.locator('.tabs button', { hasText: 'Unread' }).first().click();
|
||||
}
|
||||
await expect(first).toBeVisible({ timeout: 20_000 });
|
||||
const title = await first.locator('.t').textContent();
|
||||
await first.click();
|
||||
await expect(page.locator('#detail .dt')).toHaveText(title);
|
||||
|
||||
// A dialog open: nothing is thrown away, a reload is offered.
|
||||
await page.locator('#content .acts [data-a="settings"]').click();
|
||||
await expect(page.locator('#modal')).toHaveClass(/\bon\b/);
|
||||
await newVersionOnce(page);
|
||||
await page.evaluate(() => checkVersion());
|
||||
const offer = page.locator('.toast', { hasText: 'A new version of iPX is ready' });
|
||||
await expect(offer).toBeVisible();
|
||||
await page.evaluate(() => closeModal());
|
||||
|
||||
// Idle: it reloads by itself, and the item read, now off the Unread list, is open again.
|
||||
await newVersionOnce(page);
|
||||
const reloaded = page.waitForEvent('load');
|
||||
await page.evaluate(() => checkVersion());
|
||||
await reloaded;
|
||||
await expect(page.locator('#detail .dt')).toHaveText(title, { timeout: 20_000 });
|
||||
await expect(page.locator('.toast', { hasText: 'A new version' })).toHaveCount(0);
|
||||
|
||||
// The same version again: nothing happens.
|
||||
await page.evaluate(() => checkVersion());
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page.locator('#detail .dt')).toHaveText(title);
|
||||
});
|
||||
|
||||
test.describe('on a phone', () => {
|
||||
test.use({ viewport: { width: 390, height: 844 } });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user