Skip to content

Bug Report: nwsapi fails to parse CSS selectors containing :focus-visible in styled-components context (jsdom/Jest) #157

@KlimekM

Description

@KlimekM

Hey there!

Description
When rendering components that use styled-components with :focus-visible selectors, nwsapi generates malformed CSS selectors with multiple consecutive commas, which then fail parsing.

I had the following errors begin cropping up in a test suite after nwsapi got bumped to the latest version 2.2.23 in running Jest with @testing-library/user-event. This seems similar to and possibly related to:

Error messages:

SyntaxError: 'div,,,__title.StyledHeader-sc-1787r9v-0 :focus-visible' is not a valid selector
SyntaxError: 'div,,,__content.StyledBody-sc-14rzecg-0 :focus-visible' is not a valid selector

Longer stacktraces:

 SyntaxError: 'div,,,__title.StyledHeader-sc-1787r9v-0 :focus-visible' is not a valid selector

      at emit (node_modules/nwsapi/src/nwsapi.js:670:17)
      at parse (node_modules/nwsapi/src/nwsapi.js:1612:13)
      at _querySelectorAll (node_modules/nwsapi/src/nwsapi.js:1701:44)
      at Object._querySelector [as first] (node_modules/nwsapi/src/nwsapi.js:1637:14)
      at HTMLDivElementImpl.querySelector (node_modules/jsdom/lib/jsdom/living/nodes/ParentNode-impl.js:69:44)
      at HTMLDivElement.querySelector (node_modules/jsdom/lib/jsdom/living/generated/Element.js:1094:58)
      at Array.Resolver (eval at compile (node_modules/nwsapi/src/nwsapi.js:896:17), <anonymous>:3:67)
      at match_assert (node_modules/nwsapi/src/nwsapi.js:1556:13)
      at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1626:16)
      at exports.matchesDontThrow (node_modules/jsdom/lib/jsdom/living/helpers/selectors.js:29:36)
      at matches (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:172:10)
      at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:109:18
          at Array.forEach (<anonymous>)
      at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:100:13)
          at Array.forEach (<anonymous>)
      at forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:120:11)
      at Object.exports.getDeclarationForElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:156:3)
      at getCascadedPropertyValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:182:18)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:188:19)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at exports.getResolvedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:240:10)
      at node_modules/jsdom/lib/jsdom/browser/Window.js:913:41
          at Array.forEach (<anonymous>)
      at window.getComputedStyle (node_modules/jsdom/lib/jsdom/browser/Window.js:912:13)
      at closestPointerEventsDeclaration (node_modules/@testing-library/user-event/dist/cjs/utils/pointer/cssPointerEvents.js:16:38)
      at checkPointerEvents (node_modules/@testing-library/user-event/dist/cjs/utils/pointer/cssPointerEvents.js:36:25)
      at Object.assertPointerEvents (node_modules/@testing-library/user-event/dist/cjs/utils/pointer/cssPointerEvents.js:45:25)
      at Object.enter (node_modules/@testing-library/user-event/dist/cjs/system/pointer/pointer.js:52:34)
      at PointerHost.move (node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:53:85)
      at pointerAction (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:59:39)
      at Object.pointer (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:27:15)
      at node_modules/@testing-library/react/dist/pure.js:59:16
SyntaxError: 'div,,,__content.StyledBody-sc-14rzecg-0 :focus-visible' is not a valid selector

      59 |
      60 |       screen.logTestingPlaygroundURL()
    > 61 |       const fieldTypeRadio = screen.getByRole('radio', {
         |                                     ^
      62 |         name: `${fieldType?.tileTitle} ${fieldType?.tileDescription}`
      63 |       })
      64 |

      at emit (node_modules/nwsapi/src/nwsapi.js:670:17)
      at parse (node_modules/nwsapi/src/nwsapi.js:1612:13)
      at _querySelectorAll (node_modules/nwsapi/src/nwsapi.js:1701:44)
      at Object._querySelector [as first] (node_modules/nwsapi/src/nwsapi.js:1637:14)
      at HTMLDivElementImpl.querySelector (node_modules/jsdom/lib/jsdom/living/nodes/ParentNode-impl.js:69:44)
      at HTMLDivElement.querySelector (node_modules/jsdom/lib/jsdom/living/generated/Element.js:1094:58)
      at Array.Resolver (eval at compile (node_modules/nwsapi/src/nwsapi.js:896:17), <anonymous>:3:67)
      at match_assert (node_modules/nwsapi/src/nwsapi.js:1556:13)
      at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1626:16)
      at exports.matchesDontThrow (node_modules/jsdom/lib/jsdom/living/helpers/selectors.js:29:36)
      at matches (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:172:10)
      at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:109:18
          at Array.forEach (<anonymous>)
      at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:100:13)
          at Array.forEach (<anonymous>)
      at forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:120:11)
      at Object.exports.getDeclarationForElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:156:3)
      at getCascadedPropertyValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:182:18)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:188:19)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at getSpecifiedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:200:12)
      at getComputedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:211:12)
      at exports.getResolvedValue (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:240:10)
      at node_modules/jsdom/lib/jsdom/browser/Window.js:913:41
          at Array.forEach (<anonymous>)
      at window.getComputedStyle (node_modules/jsdom/lib/jsdom/browser/Window.js:912:13)
      at getComputedStyleImplementation (node_modules/@testing-library/dom/node_modules/dom-accessibility-api/sources/accessible-name-and-description.ts:84:16)
      at isHidden (node_modules/@testing-library/dom/node_modules/dom-accessibility-api/sources/accessible-name-and-description.ts:570:4)
      at computeTextAlternative (node_modules/@testing-library/dom/node_modules/dom-accessibility-api/sources/accessible-name-and-description.ts:721:3)
      at computeAccessibleName (node_modules/@testing-library/dom/node_modules/dom-accessibility-api/sources/accessible-name.ts:40:31)
      at node_modules/@testing-library/dom/dist/queries/role.js:132:82
          at Array.filter (<anonymous>)
      at queryAllByRole (node_modules/@testing-library/dom/dist/queries/role.js:127:6)
      at node_modules/@testing-library/dom/dist/query-helpers.js:74:17
      at node_modules/@testing-library/dom/dist/query-helpers.js:52:17
      at node_modules/@testing-library/dom/dist/query-helpers.js:95:19
      at getByRole

Environment

  • jest: 30.2.0
  • jest-environment-jsdom: 30.2.0
  • styled-components: 5.3.11
  • @testing-library/user-event: 14.6.1
  • Node: 22+

Workaround
I was able to get around the issue by using an override to pin nwsapi to version 2.2.20 in package.json.

Additional Context
Hope that helps, happy to provide any additional info as needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions