Repository: capricorn86/happy-dom (ts)

Issue:
`:not()` pseudo class doesn't consider element type
**Describe the bug**
`:not(element)` selector doesn't consider provided element type when matching nodes.

**To Reproduce**
The following reproduction test is currently failing in happy-dom.
```js
it('Returns all elements matching "[tabindex]:not(textarea)".', () => {
  document.body.innerHTML = `
    <div tabindex="-1"></div>
    <div tabindex="0"></div>
    <div tabindex="1"></div>
    <textarea tabindex="-1"></textarea>
  `;
  const elements = document.querySelectorAll('[tabindex]:not(textarea)');
  
  expect(elements.length).toBe(3);   // but actual is 0
});
```

**Expected behavior**
`:not()` pseudo class selector should properly match elements that do not match provided element type selector.



Pull request:
#753@patch: Pseudo `not` should match element
fix #753 

Patch:
diff --git a/packages/happy-dom/src/query-selector/SelectorItem.ts b/packages/happy-dom/src/query-selector/SelectorItem.ts
index cca4cb5c..4e95ad99 100644
--- a/packages/happy-dom/src/query-selector/SelectorItem.ts
+++ b/packages/happy-dom/src/query-selector/SelectorItem.ts
@@ -125,12 +125,20 @@ export default class SelectorItem {
 			const isNotClass = match[3] && match[3].trim()[0] === '.';
 			if (match[1] && !this.matchesNthChild(element, match[1], match[2])) {
 				return false;
-			} else if (
-				match[3] &&
-				((isNotClass && this.matchesClass(element, match[3]).matches) ||
-					(!isNotClass && this.matchesAttribute(element, match[3])).matches)
-			) {
-				return false;
+			} else if (match[3]) {
+				if (isNotClass && this.matchesClass(element, match[3]).matches) {
+					return false;
+				}
+				if (
+					!isNotClass &&
+					match[3].includes('[') &&
+					this.matchesAttribute(element, match[3]).matches
+				) {
+					return false;
+				}
+				if (!isNotClass && element.tagName.toLowerCase() === match[3]) {
+					return false;
+				}
 			} else if (match[4] && !this.matchesPsuedoExpression(element, match[4])) {
 				return false;
 			}


Test patch:
diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
index 0adf0de4..9f1dd914 100644
--- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts
+++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
@@ -486,6 +486,18 @@ describe('QuerySelector', () => {
 			expect(elements[0]).toBe(document.body.children[1]);
 		});
 
+		it('Returns all elements matching "[tabindex]:not(textarea)".', () => {
+			document.body.innerHTML = `
+				<div tabindex="-1"></div>
+				<div tabindex="0"></div>
+				<div tabindex="1"></div>
+				<textarea tabindex="-1"></textarea>
+			`;
+			const elements = document.querySelectorAll('[tabindex]:not(textarea)');
+			expect(elements.length).toBe(3);
+			expect(elements[0]).toBe(document.body.children[0]);
+		});
+
 		it('Returns all span elements matching span:nth-child(1) or span:nth-child(2).', () => {
 			const container = document.createElement('div');
 			container.innerHTML = QuerySelectorHTML;