diff options
Diffstat (limited to 'packages/meshbay-hub/tests/harness/music_queue_probe.py')
| -rwxr-xr-x | packages/meshbay-hub/tests/harness/music_queue_probe.py | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/packages/meshbay-hub/tests/harness/music_queue_probe.py b/packages/meshbay-hub/tests/harness/music_queue_probe.py index f74ceb2..a9146ce 100755 --- a/packages/meshbay-hub/tests/harness/music_queue_probe.py +++ b/packages/meshbay-hub/tests/harness/music_queue_probe.py @@ -119,12 +119,24 @@ function Harness() { const onPlayQueue = useCallback((tracks, startIndex, source, op) => { setQueue({ tracks, startIndex, nonce: Date.now(), op: op || 'replace' }); }, []); + // A queue that crosses groups cannot be built from one group's page, and + // that is the case the skipping rule exists for — so the probe reaches in + // for that one step rather than pretending a gesture builds it. + window.__probePlayQueue = onPlayQueue; + + // Rejects at once for a group nothing serves, and hangs for every other — + // hanging is what the stub node does anyway, and what matters here is which + // track the playhead lands on, not whether anything plays. + const getConnection = (groupId) => (String(groupId).startsWith('dead') + ? Promise.reject(new Error('no node')) + : new Promise(() => {})); + return html` <${GroupPage} groupId="g1" token="t" username="me" userId="u1" group=${{ id: 'g1', name: 'un groupe', owner_username: 'me', is_admin: false }} userPrefs=${{ default_tab: 'music', media_page_size: '50' }} onPlayQueue=${onPlayQueue} /> - ${queue && html`<${MusicPlayerBar} getConnection=${() => new Promise(() => {})} + ${queue && html`<${MusicPlayerBar} getConnection=${getConnection} queue=${queue} userPrefs=${{}} onClose=${() => setQueue(null)} />`} `; } @@ -171,9 +183,29 @@ const clickMenu = async (i) => { await initLocale(); render(html`<${Harness} />`, document.getElementById('root')); - if (!await waitFor('.music-card')) return fail('no album grid'); + // Wait for the grid to be *complete*, not merely present — and scroll, + // because it will not complete otherwise: the tiles mount on intersection + // (`LazyTile`), so an album below the fold has no card at all until the + // page is scrolled to it. A probe that counts what happens to be on screen + // is measuring the height of its own iframe; adding one button to the + // toolbar was enough to push the fourth album out of view. + const waitForCount = async (sel, n, tries = 80) => { + for (let i = 0; i < tries; i++) { + if (document.querySelectorAll(sel).length >= n) { + scrollTo(0, 0); + await sleep(100); + return true; + } + scrollTo(0, document.documentElement.scrollHeight); + await sleep(50); + } + return false; + }; + if (!await waitForCount('.music-card', 4)) { + return fail('expected 4 albums, got ' + + document.querySelectorAll('.music-card').length); + } const cards = [...document.querySelectorAll('.music-card')]; - if (cards.length < 4) return fail('expected 4 albums, got ' + cards.length); // 1. Open album 1 and play its second track — the ordinary path, through a // row that is no longer one big button. @@ -219,6 +251,26 @@ const clickMenu = async (i) => { await sleep(250); await queueNow('replace with album 4'); + // 6. A group that does not answer: every one of its queued tracks is + // skipped in one step, not one failure at a time against a bound that + // was sized for corrupt files. + const mixed = (id, group) => ({ + id, name: id + '.flac', display_title: id, path: 'p', size: 10, + type: 'audio', duration: 100, groupId: group, + }); + window.__probePlayQueue([ + mixed('live-1', 'g1'), + mixed('dead-1', 'dead-a'), mixed('dead-2', 'dead-a'), + mixed('dead-3', 'dead-a'), mixed('dead-4', 'dead-a'), + mixed('dead-5', 'dead-a'), mixed('dead-6', 'dead-a'), + mixed('live-2', 'g1'), + ], 1, null, 'replace'); + await sleep(1200); + steps.push({ + step: 'an unreachable group is skipped whole', + nowPlaying: (document.querySelector('.music-player-title') || {}).textContent || null, + }); + parent.postMessage({ steps, logs: LOGS.slice(0, 8) }, '*'); } catch (err) { fail(String((err && err.stack) || err)); |