From 1499871584289c0a3044e84524e1c73bb9439435 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Tue, 29 Jul 2025 09:34:52 -0400 Subject: [PATCH 1/5] Rewrite to make its use more understandable + remove getSelector --- docs/api/cypress-api/element-selector-api.mdx | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/docs/api/cypress-api/element-selector-api.mdx b/docs/api/cypress-api/element-selector-api.mdx index d2a2665d80..330111d71d 100644 --- a/docs/api/cypress-api/element-selector-api.mdx +++ b/docs/api/cypress-api/element-selector-api.mdx @@ -1,6 +1,6 @@ --- title: 'Cypress.ElementSelector | Cypress Documentation' -description: 'The Element Selector exposes APIs that enable you to change the default selector strategy and override the selectors that are returned per element.' +description: 'Customize how Cypress chooses selectors in Studio and Selector Playground by setting your preferred selector strategy.' sidebar_label: ElementSelector sidebar_position: 105 --- @@ -9,13 +9,14 @@ sidebar_position: 105 # Cypress.ElementSelector -The Element Selector API is used to get the selector priority for selecting elements in [Cypress Studio](/app/guides/cypress-studio) and [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). +The ElementSelector API lets you define how Cypress selects elements in tools like [Cypress Studio](/app/guides/cypress-studio) and the [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). + +By setting your own selector strategy, you can control which attributes Cypress prioritizes (like `data-*`, `id`, or `aria-label`) when generating selectors. This helps you enforce consistency, improve test readability, and make generated tests more resilient to changes in your HTML. ## Syntax ```javascript Cypress.ElementSelector.defaults(options) -Cypress.ElementSelector.getSelector($el) ``` ### Arguments @@ -26,9 +27,9 @@ An object containing any or all of the following options: | Option | Accepts | Description | | ------------------ | ------------------ | -------------------------------------------------------------------------------- | -| `selectorPriority` | `Array of strings` | Determines the order of preference for which selector is chosen for the element. | +| `selectorPriority` | `Array of strings` | Determines the order of attributes Cypress uses to generate selectors. | -`selectorPriority` accepts the following strings: +Accepted values for `selectorPriority` are: - `attribute:${string}` - `attributes` @@ -41,16 +42,25 @@ An object containing any or all of the following options: +Consider the following HTML: + +```html + +``` + +With the default selector priority, Cypress prioritizes id, so the selector would be `#submit-btn`. + **$el _(Object)_** -The [jQuery element](http://api.jquery.com/Types/#jQuery) that you want to get -the selector value for. +The [jQuery element](http://api.jquery.com/Types/#jQuery) for which you want to retrieve a selector. ## Examples -### Selector Priority +### Set custom selector priority + +You can customize how Cypress generates selectors by defining a priority order for which attributes to prefer. This affects the selectors you see in tools like [Cypress Studio](/app/guides/cypress-studio) and the [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). -Set the selector priority to favor role, then aria-label, then name, then classes, then attributes. +For example, you may want Cypress to prefer semantic attributes (`role`, `aria-label`, `name`) over implementation details (`class`, `id`): ```javascript Cypress.ElementSelector.defaults({ @@ -64,37 +74,23 @@ Cypress.ElementSelector.defaults({ }) ``` -### Get Selector +### Prioritize accessible attributes -Returns you the selector value for a given element as determined by the selector -strategy. This is useful for debugging custom selector priorities you have set. - -For example, consider this HTML fragment: - -```html - -``` - -With the default selector strategy, the selector value will be `'#bingo'` -because IDs have priority over classes. - -```js -const $el = Cypress.$('button') -const selector = Cypress.ElementSelector.getSelector($el) // '#bingo' -``` - -With a custom selector strategy that favors classes, the selector value will be -`'.number3'`. +Now, let's say you want to favor ARIA and semantic attributes over `id` and `class`. You update the selector strategy as follows: ```js Cypress.ElementSelector.defaults({ - selectorPriority: ['class', 'id'], + selectorPriority: [ + 'attribute:aria-label', + 'attribute:role', + 'id', + 'class', + ], }) - -const $el = Cypress.$('button') -const selector = Cypress.ElementSelector.getSelector($el) // '.number3' ``` +This helps produce more readable and resilient selectors, especially for accessibility-first applications. + ## See also - [Cypress Studio](/app/guides/cypress-studio) From eee26d438dfa3056b9acc6c500e378b7fee3389c Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Tue, 29 Jul 2025 10:16:35 -0400 Subject: [PATCH 2/5] Add more examples + simplify --- docs/api/cypress-api/element-selector-api.mdx | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/docs/api/cypress-api/element-selector-api.mdx b/docs/api/cypress-api/element-selector-api.mdx index 330111d71d..4fed2e7b41 100644 --- a/docs/api/cypress-api/element-selector-api.mdx +++ b/docs/api/cypress-api/element-selector-api.mdx @@ -31,10 +31,10 @@ An object containing any or all of the following options: Accepted values for `selectorPriority` are: -- `attribute:${string}` -- `attributes` +- `attribute:${string}` - for specific attributes like `attribute:aria-label`, `attribute:lang`, etc. +- `attributes` - general fallback for any other attributes - `class` -- `data-${string}` +- `data-${string}` - for specific data attributes like `data-cy`, `data-testid`, etc. - `id` - `name` - `nth-child` @@ -48,7 +48,7 @@ Consider the following HTML: ``` -With the default selector priority, Cypress prioritizes id, so the selector would be `#submit-btn`. +With the default selector priority, Cypress prioritizes `id`, so the selector would be `#submit-btn`. **$el _(Object)_** @@ -60,7 +60,7 @@ The [jQuery element](http://api.jquery.com/Types/#jQuery) for which you want to You can customize how Cypress generates selectors by defining a priority order for which attributes to prefer. This affects the selectors you see in tools like [Cypress Studio](/app/guides/cypress-studio) and the [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). -For example, you may want Cypress to prefer semantic attributes (`role`, `aria-label`, `name`) over implementation details (`class`, `id`): +For example, this config tells Cypress to prefer semantic and accessibility attributes before falling back to styling details like class names. ```javascript Cypress.ElementSelector.defaults({ @@ -76,7 +76,7 @@ Cypress.ElementSelector.defaults({ ### Prioritize accessible attributes -Now, let's say you want to favor ARIA and semantic attributes over `id` and `class`. You update the selector strategy as follows: +Accessibility-first apps often use ARIA roles and labels. You can configure Cypress to prioritize these when generating selectors: ```js Cypress.ElementSelector.defaults({ @@ -91,6 +91,57 @@ Cypress.ElementSelector.defaults({ This helps produce more readable and resilient selectors, especially for accessibility-first applications. +### Prioritize language-agnostic selectors (for i18n) + +In multilingual applications, selectors based on text or labels may change between locales. Prefer stable, language-agnostic attributes like `data-*`, `role`, and `aria-labelledby`. + +```js +Cypress.ElementSelector.defaults({ + selectorPriority: [ + 'data-cy', + 'attribute:role', + 'attribute:aria-labelledby', + 'name', + 'id', + 'class', + 'attributes', + ], +}) +``` + +This ensures selectors are resilient to translation changes in text or labels. + +### Avoid dynamic or auto-generated selectors + +Many frameworks produce dynamic ids or class names such as: + +```html + +``` + +You can configure Cypress to prioritize `data-cy` and `role` attributes, and skip `id` and `class` attributes that are dynamically generated. + +```js +Cypress.ElementSelector.defaults({ + selectorPriority: [ + 'data-cy', + 'attribute:role', + 'attribute:aria-label', + 'name', + 'attributes', // fallback + // deliberately omit 'id' and 'class' + ], +}) +``` + ## See also - [Cypress Studio](/app/guides/cypress-studio) From 1c6f81b9d581c8cd5d267b6a02585e14efe0a351 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Tue, 29 Jul 2025 10:23:08 -0400 Subject: [PATCH 3/5] lint --- docs/api/cypress-api/element-selector-api.mdx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/api/cypress-api/element-selector-api.mdx b/docs/api/cypress-api/element-selector-api.mdx index 4fed2e7b41..d7c38574b9 100644 --- a/docs/api/cypress-api/element-selector-api.mdx +++ b/docs/api/cypress-api/element-selector-api.mdx @@ -9,7 +9,7 @@ sidebar_position: 105 # Cypress.ElementSelector -The ElementSelector API lets you define how Cypress selects elements in tools like [Cypress Studio](/app/guides/cypress-studio) and the [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). +The ElementSelector API lets you define how Cypress selects elements in tools like [Cypress Studio](/app/guides/cypress-studio) and the [Selector Playground](/app/core-concepts/open-mode#Selector-Playground). By setting your own selector strategy, you can control which attributes Cypress prioritizes (like `data-*`, `id`, or `aria-label`) when generating selectors. This helps you enforce consistency, improve test readability, and make generated tests more resilient to changes in your HTML. @@ -25,8 +25,8 @@ Cypress.ElementSelector.defaults(options) An object containing any or all of the following options: -| Option | Accepts | Description | -| ------------------ | ------------------ | -------------------------------------------------------------------------------- | +| Option | Accepts | Description | +| ------------------ | ------------------ | ---------------------------------------------------------------------- | | `selectorPriority` | `Array of strings` | Determines the order of attributes Cypress uses to generate selectors. | Accepted values for `selectorPriority` are: @@ -44,8 +44,10 @@ Accepted values for `selectorPriority` are: Consider the following HTML: -```html - +```html + ``` With the default selector priority, Cypress prioritizes `id`, so the selector would be `#submit-btn`. @@ -80,12 +82,7 @@ Accessibility-first apps often use ARIA roles and labels. You can configure Cypr ```js Cypress.ElementSelector.defaults({ - selectorPriority: [ - 'attribute:aria-label', - 'attribute:role', - 'id', - 'class', - ], + selectorPriority: ['attribute:aria-label', 'attribute:role', 'id', 'class'], }) ``` From 4d448d0586bc1994f05b801431dd4022d0d4db21 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Tue, 29 Jul 2025 10:33:51 -0400 Subject: [PATCH 4/5] add note about uniqueness of selector --- docs/api/cypress-api/element-selector-api.mdx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/api/cypress-api/element-selector-api.mdx b/docs/api/cypress-api/element-selector-api.mdx index d7c38574b9..5013760096 100644 --- a/docs/api/cypress-api/element-selector-api.mdx +++ b/docs/api/cypress-api/element-selector-api.mdx @@ -13,6 +13,11 @@ The ElementSelector API lets you define how Cypress selects elements in tools li By setting your own selector strategy, you can control which attributes Cypress prioritizes (like `data-*`, `id`, or `aria-label`) when generating selectors. This helps you enforce consistency, improve test readability, and make generated tests more resilient to changes in your HTML. +Cypress uses a strategy to generate selectors that are not only based on your preferred selectors, but also guaranteed to be **unique** within the document. + +This means Cypress will **attempt to follow your configured `selectorPriority`**, but may skip lower-priority options or combine multiple selectors if a single attribute isn't unique enough. + + ## Syntax ```javascript @@ -139,6 +144,12 @@ Cypress.ElementSelector.defaults({ }) ``` +## History + +| Version | Changes | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | +| [15.0.0](/app/references/changelog#15-0-0) | Renamed `Cypress.SelectorPlayground` to `Cypress.ElementSelector`. | + ## See also - [Cypress Studio](/app/guides/cypress-studio) From 9696a59aa0df2225c768343bcf513bf7e92c40e9 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Tue, 29 Jul 2025 10:41:29 -0400 Subject: [PATCH 5/5] lint --- docs/api/cypress-api/element-selector-api.mdx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/api/cypress-api/element-selector-api.mdx b/docs/api/cypress-api/element-selector-api.mdx index 5013760096..28a1f40a05 100644 --- a/docs/api/cypress-api/element-selector-api.mdx +++ b/docs/api/cypress-api/element-selector-api.mdx @@ -17,7 +17,6 @@ Cypress uses a strategy to generate selectors that are not only based on your pr This means Cypress will **attempt to follow your configured `selectorPriority`**, but may skip lower-priority options or combine multiple selectors if a single attribute isn't unique enough. - ## Syntax ```javascript @@ -146,9 +145,9 @@ Cypress.ElementSelector.defaults({ ## History -| Version | Changes | -| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -| [15.0.0](/app/references/changelog#15-0-0) | Renamed `Cypress.SelectorPlayground` to `Cypress.ElementSelector`. | +| Version | Changes | +| ------------------------------------------ | ------------------------------------------------------------------ | +| [15.0.0](/app/references/changelog#15-0-0) | Renamed `Cypress.SelectorPlayground` to `Cypress.ElementSelector`. | ## See also