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');