[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.0node
version: 20.11.0jest
version: 29.7.0yarn
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.