cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.02k stars 3.18k forks source link

Cypress treats case-insensitive selectors as a syntax error instead of a valid selector #25304

Open TiManGames opened 1 year ago

TiManGames commented 1 year ago

Current behavior

Cypress treats case-insensitive selectors as a syntax error, despite the selector being valid image

Desired behavior

Cypress should find the element. It works in Cypress Runner just fine.

image

Test code to reproduce

cy.visit("https://www.saucedemo.com/");
cy.get('.login-box').find(`[data-test="login-button" i]`); <--- fails on "invalid syntax" 

Cypress Version

11.2.0

Node version

v14.18.0

Operating System

Windows 10 22H2

Debug Logs

No response

Other

No response

bahmutov commented 1 year ago

Can confirm. In Cypress v9.7.0

    ### Case-insensitive attribute selectors

    <!-- fiddle.only cy.get / Case-insensitive selectors -->

    <button class="btn-PRIMARY">Green</button>
    <button class="btn-primary">Red</button>

     cy.get('button[class=btn-primary i]').should('have.length', 2)

     <!-- fiddle-end -->

Produces an error

Screen Shot 2022-12-29 at 09 08 54
emilyrohrbough commented 1 year ago

I am to reproduce this with Cypress 12.2.0, though I am unable to repo using @bahmutov's snippet:

  it('t1', () => {
    cy.visit('https://example.cypress.io/commands/querying')
    cy.get('code[class="javascript hljs" i]').should('have.length', 8)              // PASSES
    cy.get('code').find('[class="javascript hljs" i]').should('have.length', 8)     // FAILS
    cy.get('pre').find('code[class="javascript hljs" i]').should('have.length', 8)  // FAILS
  })

This error is coming from Sizzle:

    at Sizzle.error (https://example.cypress.io/__cypress/runner/cypress_runner.js:91924:8)
    at Sizzle.tokenize (https://example.cypress.io/__cypress/runner/cypress_runner.js:92576:11)
    at Function.Sizzle [as find] (https://example.cypress.io/__cypress/runner/cypress_runner.js:91198:15)
    at jQuery.fn.init.find (https://example.cypress.io/__cypress/runner/cypress_runner.js:93259:11)
    at getEl (https://example.cypress.io/__cypress/runner/cypress_runner.js:145737:31)
    at <unknown> (https://example.cypress.io/__cypress/runner/cypress_runner.js:145777:21)
    at Object.subjectFn (https://example.cypress.io/__cypress/runner/cypress_runner.js:154817:16)
    at $Cy.verifyUpcomingAssertions (https://example.cypress.io/__cypress/runner/cypress_runner.js:134218:31)
    at onRetry (https://example.cypress.io/__cypress/runner/cypress_runner.js:154809:15)
arindams commented 1 year ago

it is reproducible in 12.16 as-well. is it planned to be fixed ?

zokkis commented 1 year ago

Same in 12.8.1

bahmutov commented 12 months ago

Find my workaround for this bug in https://glebbahmutov.com/cypress-examples/recipes/case-insensitive-query.html and in the video https://youtu.be/XQ6GQSmF5_I

S-Tornqvist commented 11 months ago

Seems that the problem might not only be Sizzle, but rather the browser version used by Cypress https://stackoverflow.com/a/70466178: "This happens because jQuery switches selector engines depending on the selector it's given. By default, when given a valid CSS selector jQuery passes it to the browser's native selector engine via document.querySelectorAll() to match elements. This is to maximize performance." The i qualifier (CSS4 https://www.w3.org/TR/selectors-4/#attribute-case) is not supported by Sizzle. If the browser also does not support it the selector is still given to Sizzle, which crashes . My guess is that the same is true for the s qualifier.

If this is true then one solution would be upgrading the Cypress browser versions to ones that support CSS4. I don't think it would be feasible to override the behavior of jQuery, Sizzle or the native browser to solve this.

The jQuery project has two issues about this: https://github.com/jquery/jquery/issues/4841 and https://github.com/jquery/jquery/issues/5111