From 76a04065df9e68f4f26ec9b9911b6c4427e06c40 Mon Sep 17 00:00:00 2001 From: Jonathan Baldie Date: Sat, 2 May 2026 13:27:09 +0100 Subject: [PATCH] test: add SmartSpeedInit focused unit test from na9 Cherry-picked from bead/audiobookshelf-na9-playerui-init (8c645cdf). Adds focused unit test that proves Smart Speed worklet initialization works correctly. Tests LocalAudioPlayer.setSmartSpeed() directly and verifies audioWorklet.addModule is called with SilenceDetectorProcessor.js. Closes audiobookshelf-na9. --- .../tests/players/SmartSpeedInit.cy.js | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 client/cypress/tests/players/SmartSpeedInit.cy.js diff --git a/client/cypress/tests/players/SmartSpeedInit.cy.js b/client/cypress/tests/players/SmartSpeedInit.cy.js new file mode 100644 index 00000000..165aa42b --- /dev/null +++ b/client/cypress/tests/players/SmartSpeedInit.cy.js @@ -0,0 +1,96 @@ +import LocalAudioPlayer from '../../../players/LocalAudioPlayer' + +describe('Smart Speed Initialization', () => { + it('calls audioWorklet.addModule when Smart Speed is enabled', () => { + const audioContext = { + destination: { label: 'destination' }, + state: 'running', + currentTime: 0, + resume: cy.stub().resolves(), + suspend: cy.stub().resolves(), + close: cy.stub().resolves(), + createMediaElementSource: cy.stub().returns({ + connect: cy.stub(), + disconnect: cy.stub() + }), + audioWorklet: { + addModule: cy.stub().resolves().as('audioWorkletAddModule') + } + } + + cy.window().then((win) => { + // Create a mock audio element + const audioElement = win.document.createElement('audio') + audioElement.id = 'test-audio' + audioElement.src = '/__cypress/fixtures/test-audio.wav' + win.document.body.appendChild(audioElement) + + // Mock AudioWorkletNode + win.AudioWorkletNode = function AudioWorkletNode() { + return { + connect: cy.stub(), + disconnect: cy.stub(), + port: { + onmessage: null, + postMessage: cy.stub() + } + } + } + + // Create player instance + const player = new LocalAudioPlayer() + player.player = audioElement + player.audioContext = audioContext + player.usingWebAudio = true + player.audioSourceNode = audioContext.createMediaElementSource(audioElement) + player.smartSpeedRatio = 2.5 + + // Call setSmartSpeed with enabled=true + player.setSmartSpeed(true).then(() => { + // Verify audioWorklet.addModule was called with the correct path + cy.get('@audioWorkletAddModule').should('have.been.calledOnce') + cy.get('@audioWorkletAddModule').should( + 'have.been.calledWith', + '/client/players/smart-speed/SilenceDetectorProcessor.js' + ) + }) + }) + }) + + it('does not initialize worklet when Smart Speed is disabled', () => { + const audioContext = { + destination: { label: 'destination' }, + state: 'running', + currentTime: 0, + resume: cy.stub().resolves(), + suspend: cy.stub().resolves(), + close: cy.stub().resolves(), + createMediaElementSource: cy.stub().returns({ + connect: cy.stub(), + disconnect: cy.stub() + }), + audioWorklet: { + addModule: cy.stub().resolves().as('audioWorkletAddModule') + } + } + + cy.window().then((win) => { + const audioElement = win.document.createElement('audio') + audioElement.id = 'test-audio' + audioElement.src = '/__cypress/fixtures/test-audio.wav' + win.document.body.appendChild(audioElement) + + const player = new LocalAudioPlayer() + player.player = audioElement + player.audioContext = audioContext + player.usingWebAudio = true + player.audioSourceNode = audioContext.createMediaElementSource(audioElement) + + // Call setSmartSpeed with enabled=false + player.setSmartSpeed(false).then(() => { + // Verify audioWorklet.addModule was NOT called + cy.get('@audioWorkletAddModule').should('not.have.been.called') + }) + }) + }) +})