Skip to content

Commit 0f4384b

Browse files
astone123mschile
andauthored
internal: (studio) persist telemetry session ID in URL (#32170)
* internal: (studio) persist telemetry session ID in URL * update sessionId name, update assertions * fix url params * fix test * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * Update packages/app/src/store/studio-store.ts Co-authored-by: Matt Schile <[email protected]> * update variable names --------- Co-authored-by: Matt Schile <[email protected]>
1 parent c46b3c3 commit 0f4384b

File tree

5 files changed

+88
-30
lines changed

5 files changed

+88
-30
lines changed

packages/app/cypress/e2e/studio/studio-cloud.cy.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,4 +505,44 @@ describe('studio functionality', () => {
505505
})
506506
})
507507
})
508+
509+
it('persists sessionId across page refresh', () => {
510+
launchStudio()
511+
512+
cy.findByTestId('studio-panel').should('be.visible')
513+
514+
cy.location().its('hash').should('contain', 'sessionId=')
515+
516+
let originalSessionId: string
517+
518+
cy.location('hash').then((hash) => {
519+
const urlParams = new URLSearchParams(hash)
520+
521+
originalSessionId = urlParams.get('sessionId')!
522+
523+
expect(originalSessionId).to.be.a('string')
524+
expect(originalSessionId).to.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
525+
})
526+
527+
cy.reload()
528+
529+
cy.waitForSpecToFinish()
530+
531+
cy.findByTestId('studio-panel').should('be.visible')
532+
533+
cy.location().its('hash').should('contain', 'sessionId=')
534+
535+
cy.location('hash').then((hash) => {
536+
const urlParams = new URLSearchParams(hash)
537+
const persistedSessionId = urlParams.get('sessionId')
538+
539+
expect(persistedSessionId).to.equal(originalSessionId)
540+
})
541+
542+
cy.findByTestId('studio-header-studio-button').click()
543+
544+
cy.location().its('hash').should('not.contain', 'sessionId=')
545+
546+
cy.findByTestId('studio-panel').should('not.exist')
547+
})
508548
})

packages/app/cypress/e2e/studio/studio.cy.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -664,21 +664,21 @@ describe('studio functionality', () => {
664664
it('updates the url with the testId and studio parameters when entering studio with a test', () => {
665665
launchStudio()
666666

667-
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=')
667+
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=').and('contain', 'sessionId=')
668668
})
669669

670670
it('update the url with the suiteId and studio parameters when entering studio with a suite', () => {
671671
launchStudio({ createNewTestFromSuite: true })
672672

673-
cy.location().its('hash').should('contain', 'suiteId=r2').and('contain', 'studio=')
673+
cy.location().its('hash').should('contain', 'suiteId=r2').and('contain', 'studio=').and('contain', 'sessionId=')
674674
})
675675

676676
it('updates the studio url parameters and displays the single test view after creating a new test', () => {
677677
loadProjectAndRunSpec()
678678

679679
// open the studio panel to create a new test in the root suite
680680
cy.findByTestId('studio-button').click()
681-
cy.location().its('hash').should('contain', 'suiteId=r1').and('contain', 'studio=')
681+
cy.location().its('hash').should('contain', 'suiteId=r1').and('contain', 'studio=').and('contain', 'sessionId=')
682682

683683
// create a new test in the root suite
684684
inputNewTestName()
@@ -694,7 +694,7 @@ describe('studio functionality', () => {
694694
it('does not remove the studio url parameters when saving test changes', () => {
695695
launchStudio()
696696

697-
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=')
697+
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=').and('contain', 'sessionId=')
698698

699699
cy.findByTestId('record-button-recording').should('be.visible')
700700

@@ -706,7 +706,7 @@ describe('studio functionality', () => {
706706

707707
cy.findByTestId('studio-save-button').click()
708708

709-
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=')
709+
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=').and('contain', 'sessionId=')
710710
})
711711

712712
it('does not remove the studio url parameters if saving fails', () => {
@@ -716,7 +716,7 @@ describe('studio functionality', () => {
716716

717717
incrementCounter(0)
718718

719-
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=')
719+
cy.location().its('hash').should('contain', 'testId=r3').and('contain', 'studio=').and('contain', 'sessionId=')
720720

721721
// update the spec on the file system by changing the
722722
// test name which will cause the save to fail since
@@ -757,7 +757,7 @@ describe('studio functionality', () => {
757757

758758
cy.findByTestId('studio-header-studio-button').click()
759759

760-
cy.location().its('hash').and('not.contain', 'testId=').and('not.contain', 'studio=')
760+
cy.location().its('hash').and('not.contain', 'testId=').and('not.contain', 'studio=').and('not.contain', 'sessionId=')
761761
})
762762

763763
it('does not prompt for a URL until studio is active', () => {

packages/app/src/runner/SpecRunnerOpenMode.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<StudioPanel
9393
v-if="shouldShowStudioPanel"
9494
data-cy="studio-panel"
95-
:cloud-studio-session-id="studioStore.cloudStudioSessionId"
95+
:cloud-studio-session-id="studioStore.sessionId"
9696
:can-access-studio-a-i="studioStore.canAccessStudioAI"
9797
:on-studio-panel-close="handleStudioPanelClose"
9898
:event-manager="eventManager"

packages/app/src/runner/event-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ export class EventManager {
281281
}
282282

283283
this.studioStore.setCanAccessStudioAI(canAccessStudioAI)
284-
this.studioStore.setCloudStudioSessionId(cloudStudioSessionId)
284+
this.studioStore.setSessionId(cloudStudioSessionId)
285285
// when we enter studio with a new test, we don't want to rerun until
286286
// the the test has been created, so we just set the studio active
287287
this.studioStore.setActive(true)
@@ -298,7 +298,7 @@ export class EventManager {
298298
}
299299

300300
this.studioStore.setCanAccessStudioAI(canAccessStudioAI)
301-
this.studioStore.setCloudStudioSessionId(cloudStudioSessionId)
301+
this.studioStore.setSessionId(cloudStudioSessionId)
302302
rerun()
303303
})
304304
})

packages/app/src/store/studio-store.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,30 @@ interface StudioRecorderState {
108108
canAccessStudioAI: boolean
109109
showUrlPrompt: boolean
110110
cloudStudioRequested: boolean
111-
cloudStudioSessionId?: string
111+
sessionId?: string
112112
_isStudioCreatedTest: boolean
113113
newTestLineNumber?: number
114114
}
115115

116+
function getUrlParams () {
117+
const url = new URL(window.location.href)
118+
const hashParams = new URLSearchParams(url.hash)
119+
120+
const testId = hashParams.get('testId')
121+
const suiteId = hashParams.get('suiteId')
122+
const visitUrl = hashParams.get('url')
123+
const newTestLineNumber = hashParams.get('newTestLineNumber') ? Number(hashParams.get('newTestLineNumber')) : undefined
124+
const sessionId = hashParams.get('sessionId')
125+
126+
return { testId, suiteId, url: visitUrl, newTestLineNumber, sessionId }
127+
}
128+
116129
export const useStudioStore = defineStore('studioRecorder', {
117130
state: (): StudioRecorderState => {
131+
// try to restore sessionId from URL parameters
132+
const urlParams = getUrlParams()
133+
const persistedSessionId = urlParams.sessionId || undefined
134+
118135
return {
119136
saveModalIsOpen: false,
120137
instructionModalIsOpen: false,
@@ -128,7 +145,7 @@ export const useStudioStore = defineStore('studioRecorder', {
128145
canAccessStudioAI: false,
129146
showUrlPrompt: true,
130147
cloudStudioRequested: false,
131-
cloudStudioSessionId: undefined,
148+
sessionId: persistedSessionId,
132149
newTestLineNumber: undefined,
133150
_isStudioCreatedTest: false,
134151
}
@@ -160,8 +177,14 @@ export const useStudioStore = defineStore('studioRecorder', {
160177
this.canAccessStudioAI = canAccessStudioAI
161178
},
162179

163-
setCloudStudioSessionId (cloudStudioSessionId: string) {
164-
this.cloudStudioSessionId = cloudStudioSessionId
180+
setSessionId (sessionId: string) {
181+
this.sessionId = sessionId
182+
this._updateUrlParams(['sessionId'])
183+
},
184+
185+
clearSessionId () {
186+
this.sessionId = undefined
187+
this._removeUrlParams(['sessionId'])
165188
},
166189

167190
setNewTestLineNumber (newTestLineNumber: number) {
@@ -213,7 +236,7 @@ export const useStudioStore = defineStore('studioRecorder', {
213236
},
214237

215238
setup (config) {
216-
const studio = this._getUrlParams()
239+
const studio = this.getUrlParams()
217240

218241
if (studio.newTestLineNumber) {
219242
this.setNewTestLineNumber(studio.newTestLineNumber)
@@ -227,6 +250,10 @@ export const useStudioStore = defineStore('studioRecorder', {
227250
this._initialUrl = studio.url
228251
}
229252

253+
if (studio.sessionId) {
254+
this.sessionId = studio.sessionId
255+
}
256+
230257
// if we have an existing test or are creating a new test, we need to start loading
231258
// otherwise if we have a suite, we can just set the studio active
232259
if (this.testId || studio.newTestLineNumber) {
@@ -308,6 +335,7 @@ export const useStudioStore = defineStore('studioRecorder', {
308335
this.clearRunnableIds()
309336
this._removeUrlParams()
310337
this._initialUrl = undefined
338+
this.clearSessionId()
311339
},
312340

313341
startSave () {
@@ -436,21 +464,11 @@ export const useStudioStore = defineStore('studioRecorder', {
436464
}
437465
},
438466

439-
_getUrlParams () {
440-
const url = new URL(window.location.href)
441-
const hashParams = new URLSearchParams(url.hash)
442-
443-
const testId = hashParams.get('testId')
444-
const suiteId = hashParams.get('suiteId')
445-
const visitUrl = hashParams.get('url')
446-
const newTestLineNumber = hashParams.get('newTestLineNumber') ? Number(hashParams.get('newTestLineNumber')) : undefined
447-
448-
return { testId, suiteId, url: visitUrl, newTestLineNumber }
449-
},
467+
getUrlParams,
450468

451-
_updateUrlParams (filter: string[] = ['testId', 'suiteId', 'url', 'newTestLineNumber']) {
469+
_updateUrlParams (filter: string[] = ['testId', 'suiteId', 'url', 'newTestLineNumber', 'sessionId']) {
452470
// if we don't have studio params, we don't need to update them
453-
if (!this.testId && !this.suiteId && !this.url && !this.newTestLineNumber) return
471+
if (!this.testId && !this.suiteId && !this.url && !this.newTestLineNumber && !this.sessionId) return
454472

455473
// if we have studio params, we need to remove them before adding them back
456474
this._removeUrlParams(filter)
@@ -469,7 +487,7 @@ export const useStudioStore = defineStore('studioRecorder', {
469487
window.history.replaceState({}, '', url.toString())
470488
},
471489

472-
_removeUrlParams (filter: string[] = ['testId', 'suiteId', 'url', 'newTestLineNumber']) {
490+
_removeUrlParams (filter: string[] = ['testId', 'suiteId', 'url', 'newTestLineNumber', 'sessionId']) {
473491
const url = new URL(window.location.href)
474492
const hashParams = new URLSearchParams(url.hash)
475493

@@ -482,7 +500,7 @@ export const useStudioStore = defineStore('studioRecorder', {
482500
})
483501

484502
// if there are no studio specific params left, we can also remove the studio param
485-
if (!hashParams.has('testId') && !hashParams.has('suiteId') && !hashParams.has('url') && !hashParams.has('newTestLineNumber')) {
503+
if (!hashParams.has('testId') && !hashParams.has('suiteId') && !hashParams.has('url') && !hashParams.has('newTestLineNumber') && !hashParams.has('sessionId')) {
486504
hashParams.delete('studio')
487505
}
488506

0 commit comments

Comments
 (0)