Skip to content

Commit

Permalink
#1170@patch: Throws an error when providing an invalid selector to qu…
Browse files Browse the repository at this point in the history
…erySelector() and querySelectorAll().
  • Loading branch information
capricorn86 committed Jan 15, 2024
1 parent 85ea7d7 commit 61b3137
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 32 deletions.
33 changes: 22 additions & 11 deletions packages/happy-dom/src/query-selector/QuerySelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ type IDocumentPositionAndElement = {
element: IElement;
};

/**
* Invalid Selector RegExp.
*/
const INVALID_SELECTOR_REGEXP = /^[.#\[]?\d/;

/**
* Utility for query selection in an HTML element.
*
Expand All @@ -35,19 +40,17 @@ export default class QuerySelector {
): INodeList<IElement> {
if (selector === '') {
throw new Error(
"Failed to execute 'querySelectorAll' on 'Element': The provided selector is empty."
`Failed to execute 'querySelectorAll' on '${node.constructor.name}': The provided selector is empty.`
);
}

if (selector === null || selector === undefined) {
return new NodeList<IElement>();
}

if (/^[.#\[]?\d/.test(selector)) {
if (INVALID_SELECTOR_REGEXP.test(selector)) {
throw new Error(
"Failed to execute 'querySelectorAll' on 'Element': '" +
selector +
"' is not a valid selector."
`Failed to execute 'querySelectorAll' on '${node.constructor.name}': '${selector}' is not a valid selector.`
);
}

Expand Down Expand Up @@ -87,22 +90,20 @@ export default class QuerySelector {
public static querySelector(
node: IElement | IDocument | IDocumentFragment,
selector: string
): IElement {
): IElement | null {
if (selector === '') {
throw new Error(
"Failed to execute 'querySelector' on 'Element': The provided selector is empty."
`Failed to execute 'querySelector' on '${node.constructor.name}': The provided selector is empty.`
);
}

if (selector === null || selector === undefined) {
return null;
}

if (/^[.#\[]?\d/.test(selector)) {
if (INVALID_SELECTOR_REGEXP.test(selector)) {
throw new Error(
"Failed to execute 'querySelector' on 'Element': '" +
selector +
"' is not a valid selector."
`Failed to execute 'querySelector' on '${node.constructor.name}': '${selector}' is not a valid selector.`
);
}

Expand All @@ -128,12 +129,22 @@ export default class QuerySelector {
* @returns Result.
*/
public static match(element: IElement, selector: string): ISelectorMatch | null {
if (!selector) {
return null;
}

if (selector === '*') {
return {
priorityWeight: 1
};
}

if (INVALID_SELECTOR_REGEXP.test(selector)) {
throw new Error(
`Failed to execute 'match' on '${element.constructor.name}': '${selector}' is not a valid selector.`
);
}

for (const items of SelectorParser.getSelectorGroups(selector)) {
const result = this.matchSelector(element, element, items.reverse());

Expand Down
42 changes: 21 additions & 21 deletions packages/happy-dom/test/query-selector/QuerySelector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,22 @@ describe('QuerySelector', () => {

expect(elements.length).toBe(0);
});

it('Throws an error when providing an invalid selector', () => {
const div = document.createElement('div');
expect(() => div.querySelectorAll('1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'HTMLElement': '1' is not a valid selector."
);
expect(() => div.querySelectorAll('[1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'HTMLElement': '[1' is not a valid selector."
);
expect(() => div.querySelectorAll('.1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'HTMLElement': '.1' is not a valid selector."
);
expect(() => div.querySelectorAll('#1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'HTMLElement': '#1' is not a valid selector."
);
});
});

describe('querySelector', () => {
Expand Down Expand Up @@ -1127,35 +1143,19 @@ describe('QuerySelector', () => {
expect(element2 === div.children[0]).toBe(true);
});

it('querySelector Trhow an error when provide selector is a invalid value', () => {
it('Throws an error when providing an invalid selector', () => {
const div = document.createElement('div');
expect(() => div.querySelector('1')).toThrowError(
"Failed to execute 'querySelector' on 'Element': '1' is not a valid selector."
"Failed to execute 'querySelector' on 'HTMLElement': '1' is not a valid selector."
);
expect(() => div.querySelector('[1')).toThrowError(
"Failed to execute 'querySelector' on 'Element': '[1' is not a valid selector."
"Failed to execute 'querySelector' on 'HTMLElement': '[1' is not a valid selector."
);
expect(() => div.querySelector('.1')).toThrowError(
"Failed to execute 'querySelector' on 'Element': '.1' is not a valid selector."
"Failed to execute 'querySelector' on 'HTMLElement': '.1' is not a valid selector."
);
expect(() => div.querySelector('#1')).toThrowError(
"Failed to execute 'querySelector' on 'Element': '#1' is not a valid selector."
);
});

it('querySelectorAll Trhow an error when provide selector is a invalid value', () => {
const div = document.createElement('div');
expect(() => div.querySelectorAll('1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'Element': '1' is not a valid selector."
);
expect(() => div.querySelectorAll('[1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'Element': '[1' is not a valid selector."
);
expect(() => div.querySelectorAll('.1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'Element': '.1' is not a valid selector."
);
expect(() => div.querySelectorAll('#1')).toThrowError(
"Failed to execute 'querySelectorAll' on 'Element': '#1' is not a valid selector."
"Failed to execute 'querySelector' on 'HTMLElement': '#1' is not a valid selector."
);
});
});
Expand Down

0 comments on commit 61b3137

Please sign in to comment.