aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-18 22:36:04 -0700
committerAdam Soltys <[email protected]>2026-10-18 22:36:04 -0700
commit1842b5ebbfd9e47323f6175babc222970a21a966 (patch)
tree48043f40b9f62fdb88edaffcb4f47d7963207e2c /tools
parent3154e5a24613bf276c6a878cb47ba72831f41e84 (diff)
downloadcoinosv3-1842b5ebbfd9e47323f6175babc222970a21a966.tar.gz
coinosv3-1842b5ebbfd9e47323f6175babc222970a21a966.zip
Past streams: under the Live chip, the feed's streams of the last month that left a recording (newest first, when each ended); a profile lists its person's too. A tap plays the recording.
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'tools')
-rw-r--r--tools/live-stream-test.js21
1 files changed, 16 insertions, 5 deletions
diff --git a/tools/live-stream-test.js b/tools/live-stream-test.js
index 88d2b17..d8f2283 100644
--- a/tools/live-stream-test.js
+++ b/tools/live-stream-test.js
@@ -45,7 +45,12 @@ const chat = finalizeEvent({ kind: 1311, created_at: now - 20, content: 'hello f
const zapReq = finalizeEvent({ kind: 9734, created_at: now - 15, content: 'great stream', tags: [['p', HOST.pk], ['a', A], ['amount', '21000']] }, FAN.sk);
const zap = finalizeEvent({ kind: 9735, created_at: now - 15, content: '', tags: [['p', HOST.pk], ['a', A], ['bolt11', 'lnbc210n1invalid'], ['description', JSON.stringify(zapReq)], ['P', FAN.pk]] }, SERVICE.sk);
const post = finalizeEvent({ kind: 1, created_at: now - 100, content: 'come watch nostr:' + NADDR, tags: [] }, HOST.sk);
-const FIXTURES = [live, stale, chat, zap];
+// yesterday's stream, over, its recording kept
+const past = finalizeEvent({ kind: 30311, created_at: now - 86000, content: '', tags: [
+ ['d', 'stream-0'], ['title', 'Yesterday on coinos'], ['status', 'ended'], ['streaming', STREAM], ['recording', STREAM],
+ ['starts', String(now - 90000)], ['ends', String(now - 86000)], ['p', HOST.pk, '', 'Host'],
+] }, SERVICE.sk);
+const FIXTURES = [live, stale, past, chat, zap];
const ended = finalizeEvent({ ...live, id: undefined, sig: undefined, created_at: now - 5, tags: live.tags.map((x) => (x[0] === 'status' ? ['status', 'ended'] : x)) }, SERVICE.sk);
// the site as built (the split build: hls.js arrives as its own chunk)
@@ -146,9 +151,11 @@ try {
}, 15000));
check('...and no streams above the posts', !(await page.evaluate(() => document.querySelector('.live-grid, .live-strip'))));
await page.evaluate(() => document.querySelector('.media-mode[data-mode="live"]').click());
- check('the Live chip shows the stream', await waitFor(() => !!document.querySelector('.live-grid .live-tile'), 15000));
- const tile = await page.evaluate(() => [...document.querySelectorAll('.live-grid .live-tile')].map((t) => t.innerText.replace(/\s+/g, ' ')));
+ check('the Live chip shows the stream', await waitFor(() => !!document.querySelector('.live-grid:not(.live-past) .live-tile'), 15000));
+ const tile = await page.evaluate(() => [...document.querySelectorAll('.live-grid:not(.live-past) .live-tile')].map((t) => t.innerText.replace(/\s+/g, ' ')));
check('...titled, marked LIVE, with how many watch and who', tile.length && /LIVE/.test(tile[0]) && /12 watching/.test(tile[0]) && /Building coinos live/.test(tile[0]), JSON.stringify(tile));
+ check('past streams follow, the recording kept, its end time shown', await waitFor(() => [...document.querySelectorAll('.live-past .live-tile')].some((t) => /Yesterday on coinos/.test(t.innerText) && /RECORDING/.test(t.innerText)), 8000)
+ && await page.evaluate(() => /Past streams/.test(document.body.innerText)));
check('...and a stream unrefreshed for two hours is not there', tile.length === 1 && !(await page.evaluate(() => document.body.innerText.includes('Forgotten stream'))));
await page.evaluate(() => document.querySelector('.media-mode[data-mode="all"]').click());
check('a post linking the stream shows it as a card', await waitFor(() => !!document.querySelector('.notes-feed .live-card'), 15000));
@@ -158,10 +165,10 @@ try {
await page.goBack();
await waitFor(() => !document.querySelector('.live-page') && !!document.querySelector('.media-modes'), 5000);
await page.evaluate(() => document.querySelector('.media-mode[data-mode="live"]').click());
- await waitFor(() => !!document.querySelector('.live-grid .live-tile'), 5000);
+ await waitFor(() => !!document.querySelector('.live-grid:not(.live-past) .live-tile'), 5000);
console.log('\n[the stream\'s page]');
- await page.evaluate(() => document.querySelector('.live-grid .live-tile').click());
+ await page.evaluate(() => document.querySelector('.live-grid:not(.live-past) .live-tile').click());
check('a tap opens it, the address bar naming the stream', await waitFor(() => !!document.querySelector('.live-page'), 5000) && await waitFor((n) => location.pathname === '/' + n, 5000, NADDR), await page.evaluate(() => location.pathname));
check('the stream plays', await waitFor(playing, 20000), JSON.stringify(await page.evaluate(() => { const v = document.querySelector('video.live-video'); return v && { t: v.currentTime, paused: v.paused, err: v.error && v.error.code, src: v.currentSrc.slice(0, 60) }; })));
check('...from its playlist, natively in Chrome', await page.evaluate((s) => document.querySelector('video.live-video').currentSrc === s, STREAM));
@@ -184,8 +191,12 @@ try {
await page.evaluate(() => document.querySelector('.notes-feed .live-card').click());
check('the card in the post opens the stream too', await waitFor(() => !!document.querySelector('.live-page'), 5000) && await waitFor(playing, 20000));
await page.evaluate(() => { const a = [...document.querySelectorAll('.live-page a.quote-name')].find((x) => /Stream Host/.test(x.textContent)); a.click(); });
+ check('the host\'s profile lists their past streams', await waitFor(() => [...document.querySelectorAll('.live-past-row .live-tile')].some((t) => /Yesterday on coinos/.test(t.innerText)), 10000));
check('the host\'s profile says they\'re on', await waitFor(() => !!document.querySelector('.live-banner'), 10000) && await waitText('Building coinos live', 2000));
check('...the player stopped when the page went', await page.evaluate(() => [...document.querySelectorAll('video')].every((v) => v.paused || !v.isConnected)));
+ await page.evaluate(() => [...document.querySelectorAll('.live-past-row .live-tile')].find((t) => /Yesterday on coinos/.test(t.innerText)).click());
+ check('a past stream opens on its recording, playing', await waitFor(() => !!document.querySelector('.live-page'), 5000) && await waitFor(playing, 20000)
+ && await page.evaluate(() => !document.body.innerText.includes('This stream has ended')));
check('no page errors', !page.errs.length, page.errs.join(' | '));
await page.close();