Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3e440ec
feat: Rename SelectorPriority API to ElementSelector API
jennifer-shehane Jun 13, 2025
139874d
Merge branch 'release/15.0.0' into selector-playground-api-to-element…
jennifer-shehane Jun 13, 2025
e07db39
bump unique-selector + remove restriction on type of prop
jennifer-shehane Jun 13, 2025
5b1eece
Merge branch 'selector-playground-api-to-element-selector' of https:/…
jennifer-shehane Jun 13, 2025
54538a8
rename file + remove test
jennifer-shehane Jun 13, 2025
2ce3309
rename and add types to files
jennifer-shehane Jun 13, 2025
080d9d6
save file
jennifer-shehane Jun 13, 2025
770af77
fix types
jennifer-shehane Jun 16, 2025
6866162
Add error when Cypress.SelectorPlayground is called to suggest renaming
jennifer-shehane Jun 16, 2025
e3c103e
Add better description of ElementSelector API
jennifer-shehane Jun 16, 2025
c31f27d
Error on invalid selector priority types
jennifer-shehane Jun 17, 2025
f002750
changelog entry
jennifer-shehane Jun 18, 2025
72e8260
Merge branch 'release/15.0.0' into selector-playground-api-to-element…
jennifer-shehane Jun 18, 2025
d792b66
Update types to match exact type of selectorPriority
jennifer-shehane Jun 20, 2025
ea5816d
remove semicolon
jennifer-shehane Jun 20, 2025
3fa5bdb
Add feature description for separate feature
jennifer-shehane Jun 20, 2025
c909ecb
remove the other semicolon
jennifer-shehane Jun 20, 2025
8d16f65
Update types to use official cypress types
jennifer-shehane Jun 23, 2025
8330fa3
Add other issue that this PR resolves.
jennifer-shehane Jun 24, 2025
54b71a7
add name to selector priority
jennifer-shehane Jun 24, 2025
bd5a7f9
alphabetize strings in selectorPriority types
jennifer-shehane Jun 24, 2025
d1c4948
Merge branch 'release/15.0.0' into selector-playground-api-to-element…
jennifer-shehane Jun 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions cli/types/cypress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,10 +696,10 @@ declare namespace Cypress {
}

/**
* @see https://on.cypress.io/selector-playground-api
* @see https://on.cypress.io/element-selector-api
*/
SelectorPlayground: {
defaults(options: Partial<SelectorPlaygroundDefaultsOptions>): void
ElementSelector: {
defaults(options: Partial<ElementSelectorDefaultsOptions>): void
getSelector($el: JQuery): JQuery.Selector
}

Expand Down Expand Up @@ -2971,7 +2971,7 @@ declare namespace Cypress {
*/
requestTimeout: number
/**
* Time, in milliseconds, to wait until a response in a [cy.request()](https://on.cypress.io/request), [cy.wait()](https://on.cypress.io/wait), [cy.fixture()](https://on.cypress.io/fixture), [cy.getCookie()](https://on.cypress.io/getcookie), [cy.getCookies()](https://on.cypress.io/getcookies), [cy.setCookie()](https://on.cypress.io/setcookie), [cy.clearCookie()](https://on.cypress.io/clearcookie), [cy.clearCookies()](https://on.cypress.io/clearcookies), and [cy.screenshot()](https://on.cypress.io/screenshot) commands
* Time, in milliseconds, to wait for a response in a [cy.request()](https://on.cypress.io/request), [cy.wait()](https://on.cypress.io/wait), [cy.fixture()](https://on.cypress.io/fixture), [cy.getCookie()](https://on.cypress.io/getcookie), [cy.getCookies()](https://on.cypress.io/getcookies), [cy.setCookie()](https://on.cypress.io/setcookie), [cy.clearCookie()](https://on.cypress.io/clearcookie), [cy.clearCookies()](https://on.cypress.io/clearcookies), and [cy.screenshot()](https://on.cypress.io/screenshot) commands
* @default 30000
*/
responseTimeout: number
Expand Down Expand Up @@ -3714,9 +3714,8 @@ declare namespace Cypress {
screenshotOnRunFailure: boolean
}

interface SelectorPlaygroundDefaultsOptions {
interface ElementSelectorDefaultsOptions {
selectorPriority: string[]
onElement: ($el: JQuery) => string | null | undefined
}

interface ScrollToOptions extends Loggable, Timeoutable {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/runner/aut-iframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export class AutIframe {

const Cypress = this.eventManager.getCypress()

const selector = Cypress.SelectorPlayground.getSelector($el)
const selector = Cypress.ElementSelector.getSelector($el)
const selectorPlaygroundStore = useSelectorPlaygroundStore()

this._addOrUpdateSelectorPlaygroundHighlight({
Expand Down
6 changes: 3 additions & 3 deletions packages/app/src/store/studio-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ export const useStudioStore = defineStore('studioRecorder', {
if (name === 'click' && this._matchPreviousMouseEvent($el)) {
selector = this._previousMouseEvent?.selector
} else {
selector = getCypress().SelectorPlayground.getSelector($el)
selector = getCypress().ElementSelector.getSelector($el)
}

this._clearPreviousMouseEvent()
Expand Down Expand Up @@ -428,7 +428,7 @@ export const useStudioStore = defineStore('studioRecorder', {

_addAssertion ($el: HTMLElement | JQuery<HTMLElement>, ...args: AssertionArgs) {
const id = this._getId()
const selector = getCypress().SelectorPlayground.getSelector($el)
const selector = getCypress().ElementSelector.getSelector($el)

const log: StudioLog = {
id,
Expand Down Expand Up @@ -649,7 +649,7 @@ export const useStudioStore = defineStore('studioRecorder', {
if (!this._matchPreviousMouseEvent(target)) {
this._previousMouseEvent = {
element: target,
selector: getCypress().SelectorPlayground.getSelector(window.UnifiedRunner.CypressJQuery(target)),
selector: getCypress().ElementSelector.getSelector(window.UnifiedRunner.CypressJQuery(target)),
}
}
},
Expand Down
86 changes: 86 additions & 0 deletions packages/driver/cypress/e2e/cypress/element_selector.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/// <reference types="cypress" />
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted to TypeScript - the tests are the same except for removing tests around onElement

import type { ElementSelectorAPI, SelectorType } from '../../../src/cypress/element_selector'
import { DEFAULT_SELECTOR_PRIORITIES } from '../../../src/cypress/element_selector'
const { $: $cypress } = Cypress.$Cypress
const ElementSelector = Cypress.ElementSelector as ElementSelectorAPI

const SELECTOR_DEFAULTS: SelectorType[] = [...DEFAULT_SELECTOR_PRIORITIES]

describe('src/cypress/element_selector', () => {
beforeEach(() => {
ElementSelector.reset()
})

it('has defaults', () => {
expect(ElementSelector.getSelectorPriority()).to.deep.eq(SELECTOR_DEFAULTS)
})

context('.defaults', () => {
it('is noop if not called with selectorPriority', () => {
ElementSelector.defaults({})
expect(ElementSelector.getSelectorPriority()).to.deep.eq(SELECTOR_DEFAULTS)
})

it('sets element:selector:priority if selectorPriority specified', () => {
const selectorPriority: SelectorType[] = [
'data-1',
'data-2',
'id',
'class',
'tag',
'attributes',
'nth-child',
]

ElementSelector.defaults({
selectorPriority,
})

expect(ElementSelector.getSelectorPriority()).to.eql(selectorPriority)
})

it('throws if not passed an object', () => {
const fn = () => {
ElementSelector.defaults(undefined as any)
}

expect(fn).to.throw()
.with.property('message')
.and.include('`Cypress.ElementSelector.defaults()` must be called with an object. You passed: ')

expect(fn).to.throw()
.with.property('docsUrl')
.and.include('https://on.cypress.io/element-selector-api')
})

it('throws if selectorPriority is not an array', () => {
const fn = () => {
ElementSelector.defaults({ selectorPriority: 'foo' as any })
}

expect(fn).to.throw()
.with.property('message')
.and.include('`Cypress.ElementSelector.defaults()` called with invalid `selectorPriority` property. It must be an array. You passed: `foo`')

expect(fn).to.throw()
.with.property('docsUrl')
.and.include('https://on.cypress.io/element-selector-api')
})
})

context('.getSelector', () => {
it('uses defaults.selectorPriority', () => {
const $div = $cypress('<div data-cy=\'main button 123\' data-foo-bar-baz=\'quux\' data-test=\'qwerty\' data-foo=\'bar\' />')

Cypress.$('body').append($div)

expect(ElementSelector.getSelector($div)).to.eq('[data-cy="main button 123"]')

ElementSelector.defaults({
selectorPriority: ['data-foo'],
})

expect(ElementSelector.getSelector($div)).to.eq('[data-foo="bar"]')
})
})
})
154 changes: 0 additions & 154 deletions packages/driver/cypress/e2e/cypress/selector_playground.cy.js

This file was deleted.

2 changes: 1 addition & 1 deletion packages/driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"devDependencies": {
"@babel/code-frame": "7.24.7",
"@cypress/sinon-chai": "2.9.1",
"@cypress/unique-selector": "0.0.5",
"@cypress/unique-selector": "2.1.1",
"@cypress/webpack-dev-server": "0.0.0-development",
"@cypress/webpack-preprocessor": "0.0.0-development",
"@packages/config": "0.0.0-development",
Expand Down
4 changes: 2 additions & 2 deletions packages/driver/src/cypress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import $Mocha from './cypress/mocha'
import { create as createMouse } from './cy/mouse'
import $Runner from './cypress/runner'
import $Screenshot from './cypress/screenshot'
import $SelectorPlayground from './cypress/selector_playground'
import $ElementSelector from './cypress/element_selector'
import $Server from './cypress/server'
import $SetterGetter from './cypress/setter_getter'
import { validateConfig } from './util/config'
Expand Down Expand Up @@ -151,7 +151,7 @@ class $Cypress {
Runner = $Runner
Server = $Server
Screenshot = $Screenshot
SelectorPlayground = $SelectorPlayground
ElementSelector = $ElementSelector
utils = $utils
_ = _
Blob = blobUtil
Expand Down
Loading
Loading