@@ -102,6 +102,8 @@ async function startRecording({ config, context, step, driver }) {
102102 // Start recording using executeAsync so we properly wait for
103103 // getDisplayMedia() to resolve before switching tabs.
104104 const recorderStarted = await driver . executeAsync ( ( baseName , done ) => {
105+ let stream ;
106+ let recorder ;
105107 const displayMediaOptions = {
106108 video : {
107109 displaySurface : "browser" ,
@@ -115,45 +117,58 @@ async function startRecording({ config, context, step, driver }) {
115117 surfaceSwitching : "include" ,
116118 monitorTypeSurfaces : "include" ,
117119 } ;
118-
119- ( async ( ) => {
120+ async function startCapture ( displayMediaOptions ) {
120121 try {
121- const stream = await navigator . mediaDevices . getDisplayMedia (
122+ const captureStream = await navigator . mediaDevices . getDisplayMedia (
122123 displayMediaOptions
123124 ) ;
124- if ( ! stream ) {
125- done ( false ) ;
126- return ;
127- }
125+ return captureStream ;
126+ } catch ( err ) {
127+ console . error ( `Error: ${ err } ` ) ;
128+ return null ;
129+ }
130+ }
131+ async function captureAndDownload ( ) {
132+ stream = await startCapture ( displayMediaOptions ) ;
133+ if ( stream ) {
134+ await recordStream ( stream ) ;
135+ } else {
136+ done ( false ) ;
137+ }
138+ return stream ;
139+ }
140+ async function recordStream ( stream ) {
141+ window . recorder = new MediaRecorder ( stream , { mimeType : "video/webm" } ) ; // or 'video/mp4'
142+ let data = [ ] ;
128143
129- window . recorder = new MediaRecorder ( stream , { mimeType : "video/webm" } ) ;
130- let data = [ ] ;
144+ window . recorder . ondataavailable = ( event ) => data . push ( event . data ) ;
145+ window . recorder . start ( ) ;
131146
132- window . recorder . ondataavailable = ( event ) => data . push ( event . data ) ;
147+ // Signal that recording has started successfully.
148+ // executeAsync resolves here; the rest continues in the browser.
149+ done ( true ) ;
133150
134- // When recording stops, create a download link for the file
135- window . recorder . onstop = ( ) => {
136- let blob = new Blob ( data , { type : "video/webm" } ) ;
137- let url = URL . createObjectURL ( blob ) ;
138- let a = document . createElement ( "a" ) ;
139- a . style . display = "none" ;
140- a . href = url ;
141- a . download = `${ baseName } .webm` ;
142- document . body . appendChild ( a ) ;
143- a . click ( ) ;
144- setTimeout ( ( ) => {
145- document . body . removeChild ( a ) ;
146- window . URL . revokeObjectURL ( url ) ;
147- } , 100 ) ;
148- } ;
151+ let stopped = new Promise ( ( resolve , reject ) => {
152+ window . recorder . onstop = resolve ;
153+ window . recorder . onerror = ( event ) => reject ( event . name ) ;
154+ } ) ;
149155
150- window . recorder . start ( ) ;
151- done ( true ) ;
152- } catch ( err ) {
153- console . error ( `Error starting recording: ${ err } ` ) ;
154- done ( false ) ;
155- }
156- } ) ( ) ;
156+ await stopped ;
157+
158+ let blob = new Blob ( data , { type : "video/webm" } ) ;
159+ let url = URL . createObjectURL ( blob ) ;
160+ let a = document . createElement ( "a" ) ;
161+ a . style . display = "none" ;
162+ a . href = url ;
163+ a . download = `${ baseName } .webm` ;
164+ document . body . appendChild ( a ) ;
165+ a . click ( ) ;
166+ setTimeout ( ( ) => {
167+ document . body . removeChild ( a ) ;
168+ window . URL . revokeObjectURL ( url ) ;
169+ } , 100 ) ;
170+ }
171+ captureAndDownload ( ) ;
157172 } , baseName ) ;
158173
159174 if ( ! recorderStarted ) {
0 commit comments