@@ -24,6 +24,18 @@ const defaultOptions = {
2424let browser = null
2525const sleep = ms => new Promise ( function ( resolve ) { setTimeout ( resolve , ms ) } )
2626
27+ const waitForCondition = async ( page , expression , timeout = 15000 ) => {
28+ const start = Date . now ( )
29+ while ( Date . now ( ) - start < timeout ) {
30+ const result = await page . evaluate ( expression )
31+ if ( result ) {
32+ return result
33+ }
34+ await new Promise ( resolve => setTimeout ( resolve , 500 ) )
35+ }
36+ return await page . evaluate ( expression )
37+ }
38+
2739afterEach ( async ( ) => {
2840 if ( browser ) {
2941 const pages = await browser . pages ( )
@@ -76,13 +88,11 @@ defineFeature(feature, test => {
7688 return startViewer ( streamName , accountId )
7789 } , { streamName, accountId : process . env . ACCOUNT_ID } )
7890
79- await sleep ( 3000 )
8091 isActive = await broadcastPage . evaluate ( 'window.publish.isActive()' )
8192 videoFrame1 = await viewerPage . evaluate ( 'getVideoPixelSums()' )
82- await sleep ( 500 )
93+ await sleep ( 1000 )
8394 videoFrame2 = await viewerPage . evaluate ( 'getVideoPixelSums()' )
8495 } )
85-
8696 then ( 'broadcast is active and Viewer receive video data' , async ( ) => {
8797 expect ( isActive ) . toBeTruthy ( )
8898 expect ( videoFrame1 ) . not . toBe ( 0 )
@@ -181,26 +191,47 @@ defineFeature(feature, test => {
181191 test ( 'Simulcast layer generation' , ( { given, when, then } ) => {
182192 let broadcastPage
183193 given ( / ^ a b r o a d c a s t e r w i t h s i m u l c a s t e n a b l e d a n d c o d e c ( .* ) $ / , async ( codec ) => {
184- if ( ! browser ) browser = await puppeteer . launch ( { headless : true , executablePath : puppeteer . executablePath ( ) , args : [ '--no-sandbox' , '--use-fake-ui-for-media-stream' , '--use-fake-device-for-media-stream' , '--allow-file-access-from-files' ] } )
194+ if ( ! browser ) {
195+ browser = await puppeteer . launch ( {
196+ headless : true ,
197+ executablePath : puppeteer . executablePath ( ) ,
198+ args : [
199+ '--no-sandbox' ,
200+ '--use-fake-ui-for-media-stream' ,
201+ '--use-fake-device-for-media-stream' ,
202+ '--allow-file-access-from-files'
203+ ]
204+ } )
205+ }
185206 broadcastPage = await browser . newPage ( )
186207 await broadcastPage . goto ( pageLocation )
187208 await broadcastPage . evaluate ( ( { token, streamName, codec } ) => {
188- return startPublisher ( token , streamName , { codec, simulcast : true } )
209+ return startPublisher ( token , streamName , {
210+ codec,
211+ simulcast : true ,
212+ metadata : true
213+ } )
189214 } , { token : process . env . PUBLISH_TOKEN , streamName, codec } )
190215 } )
191216
192217 when ( 'the stream is active' , async ( ) => {
193- await sleep ( 6000 )
218+ await waitForCondition ( broadcastPage , 'window.publish.isActive()' )
194219 } )
195220
196221 then ( 'the publisher reports multiple active simulcast layers' , async ( ) => {
197- const layers = await broadcastPage . evaluate ( async ( ) => {
198- const stats = await window . publish . getRTCPeerConnection ( ) . getStats ( )
199- let count = 0
200- stats . forEach ( r => { if ( r . type === 'outbound-rtp' && r . kind === 'video' ) count ++ } )
201- return count
202- } )
203- expect ( layers ) . toBeGreaterThan ( 1 )
222+ const layersFound = await waitForCondition ( broadcastPage , `
223+ (async () => {
224+ const pc = window.publish?.getRTCPeerConnection();
225+ if (!pc) return false;
226+ const stats = await pc.getStats();
227+ let count = 0;
228+ stats.forEach(r => {
229+ if (r.type === 'outbound-rtp' && r.kind === 'video') count++;
230+ });
231+ return count > 1 ? count : false;
232+ })()
233+ ` , 20000 )
234+ expect ( layersFound ) . toBeGreaterThan ( 1 )
204235 } )
205236 } )
206237} )
0 commit comments