From 7e4e0896a72483701fd6b90ff4c100f06f4b4f57 Mon Sep 17 00:00:00 2001 From: astone123 Date: Tue, 10 Jun 2025 09:02:46 -0400 Subject: [PATCH 1/2] internal: (studio) do not record events if cloud studio is enabled --- .../app/cypress/e2e/studio/studio-cloud.cy.ts | 31 +++++++++++++++++++ .../app/src/runner/SpecRunnerOpenMode.vue | 2 ++ packages/app/src/store/studio-store.ts | 15 +++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/app/cypress/e2e/studio/studio-cloud.cy.ts b/packages/app/cypress/e2e/studio/studio-cloud.cy.ts index 5018976290cf..d75a7651a56a 100644 --- a/packages/app/cypress/e2e/studio/studio-cloud.cy.ts +++ b/packages/app/cypress/e2e/studio/studio-cloud.cy.ts @@ -227,4 +227,35 @@ describe('studio functionality', () => { // verify studio is still open cy.findByTestId('studio-panel').should('be.visible') }) + + it('does not record studio commands when cloud studio is enabled', () => { + launchStudio({ enableCloudStudio: true }) + + cy.findByTestId('studio-panel').should('be.visible') + + // Attempt to perform actions that would normally be recorded in regular studio + // but should NOT be recorded in when cloud studio is enabled because event listeners are not attached + cy.getAutIframe().within(() => { + cy.get('p').contains('Count is 0') + + // Try to click the increment button - this should NOT be recorded + // because cloud studio event listeners should not be attached + cy.get('#increment').realClick().then(() => { + cy.get('p').contains('Count is 1') + }) + }) + + // Verify that no legacy studio commands were recorded + cy.get('.command-is-studio').should('not.exist') + + // Verify that the actual DOM interactions still work (button was clicked, counter incremented) + // but they just weren't recorded by the legacy studio event listeners + cy.getAutIframe().within(() => { + cy.get('p').should('contain', 'Count is 1') + }) + + cy.findByTestId('studio-panel').should('be.visible') + + cy.get('[data-cy="studio-toolbar"]').should('not.exist') + }) }) diff --git a/packages/app/src/runner/SpecRunnerOpenMode.vue b/packages/app/src/runner/SpecRunnerOpenMode.vue index b7a6a5aaf31a..2ae8383bfa69 100644 --- a/packages/app/src/runner/SpecRunnerOpenMode.vue +++ b/packages/app/src/runner/SpecRunnerOpenMode.vue @@ -269,6 +269,8 @@ useSubscription({ query: StudioStatus_ChangeDocument }, (_, data) => { }) const cloudStudioRequested = computed(() => { + studioStore.setCloudStudioRequested(props.gql.cloudStudioRequested || false) + return props.gql.cloudStudioRequested }) diff --git a/packages/app/src/store/studio-store.ts b/packages/app/src/store/studio-store.ts index d6a85b0b2491..eb1cbf505538 100644 --- a/packages/app/src/store/studio-store.ts +++ b/packages/app/src/store/studio-store.ts @@ -122,6 +122,7 @@ interface StudioRecorderState { canAccessStudioAI: boolean showUrlPrompt: boolean + cloudStudioRequested: boolean } export const useStudioStore = defineStore('studioRecorder', { @@ -138,10 +139,15 @@ export const useStudioStore = defineStore('studioRecorder', { _currentId: 1, canAccessStudioAI: false, showUrlPrompt: true, + cloudStudioRequested: false, } }, actions: { + setCloudStudioRequested (cloudStudioRequested: boolean) { + this.cloudStudioRequested = cloudStudioRequested + }, + setShowUrlPrompt (shouldShowUrlPrompt: boolean) { this.showUrlPrompt = shouldShowUrlPrompt }, @@ -498,6 +504,11 @@ export const useStudioStore = defineStore('studioRecorder', { this._body = body + // if we're in cloud studio, we shouldn't attach our own listeners - cloud studio will handle it + if (this.cloudStudioRequested) { + return + } + for (const event of eventTypes) { this._body.addEventListener(event, this._recordEvent, { capture: true, @@ -853,7 +864,7 @@ export const useStudioStore = defineStore('studioRecorder', { return $el.hasClass('__cypress-studio-assertions-menu') }, - _openAssertionsMenu (event) { + _openAssertionsMenu (event, addAssertion?: ($el: HTMLElement | JQuery, ...args: AssertionArgs) => void) { if (!this._body) { throw Error('this._body was not defined') } @@ -874,7 +885,7 @@ export const useStudioStore = defineStore('studioRecorder', { $body: window.UnifiedRunner.CypressJQuery(this._body), props: { possibleAssertions: this._generatePossibleAssertions($el), - addAssertion: this._addAssertion, + addAssertion: addAssertion || this._addAssertion, closeMenu: this._closeAssertionsMenu, }, }) From ec8c3ef67e11385a9c178af75d9dfd7d9de4bbd7 Mon Sep 17 00:00:00 2001 From: astone123 Date: Wed, 11 Jun 2025 12:55:42 -0400 Subject: [PATCH 2/2] add generatePossibleAssertions as arg --- packages/app/src/store/studio-store.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/src/store/studio-store.ts b/packages/app/src/store/studio-store.ts index eb1cbf505538..a8304f9b2f54 100644 --- a/packages/app/src/store/studio-store.ts +++ b/packages/app/src/store/studio-store.ts @@ -864,7 +864,7 @@ export const useStudioStore = defineStore('studioRecorder', { return $el.hasClass('__cypress-studio-assertions-menu') }, - _openAssertionsMenu (event, addAssertion?: ($el: HTMLElement | JQuery, ...args: AssertionArgs) => void) { + _openAssertionsMenu (event, addAssertion?: ($el: HTMLElement | JQuery, ...args: AssertionArgs) => void, generatePossibleAssertions?: ($el: JQuery) => PossibleAssertions) { if (!this._body) { throw Error('this._body was not defined') } @@ -884,7 +884,7 @@ export const useStudioStore = defineStore('studioRecorder', { $el, $body: window.UnifiedRunner.CypressJQuery(this._body), props: { - possibleAssertions: this._generatePossibleAssertions($el), + possibleAssertions: generatePossibleAssertions ? generatePossibleAssertions($el) : this._generatePossibleAssertions($el), addAssertion: addAssertion || this._addAssertion, closeMenu: this._closeAssertionsMenu, },