Skip to content

Commit 92571ca

Browse files
disable studio recording when selectorplayground is shown
1 parent 9836add commit 92571ca

File tree

2 files changed

+297
-1
lines changed

2 files changed

+297
-1
lines changed

packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx

Lines changed: 280 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import SpecRunnerHeaderOpenMode from './SpecRunnerHeaderOpenMode.vue'
2-
import { useAutStore } from '../store'
2+
import { useAutStore, useSelectorPlaygroundStore } from '../store'
33
import { useStudioStore } from '../store/studio-store'
44
import { SpecRunnerHeaderFragment, SpecRunnerHeaderFragmentDoc } from '../generated/graphql-test'
55
import { createEventManager, createTestAutIframe } from '../../cypress/component/support/ctSupport'
@@ -411,4 +411,283 @@ describe('SpecRunnerHeaderOpenMode', { viewportHeight: 500 }, () => {
411411
cy.findByTestId('studio-button').should('be.visible')
412412
})
413413
})
414+
415+
describe('selector playground and studio recording interaction', () => {
416+
it('disables studio recording when selector playground opens', () => {
417+
const studioStore = useStudioStore()
418+
const selectorPlaygroundStore = useSelectorPlaygroundStore()
419+
420+
// Start with Studio active and recording enabled
421+
studioStore.setActive(true)
422+
423+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
424+
render: (gqlVal) => {
425+
return renderWithGql(gqlVal, true)
426+
},
427+
})
428+
429+
// Verify recording is enabled initially
430+
cy.then(() => {
431+
expect(studioStore.canRecord).to.be.true
432+
})
433+
434+
// Open Selector Playground
435+
cy.findByTestId('playground-activator').click()
436+
437+
// Verify recording is disabled
438+
cy.then(() => {
439+
expect(selectorPlaygroundStore.show).to.be.true
440+
expect(studioStore.canRecord).to.be.false
441+
})
442+
})
443+
444+
it('re-enables studio recording when selector playground closes', () => {
445+
const studioStore = useStudioStore()
446+
const selectorPlaygroundStore = useSelectorPlaygroundStore()
447+
448+
// Start with Studio active
449+
studioStore.setActive(true)
450+
451+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
452+
render: (gqlVal) => {
453+
return renderWithGql(gqlVal, true)
454+
},
455+
})
456+
457+
// Open Selector Playground
458+
cy.findByTestId('playground-activator').click()
459+
460+
cy.then(() => {
461+
expect(selectorPlaygroundStore.show).to.be.true
462+
expect(studioStore.canRecord).to.be.false
463+
})
464+
465+
// Close Selector Playground
466+
cy.findByTestId('playground-activator').click()
467+
468+
// Verify recording is re-enabled
469+
cy.then(() => {
470+
expect(selectorPlaygroundStore.show).to.be.false
471+
expect(studioStore.canRecord).to.be.true
472+
})
473+
})
474+
475+
it('prevents event recording when selector playground is open', () => {
476+
const studioStore = useStudioStore()
477+
478+
studioStore.setActive(true)
479+
480+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
481+
render: (gqlVal) => {
482+
return renderWithGql(gqlVal, true)
483+
},
484+
})
485+
486+
// Open Selector Playground
487+
cy.findByTestId('playground-activator').click()
488+
489+
// Create a mock event and element
490+
cy.then(() => {
491+
const mockEvent = { type: 'click', isTrusted: true } as any
492+
const mock$el = {
493+
prop: (prop: string) => {
494+
if (prop === 'tagName') {
495+
return 'BUTTON'
496+
}
497+
498+
return undefined
499+
},
500+
} as any
501+
502+
// _shouldRecordEvent should return false when SelectorPlayground is open
503+
expect(studioStore._shouldRecordEvent(mockEvent, mock$el)).to.be.false
504+
})
505+
506+
// Close Selector Playground
507+
cy.findByTestId('playground-activator').click()
508+
509+
// Now _shouldRecordEvent should return true (assuming other conditions are met)
510+
cy.then(() => {
511+
const mockEvent = { type: 'click', isTrusted: true } as any
512+
const mock$el = {
513+
prop: (prop: string) => {
514+
if (prop === 'tagName') {
515+
return 'BUTTON'
516+
}
517+
518+
return undefined
519+
},
520+
} as any
521+
522+
expect(studioStore._shouldRecordEvent(mockEvent, mock$el)).to.be.true
523+
})
524+
})
525+
526+
it('disables recording when studio opens while selector playground is already open', () => {
527+
const studioStore = useStudioStore()
528+
const selectorPlaygroundStore = useSelectorPlaygroundStore()
529+
530+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
531+
render: (gqlVal) => {
532+
return renderWithGql(gqlVal, true)
533+
},
534+
})
535+
536+
// Open Selector Playground first
537+
cy.findByTestId('playground-activator').click()
538+
539+
cy.then(() => {
540+
expect(selectorPlaygroundStore.show).to.be.true
541+
})
542+
543+
// Now activate Studio
544+
studioStore.setActive(true)
545+
546+
// Verify recording is disabled because SelectorPlayground is open
547+
cy.then(() => {
548+
expect(studioStore.isActive).to.be.true
549+
expect(studioStore.canRecord).to.be.false
550+
})
551+
})
552+
553+
it('disables recording when tests are running', () => {
554+
const studioStore = useStudioStore()
555+
const autStore = useAutStore()
556+
557+
studioStore.setActive(true)
558+
559+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
560+
render: (gqlVal) => {
561+
return renderWithGql(gqlVal, true)
562+
},
563+
})
564+
565+
// Verify recording is enabled initially
566+
cy.then(() => {
567+
expect(studioStore.canRecord).to.be.true
568+
})
569+
570+
// Set tests to running
571+
cy.then(() => {
572+
autStore.setIsRunning(true)
573+
})
574+
575+
// Verify recording is disabled when tests are running
576+
cy.then(() => {
577+
expect(autStore.isRunning).to.be.true
578+
expect(studioStore.canRecord).to.be.false
579+
expect(studioStore._isRecordingDisabled).to.be.true
580+
})
581+
582+
// Set tests to not running
583+
cy.then(() => {
584+
autStore.setIsRunning(false)
585+
})
586+
587+
// Verify recording is re-enabled
588+
cy.then(() => {
589+
expect(autStore.isRunning).to.be.false
590+
expect(studioStore.canRecord).to.be.true
591+
expect(studioStore._isRecordingDisabled).to.be.false
592+
})
593+
})
594+
595+
it('disables recording when tests are loading', () => {
596+
const studioStore = useStudioStore()
597+
const autStore = useAutStore()
598+
599+
studioStore.setActive(true)
600+
601+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
602+
render: (gqlVal) => {
603+
return renderWithGql(gqlVal, true)
604+
},
605+
})
606+
607+
// Verify recording is enabled initially
608+
cy.then(() => {
609+
expect(studioStore.canRecord).to.be.true
610+
})
611+
612+
// Set tests to loading
613+
cy.then(() => {
614+
autStore.setIsLoading(true)
615+
})
616+
617+
// Verify recording is disabled when tests are loading
618+
cy.then(() => {
619+
expect(autStore.isLoading).to.be.true
620+
expect(studioStore.canRecord).to.be.false
621+
expect(studioStore._isRecordingDisabled).to.be.true
622+
})
623+
624+
// Set tests to not loading
625+
cy.then(() => {
626+
autStore.setIsLoading(false)
627+
})
628+
629+
// Verify recording is re-enabled
630+
cy.then(() => {
631+
expect(autStore.isLoading).to.be.false
632+
expect(studioStore.canRecord).to.be.true
633+
expect(studioStore._isRecordingDisabled).to.be.false
634+
})
635+
})
636+
637+
it('prevents event recording when tests are running', () => {
638+
const studioStore = useStudioStore()
639+
const autStore = useAutStore()
640+
641+
studioStore.setActive(true)
642+
643+
cy.mountFragment(SpecRunnerHeaderFragmentDoc, {
644+
render: (gqlVal) => {
645+
return renderWithGql(gqlVal, true)
646+
},
647+
})
648+
649+
// Set tests to running
650+
cy.then(() => {
651+
autStore.setIsRunning(true)
652+
})
653+
654+
// Create a mock event and element
655+
cy.then(() => {
656+
const mockEvent = { type: 'click', isTrusted: true } as any
657+
const mock$el = {
658+
prop: (prop: string) => {
659+
if (prop === 'tagName') {
660+
return 'BUTTON'
661+
}
662+
663+
return undefined
664+
},
665+
} as any
666+
667+
// _shouldRecordEvent should return false when tests are running
668+
expect(studioStore._shouldRecordEvent(mockEvent, mock$el)).to.be.false
669+
})
670+
671+
// Set tests to not running
672+
cy.then(() => {
673+
autStore.setIsRunning(false)
674+
})
675+
676+
// Now _shouldRecordEvent should return true (assuming other conditions are met)
677+
cy.then(() => {
678+
const mockEvent = { type: 'click', isTrusted: true } as any
679+
const mock$el = {
680+
prop: (prop: string) => {
681+
if (prop === 'tagName') {
682+
return 'BUTTON'
683+
}
684+
685+
return undefined
686+
},
687+
} as any
688+
689+
expect(studioStore._shouldRecordEvent(mockEvent, mock$el)).to.be.true
690+
})
691+
})
692+
})
414693
})

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { getEventManager } from '../runner'
55
import type { StudioSavePayload } from '../runner/event-manager-types'
66
import { closeStudioAssertionsMenu, openStudioAssertionsMenu } from '../runner/studio/mounter'
77
import { useAutStore } from './aut-store'
8+
import { useSelectorPlaygroundStore } from './selector-playground-store'
89
import type { PossibleAssertions, AssertionArgs } from '../runner/studio/types'
910

1011
function getCypress () {
@@ -662,6 +663,10 @@ export const useStudioStore = defineStore('studioRecorder', {
662663
},
663664

664665
_shouldRecordEvent (event, $el) {
666+
if (this._isRecordingDisabled) {
667+
return false
668+
}
669+
665670
const tagName = $el.prop('tagName')
666671

667672
// only want to record keystrokes within input elements
@@ -957,5 +962,17 @@ export const useStudioStore = defineStore('studioRecorder', {
957962
state: 'failed',
958963
}
959964
},
965+
966+
_isRecordingDisabled () {
967+
const selectorPlaygroundStore = useSelectorPlaygroundStore()
968+
const autStore = useAutStore()
969+
970+
// Recording is disabled when Selector Playground is open or tests are running
971+
return selectorPlaygroundStore.show || autStore.isRunning || autStore.isLoading
972+
},
973+
974+
canRecord () {
975+
return !this._isRecordingDisabled
976+
},
960977
},
961978
})

0 commit comments

Comments
 (0)