Skip to content

test: Add coverage for :is()/:matches() containing nested :has() selectors#4422

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-parseerror-issues
Draft

test: Add coverage for :is()/:matches() containing nested :has() selectors#4422
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-parseerror-issues

Conversation

Copy link

Copilot AI commented Mar 10, 2026

The parser threw ParseError: Missing closing ')' when parsing pseudo-selectors like :is(:not(:has(>.foo)), :has(>.foo.bar)), despite the parentheses being balanced. The fix was already applied in PR #4290 (changing the element fallback parser to loop through comma-separated selector lists rather than expecting a single selector before )), but the specific scenario from this issue had no test coverage.

Changes

  • tests-unit/selectors/selectors.less — Added test cases for:
    • :is(:not(:has(>.foo)), :has(>.foo.bar)) — the exact failing case
    • :matches(:not(:has(>.foo)), :has(>.foo.bar)):matches() variant
    • :is(:has(>.foo + .bar), :has(>.baz ~ .qux), :not(:has(.quux))) — multiple complex nested :has() arguments
  • tests-unit/selectors/selectors.css — Corresponding expected output
// Previously threw: ParseError: Missing closing ')'
:is(:not(:has(>.foo)), :has(>.foo.bar)) {
  overflow: clip;
}
Original prompt

This section details on the original issue you should resolve

<issue_title>ParseError with :is() or :matches() containing :has()</issue_title>
<issue_description>To reproduce:

:is(:not(:has(>.foo)), :has(>.foo.bar)) {
    overflow: clip;
}

Current behavior:

Throw a:
ParseError: Missing closing ')'

Expected behavior:

No exception has the number of close parenthesis is correct
Environment information:

  • less version: 4.2.0
  • nodejs version: 20.17
  • operating system: windows</issue_description>

<agent_instructions>Can we get proper selector parsing for known pseudo-selectors that can have selectors?</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@matthew-dean Related to: https://github.com//issues/4268 @puckowski I submitted a PR #4290

The following Less

@num: 3;
:nth-child(@{num}) {
  selector: interpolated;
}


a:is(.b, :is(.c)) {
  color: blue;
}

:is(:not(:has(>.foo)), :has(>.foo.bar)) {
  overflow: clip;
}

becomes:

:nth-child(3) {
  selector: interpolated;
}
a:is(.b, :is(.c)) {
  color: blue;
}
:is(:not(:has(>.foo)), :has(>.foo.bar)) {
  overflow: clip;
}
```</body></comment_new>
</comments>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 11, 2026 00:03
Co-authored-by: matthew-dean <414752+matthew-dean@users.noreply.github.com>
)

Co-authored-by: matthew-dean <414752+matthew-dean@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ParseError with :is() or :matches() containing :has() test: Add coverage for :is()/:matches() containing nested :has() selectors Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ParseError with :is() or :matches() containing :has()

2 participants