Skip to content

Bug: Modifying the Cypress.SelectorPlayground.defaults - selectorPriority breaks the Selector Playground #7745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mthoreso opened this issue Jun 17, 2020 · 7 comments · Fixed by #18573
Assignees
Labels
pkg/driver This is due to an issue in the packages/driver directory topic: selector playground 🚸 type: bug

Comments

@mthoreso
Copy link

mthoreso commented Jun 17, 2020

Current behavior:

Modifying the Cypress.SelectorPlayground.defaults in the support/index.js file breaks the Selector Playground in the GUI.

Desired behavior:

To be able to modify/add to the selectorPriority list and still use the Selector Playground.

Test code to reproduce

If you modify the cypress/support/index.js file with this:

Cypress.SelectorPlayground.defaults({
  selectorPriority: [
    "data-qa",
    "data-test",
    "data-cy",
    "id",
    "class",
    "name",
    "tag",
    "attributes",
    "nth-child",
  ],
});

The selector playground is broken and doesn't work at all.

When I comment this block of code out, the Selector Playground works normally.

This issue helped me figure out where to modify the selectorPriority:
7606

Versions

Cypress 4.7.0 and 4.8.0, MacOS, Chrome

@jennifer-shehane
Copy link
Member

I can verify that overwriting the Cypress.SelectorPlayground.defaults for the selectorPriority breaks the functionality of the Selector Playground.

This seems to have always been an issue? Back to 3.4.1 anyway.

spec.js

// this is default selector priority
Cypress.SelectorPlayground.defaults({
  selectorPriority: [
    "data-cy",
    "data-test",
    "data-testid",
    "id",
    "class",
    "name",
    "tag",
    "attributes",
    "nth-child",
  ]
})

it('Selector Playground', () => {
  cy.visit('https://example.cypress.io')
})

Without overwriting defaults

With overwriting defaults

@cypress-bot cypress-bot bot added the stage: ready for work The issue is reproducible and in scope label Jun 18, 2020
@jennifer-shehane jennifer-shehane added the pkg/driver This is due to an issue in the packages/driver directory label Jun 18, 2020
@madbreena
Copy link

I am facing the same issue. Will this be resolved?

@dwilches
Copy link

Today I hit the same issue. Is there a planned date in which this might be fixed?

@dwilches
Copy link

dwilches commented Jan 21, 2021

I found a workaround, instead of using selectorPriority use onElement.

So instead of:

Cypress.SelectorPlayground.defaults({
  selectorPriority: [
    "my-attribute-1",
    "my-attribute-2",
    ...
  ]
})

Use this:

Cypress.SelectorPlayground.defaults({
    onElement: ($el) => {
        const attr1 = $el.attr("my-attribute-1");
        if (attr1) {
            return `[my-attribute-1="${attr1}"]`;
        }
        const attr2 = $el.attr("my-attribute-2");
        if (attr2) {
            return `[my-attribute-2="${attr2}"]`;
        }
        // Default behaviour
        return false;
    },
});

@cypress-bot cypress-bot bot added stage: backlog and removed stage: ready for work The issue is reproducible and in scope labels Oct 15, 2021
@mjhenkes
Copy link
Contributor

Cause

The selector playground breaks in this instance because the name key is not supported by the selectorPriority field.

Cypress.SelectorPlayground.defaults({
  selectorPriority: [
    "data-qa",
    "data-test",
    "data-cy",
    "id",
    "class",
    "name",    // <-This priority is causing the issue.
    "tag",
    "attributes",
    "nth-child",
  ],
});

Explanation

We use a fork of the unique-selector package to generate the selectors for the playground. The unique-selector package only supports the following 'priorities':

  • data-*
  • id
  • class
  • attributes
  • nth-child
  • tag

Adding the name priority causes the getAllSelectors function to blow up because it doesn't have a function to create a selector for that attribute.

Resolution

We can modify Cypress to validate that the selectPriority configuration option is only set with the accepted keys. This resolution would prevent users from putting cypress in a bad state. If unique-selector falls back to the attributes priority to generate the selector, it will choose the first unique attribute. If a user wishes to create a selector that prefers one attribute over another they can (as the above workaround suggests) use the onElement configuration option to construct the selector as desired. One caveat here is that the selector priority will be ignored as long as the constructed selector is unique.

Example

DOM

<div id="item1" name="div"> example </div>

<div id="item2" name="Fred"> Fred Example </div>

<div id="item3" name="Fred"> Second Fred Example </div>

Config

Cypress.SelectorPlayground.defaults({
  onElement: ($el) => {
    const attr1 = $el.attr("name");
    if (attr1) {
      return `[name="${attr1}"]`;
    }
    const attr2 = $el.attr("title");
    if (attr2) {
      return `[title="${attr2}"]`;
    }

    return undefined;
  },
});

Cypress.SelectorPlayground.defaults({
  selectorPriority: [
    "id",
    "attributes",
  ],
});

Selector

[name="div"]

#item2

#item3

For the first example you might expect the selector to be #item1 because of the selectorPriority, but the onElement config will take precedence.

For the second and third example, the id is used because the [name="Fred"] selector is not unique.

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress and removed stage: work in progress stage: needs review The PR code is done & tested, needs review labels Oct 20, 2021
@cypress-bot cypress-bot bot added stage: pending release and removed stage: needs review The PR code is done & tested, needs review labels Oct 21, 2021
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Oct 21, 2021

The code for this is done in cypress-io/cypress#18573, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Oct 25, 2021

Released in 8.7.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v8.7.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Oct 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg/driver This is due to an issue in the packages/driver directory topic: selector playground 🚸 type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants