testing-library / jest-dom

:owl: Custom jest matchers to test the state of the DOM

Home Page:https://testing-library.com/docs/ecosystem-jest-dom

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[attribute selector]:has(+ el) pseudo-class selector with emotionStyled reported as syntax error

gavrielrh opened this issue · comments

  • @testing-library/jest-dom version: 6.2.0
  • node version: 20.11.0
  • jest version: 29.7.0
  • yarn version: 1.22.19

Relevant code or config:

import styled from "@emotion/styled";
import { expect, test } from "@jest/globals";
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";

const StyledDiv = styled("div")({
  /* Selects an unchecked checkbox element 
  with a paragraph element that immediately follows
  the checkbox and applies the style to the checkbox */
  '[aria-checked="false"]:has(+ p)': {
    marginBottom: 200,
  },
});

function Example() {
  return (
    <StyledDiv>
      <input
        type="checkbox"
        checked={false}
        aria-checked="false"
        readOnly={true}
      />
      <p>World</p>
    </StyledDiv>
  );
}

test("renders example", async () => {
  render(<Example />);
  expect(screen.getByRole("checkbox")).toBeTruthy();
});

What you did:

Wrote a test for a component that uses a specific CSS selector in emotionStyled.
The CSS is applying properly to the component outside of the test.
Ran the test.

What happened:

    SyntaxError: missing ) after argument list
        at Function (<anonymous>)

       6 | test("renders example", async () => {
       7 |   render(<Example />);
    >  8 |   expect(screen.getByRole("checkbox")).toBeTruthy();
         |                 ^
       9 | });
      10 |

      at compile (node_modules/nwsapi/src/nwsapi.js:760:17)
      at match_collect (node_modules/nwsapi/src/nwsapi.js:1339:16)
      at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1394:35)
      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:50:10)
      at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:35:18
          at Array.forEach (<anonymous>)
      at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:26:13)
          at Array.forEach (<anonymous>)
      at exports.forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:46:11)
      at Window.getComputedStyle (node_modules/jsdom/lib/jsdom/browser/Window.js:802:5)
      at isInaccessible (node_modules/@testing-library/dom/dist/role-helpers.js:67:14)
      at node_modules/@testing-library/dom/dist/queries/role.js:195:63
          at Array.filter (<anonymous>)
      at queryAllByRole (node_modules/@testing-library/dom/dist/queries/role.js:194: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 getByRole (node_modules/@testing-library/dom/dist/query-helpers.js:95:19)
      at Object.<anonymous> (src/Example.test.tsx:8:17)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
      at runJest (node_modules/@jest/core/build/runJest.js:404:19)

Reproduction:

Codesandbox: https://codesandbox.io/p/devbox/eager-leaf-fk2n4y?file=%2Fsrc%2Findex.test.tsx%3A11%2C1

Problem description:

It appears that an underlying library (nwsapi?) used by @testing-library fails to parse the :has() pseudo-class selector if it is prefixed with an attribute selector. This bubbles up as a syntax error when running the test.

The syntax error is not very helpful:

  SyntaxError: missing ) after argument list
        at Function (<anonymous>)

       6 | test("renders example", async () => {
       7 |   render(<Example />);
    >  8 |   expect(screen.getByRole("checkbox")).toBeTruthy();
         |                 ^
       9 | });

and the error itself means it is impossible to test components using emotion styled that rely on this selector.

Suggested solution:

Assuming the issue is with nwsapi, updating how it parses the :has() selector to account for the possibility of a attribute selector prefix, would fix this.
I don't know enough about testing-library/dom -> jsdom -> nwsapi to feel confident that this is the correct solution though.