From c23713ae5b6e41e9d09f03c0296dc0c971a931a9 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 31 Oct 2025 12:01:18 -0400 Subject: [PATCH 1/3] chore: Clean up selector playground code --- cli/types/cypress.d.ts | 2 +- .../cypress/component/support/ctSupport.ts | 1 - packages/app/src/pages/Specs/Runner.vue | 2 - .../runner/SpecRunnerHeaderOpenMode.cy.tsx | 66 +---- .../src/runner/SpecRunnerHeaderOpenMode.vue | 30 +-- packages/app/src/runner/aut-iframe.ts | 239 +---------------- packages/app/src/runner/event-manager.ts | 4 - packages/app/src/runner/index.ts | 1 - .../selector-playground/Highlight.ce.vue | 81 ------ .../selector-playground/HighlightApp.ce.vue | 17 -- .../SelectorPlayground.cy.tsx | 192 -------------- .../SelectorPlayground.vue | 242 ------------------ .../SelectorPlaygroundSelectMethod.vue | 29 --- .../SelectorPlaygroundTooltip.vue | 53 ---- .../selector-playground/highlight-mounter.ts | 19 -- packages/app/src/runner/unifiedRunner.ts | 12 +- packages/app/src/runner/utils.ts | 21 -- packages/app/src/store/index.ts | 2 - .../src/store/selector-playground-store.ts | 107 -------- 19 files changed, 9 insertions(+), 1111 deletions(-) delete mode 100644 packages/app/src/runner/selector-playground/Highlight.ce.vue delete mode 100644 packages/app/src/runner/selector-playground/HighlightApp.ce.vue delete mode 100644 packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx delete mode 100644 packages/app/src/runner/selector-playground/SelectorPlayground.vue delete mode 100644 packages/app/src/runner/selector-playground/SelectorPlaygroundSelectMethod.vue delete mode 100644 packages/app/src/runner/selector-playground/SelectorPlaygroundTooltip.vue delete mode 100644 packages/app/src/runner/selector-playground/highlight-mounter.ts delete mode 100644 packages/app/src/store/selector-playground-store.ts diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 7f049a8dc3f..bcd713655de 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -713,7 +713,7 @@ declare namespace Cypress { /** * Element selector logic used for generating selectors for elements - * in the Selector Playground and Cypress Studio. + * in the Cypress Studio and cy.prompt(). * @see https://on.cypress.io/element-selector-api */ ElementSelector: { diff --git a/packages/app/cypress/component/support/ctSupport.ts b/packages/app/cypress/component/support/ctSupport.ts index a93f07b717a..077666f78d4 100644 --- a/packages/app/cypress/component/support/ctSupport.ts +++ b/packages/app/cypress/component/support/ctSupport.ts @@ -32,7 +32,6 @@ export const createEventManager = () => { } const mockDom = { - addOrUpdateSelectorPlaygroundHighlight: () => {}, scrollIntoView: () => {}, getElements: () => {}, } diff --git a/packages/app/src/pages/Specs/Runner.vue b/packages/app/src/pages/Specs/Runner.vue index 5248485cb08..615f374c3b1 100644 --- a/packages/app/src/pages/Specs/Runner.vue +++ b/packages/app/src/pages/Specs/Runner.vue @@ -13,8 +13,6 @@ { cy.findByTestId('viewport-size').should('be.visible').contains('500x500') }) - describe('selector playground button', () => { - it('is enabled by default', () => { - cy.mountFragment(SpecRunnerHeaderFragmentDoc, { - render: (gqlVal) => { - return renderWithGql(gqlVal) - }, - }) - - cy.get('[data-cy="playground-activator"]').should('not.be.disabled') - }) - - it('is disabled when isRunning is true', () => { - const autStore = useAutStore() - - autStore.setIsRunning(true) - - cy.mountFragment(SpecRunnerHeaderFragmentDoc, { - render: (gqlVal) => { - return renderWithGql(gqlVal) - }, - }) - - cy.get('[data-cy="playground-activator"]').should('be.disabled') - }) - - it('is disabled when isLoading is true', () => { - const autStore = useAutStore() - - autStore.setIsLoading(true) - - cy.mountFragment(SpecRunnerHeaderFragmentDoc, { - render: (gqlVal) => { - return renderWithGql(gqlVal) - }, - }) - - cy.get('[data-cy="playground-activator"]').should('be.disabled') - }) - - it('is hidden when studio beta is available', () => { - cy.mountFragment(SpecRunnerHeaderFragmentDoc, { - render: (gqlVal) => { - return renderWithGql(gqlVal, true, true) - }, - }) - - cy.get('[data-cy="playground-activator"]').should('not.exist') - }) - - it('opens and closes selector playground', () => { - cy.mountFragment(SpecRunnerHeaderFragmentDoc, { - render: (gqlVal) => { - return renderWithGql(gqlVal) - }, - }) - - cy.findByTestId('playground-activator').click() - cy.get('#selector-playground').should('be.visible') - - cy.findByTestId('playground-activator').click() - cy.get('#selector-playground').should('not.exist') - }) - }) + // SelectorPlayground has been removed - all related tests removed describe('url input', () => { it('shows url if currentTestingType is e2e', () => { @@ -239,7 +177,7 @@ describe('SpecRunnerHeaderOpenMode', { viewportHeight: 500 }, () => { }, }) - cy.findByTestId('playground-activator').should('be.visible') + // SelectorPlayground button has been removed cy.findByTestId('aut-url-input').should('have.prop', 'readOnly', true) cy.findByTestId('aut-url-input').should('have.prop', 'placeholder', 'URL navigation disabled in component testing') cy.findByTestId('viewport-size').should('be.visible').contains('500x500') diff --git a/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue b/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue index d634d7b8eea..4bd59237f9b 100644 --- a/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue +++ b/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue @@ -4,18 +4,7 @@ ref="autHeaderEl" class="h-full bg-gray-1100 border-l-[1px] border-gray-900 min-h-[64px] text-[14px]" > -
- +
- import { computed, ref, watchEffect } from 'vue' import { useRoute } from 'vue-router' -import { useAutStore, useSpecStore, useSelectorPlaygroundStore } from '../store' +import { useAutStore, useSpecStore } from '../store' import { useAutHeader } from './useAutHeader' import { gql } from '@urql/vue' import { useI18n } from 'vue-i18n' import type { SpecRunnerHeaderFragment } from '../generated/graphql' import type { EventManager } from './event-manager' import type { AutIframe } from './aut-iframe' -import { togglePlayground as _togglePlayground } from './utils' import Tag from '@cypress-design/vue-tag' -import SelectorPlayground from './selector-playground/SelectorPlayground.vue' import ExternalLink from '@packages/frontend-shared/src/gql-components/ExternalLink.vue' import Alert from '@packages/frontend-shared/src/components/Alert.vue' @@ -174,8 +156,6 @@ watchEffect(() => { showAlert.value = route.params.shouldShowTroubleRenderingAlert === 'true' }) -const autIframe = props.getAutIframe() - const displayScale = computed(() => { return autStore.scale < 1 ? `${Math.round(autStore.scale * 100) }%` : 0 }) @@ -184,17 +164,11 @@ const autUrl = computed(() => { return autStore.url }) -const selectorPlaygroundStore = useSelectorPlaygroundStore() - -const togglePlayground = () => _togglePlayground(autIframe) - // Have to spread gql props since binding it to v-model causes error when testing const selectedBrowser = ref({ ...props.gql.activeBrowser }) const activeSpecPath = specStore.activeSpec?.absolute -const isDisabled = computed(() => autStore.isRunning || autStore.isLoading) - const urlReadOnly = computed(() => { return !studioStore.needsUrl || props.gql.currentTestingType === 'component' }) diff --git a/packages/app/src/runner/aut-iframe.ts b/packages/app/src/runner/aut-iframe.ts index af8f24b3d9a..840b7cf7d50 100644 --- a/packages/app/src/runner/aut-iframe.ts +++ b/packages/app/src/runner/aut-iframe.ts @@ -1,32 +1,20 @@ -import { useSelectorPlaygroundStore } from '../store/selector-playground-store' import { blankContents } from '../components/Blank' -import { logger } from './logger' import _ from 'lodash' -/* eslint-disable no-duplicate-imports */ -import type { DebouncedFunc } from 'lodash' import { useStudioStore } from '../store/studio-store' import { getElementDimensions, setOffset } from './dimensions' -import { getOrCreateHelperDom, getSelectorHighlightStyles, getZIndex, INT32_MAX } from './dom' -import highlightMounter from './selector-playground/highlight-mounter' -import Highlight from './selector-playground/Highlight.ce.vue' +import { getZIndex, INT32_MAX } from './dom' // JQuery bundled w/ Cypress type $CypressJQuery = any -const sizzleRe = /sizzle/i -const jQueryRe = /jquery/i - export class AutIframe { - debouncedToggleSelectorPlayground: DebouncedFunc<(isEnabled: any) => void> $iframe?: JQuery - _highlightedEl?: Element constructor ( private projectName: string, private eventManager: any, private $: $CypressJQuery, ) { - this.debouncedToggleSelectorPlayground = _.debounce(this.toggleSelectorPlayground, 300) } create (): JQuery { @@ -181,10 +169,6 @@ export class AutIframe { this._body()?.remove() this._insertBodyStyles(body.get(), bodyStyles) $html?.append(body.get()) - - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - this.debouncedToggleSelectorPlayground(selectorPlaygroundStore.isEnabled) } // note htmlAttrs is actually `NamedNodeMap`: https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap @@ -331,166 +315,6 @@ export class AutIframe { this._contents() && this._contents()?.find('.__cypress-highlight').remove() } - toggleSelectorPlayground = (isEnabled) => { - const $body = this._body() - - if (!$body) return - - if (isEnabled) { - $body.on('mouseenter', this._resetShowHighlight) - $body.on('mousemove', this._onSelectorMouseMove) - $body.on('mouseleave', this._clearHighlight) - } else { - $body.off('mouseenter', this._resetShowHighlight) - $body.off('mousemove', this._onSelectorMouseMove) - $body.off('mouseleave', this._clearHighlight) - if (this._highlightedEl) { - this._clearHighlight() - } - } - } - - _resetShowHighlight = () => { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - selectorPlaygroundStore.setShowingHighlight(false) - } - - _onSelectorMouseMove = (e: JQuery.MouseMoveEvent) => { - const $body = this._body() - - if (!$body) return - - let el = e.target - let $el = this.$(el) - - const $ancestorHighlight = $el.closest('.__cypress-selector-playground') - - if ($ancestorHighlight.length) { - $el = $ancestorHighlight - } - - if ($ancestorHighlight.length || $el.hasClass('__cypress-selector-playground')) { - const $highlight = $el - - $highlight.css('display', 'none') - el = this._document().elementFromPoint(e.clientX, e.clientY) - $el = this.$(el) - $highlight.css('display', 'block') - } - - if (this._highlightedEl === el) return - - this._highlightedEl = el - - const Cypress = this.eventManager.getCypress() - - const selector = Cypress.ElementSelector._getSelector($el) - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - this._addOrUpdateSelectorPlaygroundHighlight({ - $el, - $body, - selector, - showTooltip: true, - onClick: () => { - selectorPlaygroundStore.setNumElements(1) - selectorPlaygroundStore.resetMethod() - selectorPlaygroundStore.setSelector(selector) - selectorPlaygroundStore.setValidity(!!el) - }, - }) - } - - _clearHighlight = () => { - const $body = this._body() - - if (!$body) return - - this._addOrUpdateSelectorPlaygroundHighlight({ - $el: null, - $body, - }) - - if (this._highlightedEl) { - this._highlightedEl = undefined - } - } - - toggleSelectorHighlight (isShowingHighlight: boolean) { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - if (!isShowingHighlight) { - this._clearHighlight() - - return - } - - const Cypress = this.eventManager.getCypress() - - const $el = this.getElements(Cypress.dom) - - selectorPlaygroundStore.setValidity(!!$el) - - if ($el) { - selectorPlaygroundStore.setNumElements($el.length) - - if ($el.length) { - this._scrollIntoView(this._window(), $el[0]) - } - } - - this._addOrUpdateSelectorPlaygroundHighlight({ - $el: $el && $el.length ? $el : null, - $body: this._body(), - selector: selectorPlaygroundStore.selector, - showTooltip: false, - }) - } - - getElements (cypressDom) { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - const $contents = this._contents() - - if (!$contents || !selectorPlaygroundStore.selector) return - - return this._getElementsForSelector({ - method: selectorPlaygroundStore.method, - selector: selectorPlaygroundStore.selector, - cypressDom, - $root: $contents, - }) - } - - printSelectorElementsToConsole () { - logger.clearLog() - - const Cypress = this.eventManager.getCypress() - - const $el = this.getElements(Cypress.dom) - - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - if (!$el) { - return logger.logFormatted({ - name: selectorPlaygroundStore.command, - type: 'command', - props: { - Yielded: 'Nothing', - }, - }) - } - - logger.logFormatted({ - name: selectorPlaygroundStore.command, - type: 'command', - props: { - Elements: $el.length, - Yielded: Cypress.dom.getElements($el), - }, - }) - } - startStudio () { const studioStore = useStudioStore() @@ -514,26 +338,6 @@ export class AutIframe { ) } - private _getElementsForSelector ({ $root, selector, method, cypressDom }) { - let $el: JQuery | null = null - - try { - if (method === 'contains') { - $el = $root.find(cypressDom.getContainsSelector(selector)) as JQuery - if ($el.length) { - $el = cypressDom.getFirstDeepestElement($el) - } - } else { - $el = $root.find(selector) - } - } catch (err) { - // if not a sizzle or jQuery error, ignore it and let $el be null - if (!(sizzleRe.test(err.stack) || jQueryRe.test(err.stack))) throw err - } - - return $el - } - private _addHitBoxLayer (coords: { x: number, y: number }, body: HTMLBodyElement) { const height = 10 const width = 10 @@ -623,7 +427,7 @@ export class AutIframe { } private _addElementBoxModelLayers ($el, $body) { - $body = $body || $('body') + $body = $body || this.$('body') const el = $el.get(0) const body = $body.get(0) @@ -739,43 +543,4 @@ export class AutIframe { private _getDimensionsFor (dimensions, attr, dimension) { return dimensions[`${dimension}With${attr}`] } - - private listeners: any[] = [] - - private _addOrUpdateSelectorPlaygroundHighlight ({ $el, $body, selector, showTooltip, onClick }: any) { - const { container, vueContainer } = getOrCreateHelperDom({ - body: $body?.get(0) || document.body, - className: '__cypress-selector-playground', - css: Highlight.styles[0], - }) - - const removeContainerClickListeners = () => { - this.listeners.forEach((listener) => { - vueContainer.removeEventListener('click', listener) - }) - - this.listeners = [] - } - - if (!$el) { - removeContainerClickListeners() - container.remove() - - return - } - - const elements = $el.get() - const styles = getSelectorHighlightStyles(elements) - - if (elements.length === 1) { - removeContainerClickListeners() - - if (onClick) { - vueContainer.addEventListener('click', onClick) - this.listeners.push(onClick) - } - } - - highlightMounter.mount(vueContainer, selector, styles) - } } diff --git a/packages/app/src/runner/event-manager.ts b/packages/app/src/runner/event-manager.ts index 494a754a378..73d9245a35b 100644 --- a/packages/app/src/runner/event-manager.ts +++ b/packages/app/src/runner/event-manager.ts @@ -57,7 +57,6 @@ export class EventManager { reporterBus: EventEmitter = new EventEmitter() localBus: EventEmitter = new EventEmitter() Cypress?: $Cypress - selectorPlaygroundModel: any cypressInCypressMochaEvents: CypressInCypressMochaEvent[] = [] // Used for testing the experimentalSingleTabRunMode experiment. Ensures AUT is correctly destroyed between specs. ws: SocketShape @@ -71,11 +70,8 @@ export class EventManager { private $CypressDriver: any, // import * as MobX private Mobx: typeof MobX, - // selectorPlaygroundModel singleton - selectorPlaygroundModel: any, ws: SocketShape, ) { - this.selectorPlaygroundModel = selectorPlaygroundModel this.ws = ws this.specStore = useSpecStore() this.studioStore = useStudioStore() diff --git a/packages/app/src/runner/index.ts b/packages/app/src/runner/index.ts index 0692c278b7b..f3d6a397702 100644 --- a/packages/app/src/runner/index.ts +++ b/packages/app/src/runner/index.ts @@ -52,7 +52,6 @@ export function initializeEventManager (UnifiedRunner: any) { _eventManager = new EventManager( UnifiedRunner.CypressDriver, UnifiedRunner.MobX, - UnifiedRunner.selectorPlaygroundModel, window.ws, ) } diff --git a/packages/app/src/runner/selector-playground/Highlight.ce.vue b/packages/app/src/runner/selector-playground/Highlight.ce.vue deleted file mode 100644 index 914f3d46028..00000000000 --- a/packages/app/src/runner/selector-playground/Highlight.ce.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - diff --git a/packages/app/src/runner/selector-playground/HighlightApp.ce.vue b/packages/app/src/runner/selector-playground/HighlightApp.ce.vue deleted file mode 100644 index 8db516ba9a0..00000000000 --- a/packages/app/src/runner/selector-playground/HighlightApp.ce.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx b/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx deleted file mode 100644 index 206a1b2acef..00000000000 --- a/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { createEventManager, createTestAutIframe } from '../../../cypress/component/support/ctSupport' -import { useSelectorPlaygroundStore } from '../../store/selector-playground-store' -import { Clipboard_CopyToClipboardDocument } from '../../generated/graphql-test' -import SelectorPlayground from './SelectorPlayground.vue' -import { logger } from '../logger' - -describe('SelectorPlayground', () => { - const mountSelectorPlayground = ( - eventManager = createEventManager(), - autIframe = createTestAutIframe(), - ) => { - return { - autIframe, - element: cy.mount(() => ( -
- autIframe} - /> -
- )), - } - } - - it('populates cy.get by default with a selector of body', () => { - const { autIframe } = mountSelectorPlayground() - - cy.spy(autIframe, 'toggleSelectorHighlight') - cy.get('[data-cy="selected-playground-method"]').should('contain', 'cy.get') - cy.get('[data-cy="playground-selector"]').should('have.value', 'body') - }) - - it('toggles enabled', () => { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - expect(selectorPlaygroundStore.isEnabled).to.be.false - - const { autIframe } = mountSelectorPlayground() - - cy.spy(autIframe, 'toggleSelectorPlayground') - - cy.get('[data-cy="playground-toggle"]').click().then(() => { - expect(selectorPlaygroundStore.isEnabled).to.be.true - expect(autIframe.toggleSelectorPlayground).to.have.been.called - }) - }) - - it('changes method from cy.get to cy.contains', () => { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - const { autIframe } = mountSelectorPlayground() - - cy.spy(autIframe, 'toggleSelectorHighlight') - expect(selectorPlaygroundStore.method).to.eq('get') - - cy.get('[aria-label="Selector methods"]').click() - cy.findByRole('menuitem', { name: 'cy.contains' }).click().then(() => { - expect(selectorPlaygroundStore.method).to.eq('contains') - expect(autIframe.toggleSelectorHighlight).to.have.been.called - }) - - cy.get('[data-cy="selected-playground-method"]').should('contain', 'cy.contains') - }) - - it('shows query and number of found elements', () => { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - selectorPlaygroundStore.setNumElements(0) - - mountSelectorPlayground() - cy.then(() => selectorPlaygroundStore.setValidity(true)) - - cy.get('[data-cy="playground-num-elements"]').contains('No matches') - - cy.then(() => selectorPlaygroundStore.setNumElements(1)) - - cy.get('[data-cy="playground-num-elements"]').contains('1 match') - - cy.then(() => selectorPlaygroundStore.setNumElements(10)) - - cy.get('[data-cy="playground-num-elements"]').contains('10 matches') - - cy.then(() => selectorPlaygroundStore.setValidity(false)) - - cy.get('[data-cy="playground-num-elements"]').contains('Invalid') - }) - - it('focuses playground selector', () => { - mountSelectorPlayground() - cy.get('[data-cy="playground-selector"]').as('copy').clear().type('.foo-bar') - - cy.get('@copy').click() - cy.get('@copy').should('be.focused') - }) - - it('copies selector text', () => { - const copyStub = cy.stub() - - cy.stubMutationResolver(Clipboard_CopyToClipboardDocument, (defineResult, { text }) => { - copyStub(text) - - return defineResult({ - copyTextToClipboard: true, - }) - }) - - const { autIframe } = mountSelectorPlayground() - - cy.spy(autIframe, 'toggleSelectorHighlight') - - cy.get('[data-cy="playground-copy"]').trigger('mouseenter') - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Copy to clipboard') - - cy.get('[data-cy="playground-copy"]').click() - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Copied!') - - cy.wrap(copyStub).should('have.been.calledWith', 'cy.get(\'body\')') - }) - - it('prints elements when selected elements found', () => { - const { autIframe } = mountSelectorPlayground() - const fakeJQueryElements = Array(2) - - // It is necessary to mimic JQuery behavior. - // @ts-ignore - fakeJQueryElements.get = () => fakeJQueryElements - - cy.spy(logger, 'logFormatted') - cy.stub(autIframe, 'getElements').callsFake((() => fakeJQueryElements)) - - cy.get('[data-cy="playground-selector"]').clear().type('.foo-bar') - - cy.get('[data-cy="playground-print"]').trigger('mouseenter') - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Print to console') - - cy.get('[data-cy="playground-print"]').click() - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Printed!') - - cy.then(() => { - expect(logger.logFormatted).to.have.been.calledWith({ - name: `cy.get('.foo-bar')`, - type: 'command', - props: { - Elements: 2, - Yielded: undefined, // stubbed dom does not actually return anything - }, - }) - }) - }) - - it('prints nothing to console when no selected elements found', () => { - mountSelectorPlayground() - cy.spy(logger, 'logFormatted') - cy.get('[data-cy="playground-selector"]').clear().type('.foo-bar') - - cy.get('[data-cy="playground-print"]').as('print') - cy.get('@print').click().then(() => { - expect(logger.logFormatted).to.have.been.calledWith({ - name: `cy.get('.foo-bar')`, - type: 'command', - props: { - Yielded: 'Nothing', - }, - }) - }) - }) - - // TODO: flaky test, but we'll be removing SelectorPlayground in the near future - it.skip('shows copy tooltip when button is focused', () => { - mountSelectorPlayground() - - cy.get('[data-cy="playground-copy"]').focus() - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Copy to clipboard') - cy.get('[data-cy="playground-copy"]').trigger('mouseleave') - cy.get('[data-cy="selector-playground-tooltip"]').should('not.exist') - }) - - it('shows print tooltip when button is focused', () => { - mountSelectorPlayground() - - cy.get('[data-cy="playground-print"]').focus() - cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Print to console') - cy.get('[data-cy="playground-print"]').trigger('mouseleave') - cy.get('[data-cy="selector-playground-tooltip"]').should('not.exist') - }) - - it('ensures input autocomplete is disabled', () => { - mountSelectorPlayground() - - cy.get('[data-cy="playground-selector"]').should('have.attr', 'autocomplete', 'off') - }) -}) diff --git a/packages/app/src/runner/selector-playground/SelectorPlayground.vue b/packages/app/src/runner/selector-playground/SelectorPlayground.vue deleted file mode 100644 index 20c8d590f0d..00000000000 --- a/packages/app/src/runner/selector-playground/SelectorPlayground.vue +++ /dev/null @@ -1,242 +0,0 @@ - - - - - diff --git a/packages/app/src/runner/selector-playground/SelectorPlaygroundSelectMethod.vue b/packages/app/src/runner/selector-playground/SelectorPlaygroundSelectMethod.vue deleted file mode 100644 index b30a24d6795..00000000000 --- a/packages/app/src/runner/selector-playground/SelectorPlaygroundSelectMethod.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - - - diff --git a/packages/app/src/runner/selector-playground/SelectorPlaygroundTooltip.vue b/packages/app/src/runner/selector-playground/SelectorPlaygroundTooltip.vue deleted file mode 100644 index 0fb10ce9ac4..00000000000 --- a/packages/app/src/runner/selector-playground/SelectorPlaygroundTooltip.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/packages/app/src/runner/selector-playground/highlight-mounter.ts b/packages/app/src/runner/selector-playground/highlight-mounter.ts deleted file mode 100644 index 1d229e11b3a..00000000000 --- a/packages/app/src/runner/selector-playground/highlight-mounter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { App, createApp } from 'vue' -import HighlightApp from './HighlightApp.ce.vue' - -let app: App | null = null - -export default { - mount (container: Element, selector: string, styles: any[]) { - if (app) { - app.unmount() - } - - app = createApp(HighlightApp, { - selector, - styles, - }) - - app.mount(container) - }, -} diff --git a/packages/app/src/runner/unifiedRunner.ts b/packages/app/src/runner/unifiedRunner.ts index 8a583237b14..3d8413e5310 100644 --- a/packages/app/src/runner/unifiedRunner.ts +++ b/packages/app/src/runner/unifiedRunner.ts @@ -1,7 +1,6 @@ import { Ref, onMounted, ref, watch, watchEffect, onBeforeUnmount, readonly } from 'vue' -import { getAutIframeModel, UnifiedRunnerAPI } from '../runner' +import { UnifiedRunnerAPI } from '../runner' import { useSpecStore } from '../store' -import { useSelectorPlaygroundStore } from '../store/selector-playground-store' import { RUN_ALL_SPECS, RUN_ALL_SPECS_KEY, SpecFile } from '@packages/types/src' import { LocationQuery, useRoute } from 'vue-router' import { getPathForPlatform, posixify } from '../paths' @@ -35,7 +34,6 @@ export function useUnifiedRunner () { watchSpecs: (specs: Ref>) => { const specStore = useSpecStore() const route = useRoute() - const selectorPlaygroundStore = useSelectorPlaygroundStore() const testsForRunMutation = useMutation(TestsForRunDocument) watchEffect(async () => { @@ -77,13 +75,7 @@ export function useUnifiedRunner () { }) watch(() => getPathForPlatform(route.query.file as string), () => { - if (selectorPlaygroundStore.show) { - const autIframe = getAutIframeModel() - - autIframe.toggleSelectorPlayground(false) - selectorPlaygroundStore.setEnabled(false) - selectorPlaygroundStore.setShow(false) - } + // File changed - any cleanup can be done here }, { flush: 'post' }) }, } diff --git a/packages/app/src/runner/utils.ts b/packages/app/src/runner/utils.ts index d77df970fe7..993661edaa5 100644 --- a/packages/app/src/runner/utils.ts +++ b/packages/app/src/runner/utils.ts @@ -1,6 +1,3 @@ -import { useSelectorPlaygroundStore } from '../store/selector-playground-store' -import type { AutIframe } from './aut-iframe' - export const RUNNER_ID = 'unified-runner' export const REPORTER_ID = 'unified-reporter' @@ -26,21 +23,3 @@ export function empty (el: HTMLElement) { } } } - -export const togglePlayground = (autIframe: AutIframe) => { - const selectorPlaygroundStore = useSelectorPlaygroundStore() - - if (selectorPlaygroundStore.show) { - selectorPlaygroundStore.setShow(false) - autIframe.toggleSelectorPlayground(false) - selectorPlaygroundStore.setEnabled(false) - selectorPlaygroundStore.setShowingHighlight(false) - autIframe.toggleSelectorHighlight(false) - } else { - selectorPlaygroundStore.setShow(true) - autIframe.toggleSelectorPlayground(true) - selectorPlaygroundStore.setEnabled(true) - selectorPlaygroundStore.setShowingHighlight(true) - autIframe.toggleSelectorHighlight(true) - } -} diff --git a/packages/app/src/store/index.ts b/packages/app/src/store/index.ts index d9f7965000b..3d40c43e068 100644 --- a/packages/app/src/store/index.ts +++ b/packages/app/src/store/index.ts @@ -8,8 +8,6 @@ export * from './runner-ui-store' export * from './mobx-runner-store' -export * from './selector-playground-store' - export * from './screenshot-store' // Reusable installation function, used as an entry point for tests that diff --git a/packages/app/src/store/selector-playground-store.ts b/packages/app/src/store/selector-playground-store.ts deleted file mode 100644 index 3ca048329e5..00000000000 --- a/packages/app/src/store/selector-playground-store.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { defineStore } from 'pinia' - -type SelectorMethod = 'get' | 'contains' - -interface SelectorPlaygroundStore { - show: boolean - getSelector: string - containsSelector: string - isShowingHighlight: boolean - isOpen: boolean - isEnabled: boolean - isValid: boolean - numElements: number - method: SelectorMethod -} - -export const useSelectorPlaygroundStore = defineStore({ - id: 'selector-playground-store', - - state: (): SelectorPlaygroundStore => { - return { - show: false, - getSelector: 'body', - containsSelector: 'Hello, World', - isShowingHighlight: false, - isOpen: false, - isEnabled: false, - isValid: true, - numElements: 0, - method: 'get', - } - }, - - actions: { - setShow (show: boolean) { - this.show = show - }, - - toggleMethod () { - this.method = this.method === 'get' ? 'contains' : 'get' - }, - - setEnabled (isEnabled: boolean) { - this.isEnabled = isEnabled - - if (!this.isEnabled) { - this.isShowingHighlight = false - } - }, - - toggleOpen () { - this.setOpen(!this.isOpen) - }, - - setOpen (isOpen: boolean) { - this.isOpen = isOpen - - this.setEnabled(this.isOpen) - }, - - setSelector (selector: SelectorMethod) { - if (this.method === 'get') { - this.getSelector = selector - } else { - this.containsSelector = selector - } - }, - - setShowingHighlight (isShowingHighlight: boolean) { - this.isShowingHighlight = isShowingHighlight - }, - - setNumElements (numElements: number) { - this.numElements = numElements - }, - - setValidity (isValid: boolean) { - this.isValid = isValid - }, - - setMethod (method: SelectorMethod) { - this.method = method - }, - - resetMethod () { - this.method = 'get' - }, - }, - - getters: { - selector (state) { - return state.method === 'get' ? state.getSelector : state.containsSelector - }, - - infoHelp (state) { - if (!state.isValid) { - return 'Invalid selector' - } - - return state.numElements === 1 ? '1 matched element' : `${state.numElements} matched elements` - }, - - command (state): string { - return `cy.${state.method}('${this.selector}')` - }, - }, -}) From 9ff24f2f209f7a3056d5ff2946227a37e9fdaecd Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 31 Oct 2025 12:06:41 -0400 Subject: [PATCH 2/3] remove more tests and references --- cli/CHANGELOG.md | 2 +- packages/reporter/cypress/e2e/shortcuts.cy.ts | 1 - packages/reporter/src/main-runner.scss | 2 +- packages/reporter/src/main.scss | 2 +- packages/runner/src/header/header.scss | 277 ------------------ .../selector-playground/cypress.config.js | 5 - .../cypress/e2e/empty.cy.js | 0 .../cypress/e2e/index.html | 20 -- .../cypress/e2e/spec.cy.js | 3 - 9 files changed, 3 insertions(+), 309 deletions(-) delete mode 100644 system-tests/projects/selector-playground/cypress.config.js delete mode 100644 system-tests/projects/selector-playground/cypress/e2e/empty.cy.js delete mode 100644 system-tests/projects/selector-playground/cypress/e2e/index.html delete mode 100644 system-tests/projects/selector-playground/cypress/e2e/spec.cy.js diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index ff1b00e5b6b..651b0bbecff 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1735,7 +1735,7 @@ _Released 1/24/2023_ configured to exclude files with those extensions. Addresses [#24495](https://github.com/cypress-io/cypress/issues/24495). - Added support for the `data-qa` selector in the - [Selector Playground](guides/core-concepts/cypress-app#Selector-Playground) in + [Selector Playground](guides/core-concepts/cypress-app) in addition to `data-cy`, `data-test` and `data-testid`. Addresses [#25305](https://github.com/cypress-io/cypress/issues/25305). diff --git a/packages/reporter/cypress/e2e/shortcuts.cy.ts b/packages/reporter/cypress/e2e/shortcuts.cy.ts index a8796247d40..8e2e9487059 100755 --- a/packages/reporter/cypress/e2e/shortcuts.cy.ts +++ b/packages/reporter/cypress/e2e/shortcuts.cy.ts @@ -133,7 +133,6 @@ describe('shortcuts', function () { it('does not run shortcut if typed into an input', () => { cy.get('body') .then(($body) => { - // this realistically happens with the selector playground, but // need to add an input since this environment is isolated $body.append('') }) diff --git a/packages/reporter/src/main-runner.scss b/packages/reporter/src/main-runner.scss index dd8f97b305b..a041c26f582 100644 --- a/packages/reporter/src/main-runner.scss +++ b/packages/reporter/src/main-runner.scss @@ -9,6 +9,6 @@ @import 'lib/selfHealedBadge'; @import '@reach/dialog/styles.css'; // import all other scss files in src except if they are in lib -// or their file name is `selector-playground` or `main` +// or their file name is `main` // NOTE: no need to import scss files in their components @import '../../reporter/src/!(lib)*/**/!(main)*.scss'; diff --git a/packages/reporter/src/main.scss b/packages/reporter/src/main.scss index ddc28fafd7b..ffe87441315 100644 --- a/packages/reporter/src/main.scss +++ b/packages/reporter/src/main.scss @@ -15,6 +15,6 @@ @import 'lib/selfHealedBadge'; @import '@reach/dialog/styles.css'; // import all other scss files in src except if they are in lib -// or their file name is `selector-playground` or `main` +// or their file name is `main` // NOTA: no need to import scss files in their components @import '../../reporter/src/!(lib)*/**/!(main)*.scss'; diff --git a/packages/runner/src/header/header.scss b/packages/runner/src/header/header.scss index 2fc4cd0797d..8b1f1f75b68 100644 --- a/packages/runner/src/header/header.scss +++ b/packages/runner/src/header/header.scss @@ -19,10 +19,6 @@ padding-left: 0.4em; } - .selector-playground-toggle-tooltip-wrapper { - display: flex; - } - .header-button { background: none; border: none; @@ -62,25 +58,6 @@ } } - .display-selector-playground { - padding-left: 0; - - .selector-playground-toggle { - display: block; - } - } - - .showing-selector-playground { - .selector-playground { - display: flex; - } - - .selector-playground-toggle { - background-color: #e9e9e9; - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - } - } - .showing-studio { .studio { display: flex; @@ -98,248 +75,6 @@ color: #565554; } - .selector-playground { - &.invalid-selector, &.no-elements { - .selector-input { - input { - color: #E74C41; - - &:focus, &:active { - border: 1px solid lighten(#E74C41, 20%); - box-shadow: 0 0 0 0.1rem rgba(255,0,0,.25); - } - } - } - } - - &.no-elements, &.invalid-selector { - .num-elements { - background-color: #CC4239; - } - } - - .selector { - font-size: 1em; - align-items: center; - display: flex; - position: relative; - width: calc(100% - 115px); - } - - .selector-info { - color: #4971C6; - margin: 0 1.5em; - white-space: nowrap; - } - - .num-elements { - margin-right: 5px; - margin-left: 0; - font-size: 100%; - padding: 4px 6px; - } - - .selector, - .selector-input, - .info .spacer { - font-family: $font-mono; - } - - .wrap { - align-items: center; - // needs a background to hide the copy-to-clipboard backer input - background: #f8f8f8; - display: flex; - flex-grow: 2; - padding: 0 6px; - } - - .syntax-object { color: #e45649; } - .syntax-operator { color: #383a42; } - .syntax-method { color: #6478f2; } - .syntax-string { color: #50a160; } - - .selector-input { - flex-grow: 2; - - input { - border: 0; - color: #476fc9; - min-width: 5em; - outline: none; - padding: 6px 8px 6px 9px; - font-family: $font-mono; - border: 1px solid #ced4da; - font-size: 1em; - border-radius: 6px; - width: 100%; - - &:focus { - border: 1px solid #80bdff; - box-shadow: 0 0 0 0.1rem rgba(0,123,255,.25); - } - } - } - - .copy-backer { - font-size: 1px; - left: 6px; - position: absolute; - top: 6px; - z-index: -1; - } - - .method { - position: relative; - - button { - border: 0; - background-color: #f8f8f8; - color: #565554; - padding: 5px 0 4px; - font-family: $font-mono; - font-size: 1em; - - &:hover { - color: #111; - } - - &:focus, &:active { - outline: 0; - box-shadow: none; - } - } - - .syntax-method { - cursor: pointer; - border-bottom: dotted 1px #6478f2; - } - - .method-picker { - background: #f8f8f8; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - display: none; - font-size: 12px; - padding: 3px; - position: absolute; - top: 110%; - left: 7px; - border-radius: 6px; - border: 1px solid #ddd; - - div { - cursor: pointer; - margin-top: 2px; - padding: 3px 6px; - - &:first-child { - margin-top: 0; - } - - &:hover { - background: #e3e3e3; - } - } - } - - &.is-showing .method-picker { - display: block; - } - } - - .highlight-toggle { - background: #f8f8f8; - border: 0; - padding: 0; - margin-right: 5px; - color: #767574; - padding-left: 3px; - - &.active, &:active { - box-shadow: none; - color: #4971C6; - } - - &:focus { - outline: 0; - } - - .fa-stack { - font-size: 14px; - } - - .fa-square { - top: 0px; - left: 0px; - font-size: 22px; - } - - .fa-mouse-pointer { - left: 1.5px; - top: -1px; - font-size: 10px; - } - } - - button.copy-to-clipboard, button.print-to-console { - background: #fff; - border: 1px solid #ced4da; - color: #565554; - padding: 6px 8px; - font-size: 0.9em; - - &:disabled, &:disabled:hover, &:disabled:focus, &:disabled:active { - cursor: not-allowed; - outline: 0; - opacity: 0.65; - background-color: #fff; - color: #565554; - } - - &:hover, &:focus, &:active { - box-shadow: none; - color: #333; - outline: 0; - background-color: #f8f8f8; - } - } - - button.copy-to-clipboard { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - - button.print-to-console { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left: 0; - } - - .info { - display: block; - margin-left: 6px; - } - - .close { - background: none; - border: none; - color: #888; - padding: 4px 6px; - position: absolute; - top: 0; - right: 5px; - font-weight: bold; - - &:hover, - &:focus, - &:active { - color: #333; - outline: 0; - box-shadow: none; - } - } - } - .studio { font-family: $open-sans; font-size: 1em; @@ -653,17 +388,5 @@ .sel-url-wrap { width: 100%; } - - .selector-playground { - border-right: solid 1px #e3e3e3; - flex-grow: 2; - width: auto; - } - - .showing-selector-playground .menu { - border-bottom: none; - padding-left: 5px; - order: 3; - } } } diff --git a/system-tests/projects/selector-playground/cypress.config.js b/system-tests/projects/selector-playground/cypress.config.js deleted file mode 100644 index d12d96d7e3e..00000000000 --- a/system-tests/projects/selector-playground/cypress.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - e2e: { - supportFile: false, - }, -} diff --git a/system-tests/projects/selector-playground/cypress/e2e/empty.cy.js b/system-tests/projects/selector-playground/cypress/e2e/empty.cy.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/system-tests/projects/selector-playground/cypress/e2e/index.html b/system-tests/projects/selector-playground/cypress/e2e/index.html deleted file mode 100644 index b380b7ef0a0..00000000000 --- a/system-tests/projects/selector-playground/cypress/e2e/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - Hello Selector Playground - - -

Hello, Selector Playground!

-
- -

Some contents

- -

Para 1

-

Para 2

-

Para 3

-

Para 4

- - diff --git a/system-tests/projects/selector-playground/cypress/e2e/spec.cy.js b/system-tests/projects/selector-playground/cypress/e2e/spec.cy.js deleted file mode 100644 index 14398fef3b5..00000000000 --- a/system-tests/projects/selector-playground/cypress/e2e/spec.cy.js +++ /dev/null @@ -1,3 +0,0 @@ -it('visits a basic html page', () => { - cy.visit('cypress/e2e/index.html') -}) From b923efc93a1cc6aaf4778910c46b076caed79fbf Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 31 Oct 2025 12:09:54 -0400 Subject: [PATCH 3/3] Remove some more relevant portions of code --- packages/app/cypress/component/support/ctSupport.ts | 1 - .../app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts | 2 -- .../app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx | 3 --- .../app/src/runner/SpecRunnerHeaderRunMode.cy.tsx | 2 -- packages/frontend-shared/src/locales/en-US.json | 11 ----------- 5 files changed, 19 deletions(-) diff --git a/packages/app/cypress/component/support/ctSupport.ts b/packages/app/cypress/component/support/ctSupport.ts index 077666f78d4..db5fec4133d 100644 --- a/packages/app/cypress/component/support/ctSupport.ts +++ b/packages/app/cypress/component/support/ctSupport.ts @@ -26,7 +26,6 @@ export const createEventManager = () => { null, // packages/driver, not needed for CT tests // @ts-ignore null, // MobX, also not needed in Vue CT tests, - null, // selectorPlaygroundModel, StubWebsocket, ) } diff --git a/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts index 588246d7104..9847e59a7c0 100644 --- a/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts +++ b/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts @@ -12,7 +12,6 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => { cy.waitForSpecToFinish() cy.findByTestId('aut-url').should('be.visible') - cy.findByTestId('playground-activator').should('not.exist') cy.findByLabelText('Stats').within(() => { cy.get('.passed .num', { timeout: 10000 }).should('have.text', '1') @@ -41,7 +40,6 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => { cy.waitForSpecToFinish() cy.findByTestId('aut-url').contains('URL navigation disabled in component testing').should('be.visible') - cy.findByTestId('playground-activator').should('not.exist') cy.findByLabelText('Stats').within(() => { cy.get('.passed .num', { timeout: 10000 }).should('have.text', '1') diff --git a/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx b/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx index 3013cc628ef..cc2199c7270 100644 --- a/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx +++ b/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx @@ -39,8 +39,6 @@ describe('SpecRunnerHeaderOpenMode', { viewportHeight: 500 }, () => { cy.findByTestId('viewport-size').should('be.visible').contains('500x500') }) - // SelectorPlayground has been removed - all related tests removed - describe('url input', () => { it('shows url if currentTestingType is e2e', () => { const autStore = useAutStore() @@ -177,7 +175,6 @@ describe('SpecRunnerHeaderOpenMode', { viewportHeight: 500 }, () => { }, }) - // SelectorPlayground button has been removed cy.findByTestId('aut-url-input').should('have.prop', 'readOnly', true) cy.findByTestId('aut-url-input').should('have.prop', 'placeholder', 'URL navigation disabled in component testing') cy.findByTestId('viewport-size').should('be.visible').contains('500x500') diff --git a/packages/app/src/runner/SpecRunnerHeaderRunMode.cy.tsx b/packages/app/src/runner/SpecRunnerHeaderRunMode.cy.tsx index 6e2cefed042..2875c3e0d62 100644 --- a/packages/app/src/runner/SpecRunnerHeaderRunMode.cy.tsx +++ b/packages/app/src/runner/SpecRunnerHeaderRunMode.cy.tsx @@ -26,7 +26,6 @@ describe('SpecRunnerHeaderRunMode', { viewportHeight: 500 }, () => { cy.get('[data-cy="select-browser"]') .find('title').should('have.text', 'Chrome 1') - cy.get('[data-cy="playground-activator"]').should('not.exist') // confirm expected content is rendered cy.contains('1000x660').should('be.visible') cy.contains('40%').should('be.visible') @@ -56,7 +55,6 @@ describe('SpecRunnerHeaderRunMode', { viewportHeight: 500 }, () => { cy.contains('URL navigation disabled in component testing').should('be.visible') - cy.get('[data-cy="playground-activator"]').should('not.exist') // confirm expected content is rendered cy.contains('500x500').should('be.visible') cy.contains('40%').should('be.visible') diff --git a/packages/frontend-shared/src/locales/en-US.json b/packages/frontend-shared/src/locales/en-US.json index 8a9b600c69c..9a7a3679433 100644 --- a/packages/frontend-shared/src/locales/en-US.json +++ b/packages/frontend-shared/src/locales/en-US.json @@ -963,17 +963,6 @@ "defaultTitle": "DOM snapshot", "pinnedTitle": "Pinned" }, - "selectorPlayground": { - "matches": "No matches | {n} match | {n} matches", - "playgroundTooltip": "Click an element to see a suggested selector", - "copyTooltip": "Copy to clipboard", - "copyTooltipAction": "Copied!", - "printTooltip": "Print to console", - "printTooltipAction": "Printed!", - "invalidSelector": "Invalid", - "selectorMethodsLabel": "Selector methods", - "toggle": "Toggle playground" - }, "automation": { "disconnected": { "title": "The Cypress extension has disconnected.",