diff options
Diffstat (limited to 'tools/live-stream-test.js')
| -rw-r--r-- | tools/live-stream-test.js | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/tools/live-stream-test.js b/tools/live-stream-test.js index 4cd8337..2be6051 100644 --- a/tools/live-stream-test.js +++ b/tools/live-stream-test.js @@ -55,6 +55,9 @@ const pastPage = finalizeEvent({ kind: 30311, created_at: now - 50000, content: ['d', 'stream-p'], ['title', 'Zelda on Rumble'], ['status', 'ended'], ['streaming', STREAM], ['recording', 'https://rumble.com/v7gt2va-zelda.html'], ['ends', String(now - 50000)], ['p', HOST.pk, '', 'Host'], ] }, SERVICE.sk); +// who's watching (NIP-53 presence): the fan, just now; someone two hours ago is gone +const here = finalizeEvent({ kind: 10312, created_at: now - 60, content: '', tags: [['a', A, '', 'root']] }, FAN.sk); +const longGone = finalizeEvent({ kind: 10312, created_at: now - 7200, content: '', tags: [['a', A, '', 'root']] }, STALE.sk); const reaction = finalizeEvent({kind:7,created_at:now-10,content:'๐',tags:[['e',chat.id],['p',FAN.pk],['k','1311']]},HOST.sk); const messageZap = finalizeEvent({kind:9737,created_at:now-9,content:'nice comment',tags:[['e',chat.id],['p',FAN.pk],['P',HOST.pk],['amount','5'],['network','regtest']]},HOST.sk); // and months of older ones, past the first ask's month: the grid pages back through them @@ -62,7 +65,7 @@ const OLD = Array.from({ length: 130 }, (_, i) => finalizeEvent({ kind: 30311, c ['d', 'old-' + i], ['title', 'Old stream ' + i], ['status', 'ended'], ['streaming', STREAM], ['recording', STREAM], ['ends', String(now - 31 * 86400 - i * 3600)], ['p', HOST.pk, '', 'Host'], ] }, SERVICE.sk)); -const FIXTURES = [live, stale, past, pastPage, chat, zap, reaction, messageZap, ...OLD]; +const FIXTURES = [live, stale, past, pastPage, chat, zap, reaction, messageZap, here, longGone, ...OLD]; 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) @@ -194,6 +197,12 @@ try { check('the host\'s face on their post wears the live ring', await waitFor((pk) => !!document.querySelector('.notes-feed .note-post .note-avatar.live-ring'), 5000)); await page.evaluate(() => document.querySelector('.notes-feed .note-post .note-avatar.live-ring').click()); check('...and a tap on it opens the stream', await waitFor(() => !!document.querySelector('.live-page'), 5000)); + const lay = await page.evaluate(() => { + const r = (q) => document.querySelector(q)?.getBoundingClientRect(); + const p = r('.live-page .live-player'), c = r('.live-page .live-chat'); + return { w: document.body.clientWidth, player: p && [p.left, p.width], chat: c && [c.left, c.width] }; + }); + check('on a phone the picture runs edge to edge and the chat is as wide', lay.player && lay.player[0] === 0 && lay.player[1] === lay.w && lay.chat && lay.chat[0] === 0 && lay.chat[1] === lay.w, JSON.stringify(lay)); 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()); @@ -206,9 +215,15 @@ try { // a stream that's on plays through hls.js (kept near the live edge), not Chrome's own player check('...through hls.js, kept near the live edge', await page.evaluate(() => document.querySelector('video.live-video').currentSrc.startsWith('blob:'))); check('the chat shows what was said', await waitText('hello from the chat', 8000)); + const who = () => page.evaluate(() => { const x = document.querySelector('.live-page .live-watching'); return x && { text: x.textContent, title: x.getAttribute('title') || '' }; }); + check('"watching" names who, on hover: the fan and this viewer, not someone long gone', await waitFor(() => (document.querySelector('.live-page .live-watching')?.getAttribute('title') || '').split(', ').length === 2, 8000), JSON.stringify(await who())); + check('...this viewer said they\'re here (a 10312 for the stream)', await page.evaluate((a) => window.__published.some((e) => e.kind === 10312 && e.tags.some((t) => t[0] === 'a' && t[1] === a)), A)); + await page.evaluate(() => document.querySelector('.live-page .live-watching').click()); + check('...a tap shows their faces', await waitFor(() => document.querySelectorAll('.live-page .live-who .live-who-p').length === 2, 3000)); check('...and the zap, its amount and words', await waitText('zapped 21 sats', 5000) && await waitText('great stream', 1000)); const rowSel = '.live-message[data-key="' + chat.id + '"]'; check('comments use the group-chat bubble and shared composer', await page.$(rowSel + ' .chat-bubble') && await page.$('.live-page coinos-text#msg-draft')); + check('...drawn plain on a phone, no bubble walls', await page.evaluate((q) => { const b = document.querySelector(q); return b && getComputedStyle(b).borderStyle === 'none' && getComputedStyle(b).display === 'block'; }, rowSel + ' .chat-bubble')); check('another clientโs e-only reaction arrives on the comment', await waitFor(id => document.querySelector('.live-message[data-key="'+id+'"] .chat-reacts')?.textContent.includes('๐'), 6000, chat.id)); check('per-comment zap receipts show under the bubble', await waitFor(id => document.querySelector('.live-message[data-key="'+id+'"] .zap-tally')?.textContent.includes('5'), 6000, chat.id)); await page.click(rowSel + ' .chat-bubble'); @@ -253,21 +268,24 @@ try { console.log('\n[leaving]'); await page.goBack(); check('Back leaves the stream\'s page', await waitFor(() => !document.querySelector('.live-page'), 5000)); + check('...and takes back this viewer\'s presence (an empty 10312)', await waitFor(() => window.__published.some((e) => e.kind === 10312 && !e.tags.some((t) => t[0] === 'a')), 3000)); check('...and nothing plays on behind it', await page.evaluate(() => [...document.querySelectorAll('video')].every((v) => v.paused || !v.isConnected))); await page.evaluate(() => document.querySelector('.media-mode[data-mode="all"]').click()); await waitFor(() => !!document.querySelector('.notes-feed .live-card'), 5000); 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)); - await page.evaluate(() => [...document.querySelectorAll('.live-past-row .live-tile')].find((t) => /Zelda on Rumble/.test(t.innerText)).click()); + check('the host\'s profile has a Streams tab', await waitFor(() => !!document.querySelector('.prof-tabs [data-tab="streams"]'), 10000) && !(await page.$('.live-past'))); + await page.evaluate(() => document.querySelector('.prof-tabs [data-tab="streams"]').click()); + check('...listing their past streams', await waitFor(() => [...document.querySelectorAll('.live-past .live-tile')].some((t) => /Yesterday on coinos/.test(t.innerText)), 10000)); + await page.evaluate(() => [...document.querySelectorAll('.live-past .live-tile')].find((t) => /Zelda on Rumble/.test(t.innerText)).click()); check('a recording kept as a web page: ended, and a link to watch it there, no player', await waitFor(() => !!document.querySelector('.live-page a.live-rec-link[href="https://rumble.com/v7gt2va-zelda.html"]'), 5000) && await page.evaluate(() => /This stream has ended/.test(document.body.innerText) && !document.querySelector('.live-page video.live-video'))); await page.goBack(); await waitFor(() => !document.querySelector('.live-page'), 5000); 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()); + await page.evaluate(() => [...document.querySelectorAll('.live-past .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(' | ')); |
