diff --git a/packages/happy-dom/src/query-selector/SelectorParser.ts b/packages/happy-dom/src/query-selector/SelectorParser.ts
index da6875b0..eb960dcd 100644
--- a/packages/happy-dom/src/query-selector/SelectorParser.ts
+++ b/packages/happy-dom/src/query-selector/SelectorParser.ts
@@ -25,7 +25,7 @@ import ISelectorPseudo from './ISelectorPseudo.js';
* Group 17: Combinator.
*/
const SELECTOR_REGEXP =
- /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_]|\\.)+)|\.((?:[a-zA-Z0-9-_]|\\.)+)|\[([a-zA-Z0-9-_]+)\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*["']{1}([^"']*)["']{1}\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(([^)]+\)?)\)|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>]*)/gm;
+ /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_]|\\.)+)|\.((?:[a-zA-Z0-9-_]|\\.)+)|\[([a-zA-Z0-9-_\\:]+)\]|\[([a-zA-Z0-9-_\\:]+)\s*([~|^$*]{0,1})\s*=\s*["']{1}([^"']*)["']{1}\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(([^)]+)\){0,1}|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>]*)/gm;
/**
* Escaped Character RegExp.
diff --git a/packages/happy-dom/src/xml-parser/XMLParser.ts b/packages/happy-dom/src/xml-parser/XMLParser.ts
index b5452b57..079965c0 100755
--- a/packages/happy-dom/src/xml-parser/XMLParser.ts
+++ b/packages/happy-dom/src/xml-parser/XMLParser.ts
@@ -42,7 +42,7 @@ const MARKUP_REGEXP =
* Group 9: Attribute name when the attribute has no value (e.g. "disabled" in "
").
*/
const ATTRIBUTE_REGEXP =
- /\s*([a-zA-Z0-9-_:.$@?]+) *= *([a-zA-Z0-9-_:.$@?{}/]+)|\s*([a-zA-Z0-9-_:.$@?]+) *= *"([^"]*)("{0,1})|\s*([a-zA-Z0-9-_:.$@?]+) *= *'([^']*)('{0,1})|\s*([a-zA-Z0-9-_:.$@?]+)/gm;
+ /\s*([a-zA-Z0-9-_:.$@?\\]+) *= *([a-zA-Z0-9-_:.$@?{}/]+)|\s*([a-zA-Z0-9-_:.$@?\\]+) *= *"([^"]*)("{0,1})|\s*([a-zA-Z0-9-_:.$@?\\]+) *= *'([^']*)('{0,1})|\s*([a-zA-Z0-9-_:.$@?\\]+)/gm;
enum MarkupReadStateEnum {
startOrEndTag = 'startOrEndTag',
diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
index 0a89cce2..2a561b40 100644
--- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts
+++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
@@ -847,6 +847,31 @@ describe('QuerySelector', () => {
expect(elements3[1] === container.children[0].children[1].children[2]).toBe(true);
});
+ it('Returns all elements matching the selector without ending parenthese "button:not([type]"', () => {
+ const container = document.createElement('div');
+ container.innerHTML = `
+
+
+
+ `;
+ const elements = container.querySelectorAll('button:not([type]');
+ expect(elements.length).toBe(2);
+ expect(elements[0]).toBe(container.children[0]);
+ expect(elements[1]).toBe(container.children[2]);
+ });
+
+ it('Returns all elements matching the invalid selector "[q\\:shadowroot]"', () => {
+ const container = document.createElement('div');
+ container.innerHTML = `
+
+
+
+ `;
+ const elements = container.querySelectorAll('[q\\:shadowroot]');
+ expect(elements.length).toBe(1);
+ expect(elements[0]).toBe(container.children[0]);
+ });
+
it('Returns all elements matching "input:not([type]):not([list])" to verify that "screen.getByRole(\'checkbox\')" works in Testing Library.', () => {
const container = document.createElement('div');