@@ -11,7 +11,7 @@ import { CloudRequest } from '../api/cloud_request'
1111import  {  isRetryableError  }  from  '../network/is_retryable_error' 
1212import  {  asyncRetry  }  from  '../../util/async_retry' 
1313import  {  postStudioSession  }  from  '../api/studio/post_studio_session' 
14- import  type  {  StudioStatus  }  from  '@packages/types' 
14+ import  type  {  StudioServerOptions ,   StudioStatus  }  from  '@packages/types' 
1515import  path  from  'path' 
1616import  os  from  'os' 
1717import  {  ensureStudioBundle  }  from  './ensure_studio_bundle' 
@@ -39,7 +39,6 @@ export class StudioLifecycleManager {
3939  private  currentStudioHash ?: string 
4040
4141  private  initializationParams ?: { 
42-     projectId ?: string 
4342    cloudDataSource : CloudDataSource 
4443    cfg : Cfg 
4544    debugData : any 
@@ -55,20 +54,17 @@ export class StudioLifecycleManager {
5554  /** 
5655   * Initialize the studio manager and possibly set up protocol. 
5756   * Also registers this instance in the data context. 
58-    * @param  projectId The project ID 
5957   * @param  cloudDataSource The cloud data source 
6058   * @param  cfg The project configuration 
6159   * @param  debugData Debug data for the configuration 
6260   * @param  ctx Data context to register this instance with 
6361   */ 
6462  initializeStudioManager  ( { 
65-     projectId, 
6663    cloudDataSource, 
6764    cfg, 
6865    debugData, 
6966    ctx, 
7067  } : { 
71-     projectId ?: string 
7268    cloudDataSource : CloudDataSource 
7369    cfg : Cfg 
7470    debugData : any 
@@ -77,7 +73,7 @@ export class StudioLifecycleManager {
7773    debug ( 'Initializing studio manager' ) 
7874
7975    // Store initialization parameters for retry 
80-     this . initializationParams  =  {  projectId ,   cloudDataSource,  cfg,  debugData,  ctx } 
76+     this . initializationParams  =  {  cloudDataSource,  cfg,  debugData,  ctx } 
8177
8278    // Register this instance in the data context 
8379    ctx . update ( ( data )  =>  { 
@@ -88,48 +84,64 @@ export class StudioLifecycleManager {
8884
8985    this . updateStatus ( 'INITIALIZING' ) 
9086
87+     const  getProjectOptions  =  async  ( )  =>  { 
88+       const  [ user ,  config ]  =  await  Promise . all ( [ 
89+         ctx . actions . auth . authApi . getUser ( ) , 
90+         ctx . project . getConfig ( ) , 
91+       ] ) 
92+ 
93+       return  { 
94+         user, 
95+         projectSlug : config . projectId  ||  undefined , 
96+       } 
97+     } 
98+ 
9199    const  studioManagerPromise  =  this . createStudioManager ( { 
92-       projectId, 
93100      cloudDataSource, 
94101      cfg, 
95102      debugData, 
103+       getProjectOptions, 
96104    } ) . catch ( async  ( error )  =>  { 
97105      debug ( 'Error during studio manager setup: %o' ,  error ) 
98106
99-       const  {  cloudUrl,  cloudHeaders }  =  await  getCloudMetadata ( cloudDataSource ) 
100- 
101-       reportStudioError ( { 
102-         cloudApi : { 
103-           cloudUrl, 
104-           cloudHeaders, 
105-           CloudRequest, 
106-           isRetryableError, 
107-           asyncRetry, 
108-         } , 
109-         studioHash : this . currentStudioHash , 
110-         projectSlug : cfg . projectId , 
111-         error, 
112-         studioMethod : 'initializeStudioManager' , 
113-         studioMethodArgs : [ ] , 
114-       } ) 
107+       try  { 
108+         const  {  cloudUrl,  cloudHeaders }  =  await  getCloudMetadata ( cloudDataSource ) 
109+ 
110+         reportStudioError ( { 
111+           cloudApi : { 
112+             cloudUrl, 
113+             cloudHeaders, 
114+             CloudRequest, 
115+             isRetryableError, 
116+             asyncRetry, 
117+           } , 
118+           studioHash : this . currentStudioHash , 
119+           projectSlug : ( await  getProjectOptions ( ) ) . projectSlug , 
120+           error, 
121+           studioMethod : 'initializeStudioManager' , 
122+           studioMethodArgs : [ ] , 
123+         } ) 
115124
116-       this . updateStatus ( 'IN_ERROR' ) 
125+          this . updateStatus ( 'IN_ERROR' ) 
117126
118-       telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . BUNDLE_LIFECYCLE_END ) 
119-       reportTelemetry ( BUNDLE_LIFECYCLE_TELEMETRY_GROUP_NAMES . COMPLETE_BUNDLE_LIFECYCLE ,  { 
120-         success : false , 
121-       } ) 
127+         telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . BUNDLE_LIFECYCLE_END ) 
128+         reportTelemetry ( BUNDLE_LIFECYCLE_TELEMETRY_GROUP_NAMES . COMPLETE_BUNDLE_LIFECYCLE ,  { 
129+           success : false , 
130+         } ) 
131+       }  catch  ( error )  { 
132+         debug ( 'Error reporting studio error: %o' ,  error ) 
133+       } 
122134
123135      return  null 
124136    } ) 
125137
126138    this . studioManagerPromise  =  studioManagerPromise 
127139
128140    this . setupWatcher ( { 
129-       projectId, 
130141      cloudDataSource, 
131142      cfg, 
132143      debugData, 
144+       getProjectOptions, 
133145    } ) 
134146  } 
135147
@@ -158,29 +170,31 @@ export class StudioLifecycleManager {
158170  } 
159171
160172  private  async  createStudioManager  ( { 
161-     projectId, 
162173    cloudDataSource, 
163174    cfg, 
164175    debugData, 
176+     getProjectOptions, 
165177  } : { 
166-     projectId ?: string 
167178    cloudDataSource : CloudDataSource 
168179    cfg : Cfg 
169180    debugData : any 
181+     getProjectOptions : StudioServerOptions [ 'getProjectOptions' ] 
170182  } ) : Promise < StudioManager >  { 
171183    let  studioPath : string 
172184    let  manifest : Record < string ,  string > 
173185
186+     const  currentProjectOptions  =  await  getProjectOptions ( ) 
187+ 
174188    initializeTelemetryReporter ( { 
175-       projectSlug : projectId , 
189+       projectSlug : currentProjectOptions . projectSlug , 
176190      cloudDataSource, 
177191    } ) 
178192
179193    telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . BUNDLE_LIFECYCLE_START ) 
180194
181195    telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . POST_STUDIO_SESSION_START ) 
182196    const  studioSession  =  await  postStudioSession ( { 
183-       projectId, 
197+       projectId :  currentProjectOptions . projectSlug , 
184198    } ) 
185199
186200    telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . POST_STUDIO_SESSION_END ) 
@@ -192,22 +206,27 @@ export class StudioLifecycleManager {
192206
193207      studioPath  =  path . join ( os . tmpdir ( ) ,  'cypress' ,  'studio' ,  studioHash ) 
194208
209+       debug ( 'Setting current studio hash: %s' ,  studioHash ) 
195210      // Store the current studio hash so that we can clear the cache entry when retrying 
196211      this . currentStudioHash  =  studioHash 
197212
198213      let  hashLoadingPromise  =  StudioLifecycleManager . hashLoadingMap . get ( studioHash ) 
199214
200215      if  ( ! hashLoadingPromise )  { 
216+         debug ( 'Ensuring studio bundle for hash: %s' ,  studioHash ) 
217+ 
201218        hashLoadingPromise  =  ensureStudioBundle ( { 
202219          studioUrl : studioSession . studioUrl , 
203220          studioPath, 
204-           projectId, 
221+           projectId :  currentProjectOptions . projectSlug , 
205222        } ) 
206223
207224        StudioLifecycleManager . hashLoadingMap . set ( studioHash ,  hashLoadingPromise ) 
208225      } 
209226
210227      manifest  =  await  hashLoadingPromise 
228+ 
229+       debug ( 'Manifest: %o' ,  manifest ) 
211230    }  else  { 
212231      studioPath  =  process . env . CYPRESS_LOCAL_STUDIO_PATH 
213232      this . currentStudioHash  =  'local' 
@@ -225,10 +244,14 @@ export class StudioLifecycleManager {
225244      const  actualHash  =  crypto . createHash ( 'sha256' ) . update ( script ) . digest ( 'hex' ) 
226245
227246      if  ( ! expectedHash )  { 
247+         debug ( 'Expected hash %s for studio server script not found in manifest: %o' ,  expectedHash ,  manifest ) 
248+ 
228249        throw  new  Error ( 'Expected hash for studio server script not found in manifest' ) 
229250      } 
230251
231252      if  ( actualHash  !==  expectedHash )  { 
253+         debug ( 'Invalid hash for studio server script: %s !== %s' ,  actualHash ,  expectedHash ) 
254+ 
232255        throw  new  Error ( 'Invalid hash for studio server script' ) 
233256      } 
234257    } 
@@ -243,16 +266,15 @@ export class StudioLifecycleManager {
243266      script, 
244267      studioPath, 
245268      studioHash : this . currentStudioHash , 
246-       projectSlug : projectId , 
247269      cloudApi : { 
248270        cloudUrl, 
249271        cloudHeaders, 
250272        CloudRequest, 
251273        isRetryableError, 
252274        asyncRetry, 
253275      } , 
254-       shouldEnableStudio : this . cloudStudioRequested , 
255276      manifest, 
277+       getProjectOptions, 
256278    } ) 
257279
258280    telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . STUDIO_MANAGER_SETUP_END ) 
@@ -269,7 +291,7 @@ export class StudioLifecycleManager {
269291      telemetryManager . mark ( BUNDLE_LIFECYCLE_MARK_NAMES . STUDIO_PROTOCOL_PREPARE_START ) 
270292      await  protocolManager . prepareProtocol ( script ,  { 
271293        runId : 'studio' , 
272-         projectId : cfg . projectId , 
294+         projectId : currentProjectOptions . projectSlug , 
273295        testingType : cfg . testingType , 
274296        cloudApi : { 
275297          url : routes . apiUrl , 
@@ -319,15 +341,15 @@ export class StudioLifecycleManager {
319341  } 
320342
321343  private  setupWatcher  ( { 
322-     projectId, 
323344    cloudDataSource, 
324345    cfg, 
325346    debugData, 
347+     getProjectOptions, 
326348  } : { 
327-     projectId ?: string 
328349    cloudDataSource : CloudDataSource 
329350    cfg : Cfg 
330351    debugData : any 
352+     getProjectOptions : StudioServerOptions [ 'getProjectOptions' ] 
331353  } )  { 
332354    // Don't setup a watcher if the studio bundle is NOT local 
333355    if  ( ! process . env . CYPRESS_LOCAL_STUDIO_PATH )  { 
@@ -347,10 +369,10 @@ export class StudioLifecycleManager {
347369      await  this . studioManager ?. destroy ( ) 
348370      this . studioManager  =  undefined 
349371      this . studioManagerPromise  =  this . createStudioManager ( { 
350-         projectId, 
351372        cloudDataSource, 
352373        cfg, 
353374        debugData, 
375+         getProjectOptions, 
354376      } ) . then ( ( studioManager )  =>  { 
355377        // eslint-disable-next-line no-console 
356378        console . log ( 'Studio manager reloaded' ) 
0 commit comments