From de53a510a298a89d00615c5c935668080df38fab Mon Sep 17 00:00:00 2001 From: Matthew Lieder Date: Wed, 12 Oct 2022 09:57:30 -0500 Subject: [PATCH] #614@patch: Element.matches not working properly with descendant combinators. --- .../src/query-selector/QuerySelector.ts | 4 +-- .../test/nodes/element/Element.test.ts | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/happy-dom/src/query-selector/QuerySelector.ts b/packages/happy-dom/src/query-selector/QuerySelector.ts index 31bf010bc..ad0958c60 100644 --- a/packages/happy-dom/src/query-selector/QuerySelector.ts +++ b/packages/happy-dom/src/query-selector/QuerySelector.ts @@ -106,14 +106,14 @@ export default class QuerySelector { const selector = new SelectorItem(selectorParts[0]); const result = selector.match(currentNode); - if (targetNode === currentNode && !result.matches) { + if ((targetNode === currentNode || !currentNode.parentNode) && !result.matches) { return { priorityWeight: 0, matches: false }; } return this.matchesSelector( isDirectChild ? currentNode.parentNode : targetNode, currentNode.parentNode, - selectorParts.slice(1), + result.matches ? selectorParts.slice(1) : selectorParts, priorityWeight + result.priorityWeight ); } diff --git a/packages/happy-dom/test/nodes/element/Element.test.ts b/packages/happy-dom/test/nodes/element/Element.test.ts index 7a6e78549..3d0489872 100644 --- a/packages/happy-dom/test/nodes/element/Element.test.ts +++ b/packages/happy-dom/test/nodes/element/Element.test.ts @@ -694,6 +694,38 @@ describe('Element', () => { expect(element.matches('.container, .active')).toBe(true); }); + + it('Checks if the element matches with a descendant combinator', () => { + const grandparentElement = document.createElement('div'); + grandparentElement.setAttribute('role', 'alert'); + + const parentElement = document.createElement('div'); + parentElement.setAttribute('role', 'status'); + grandparentElement.appendChild(parentElement); + + const element = document.createElement('div'); + element.className = 'active'; + parentElement.appendChild(element); + + expect(element.matches('div[role="alert"] div.active')).toBe(true); + expect(element.matches('div[role="article"] div.active')).toBe(false); + }); + + it('Checks if the element matches with a child combinator', () => { + const grandparentElement = document.createElement('div'); + grandparentElement.setAttribute('role', 'alert'); + + const parentElement = document.createElement('div'); + grandparentElement.setAttribute('role', 'status'); + grandparentElement.appendChild(parentElement); + + const element = document.createElement('div'); + element.className = 'active'; + parentElement.appendChild(element); + + expect(element.matches('div[role="status"] > div.active')).toBe(true); + expect(element.matches('div[role="alert"] > div.active')).toBe(false); + }); }); describe('closest()', () => {