chore: better error message when CSS selector fails to parse (#34331)
This commit is contained in:
parent
aeec0c0e36
commit
4d55d3039a
|
|
@ -43,7 +43,7 @@ export function parseCSS(selector: string, customNames: Set<string>): { selector
|
||||||
if (!(tokens[tokens.length - 1] instanceof css.EOFToken))
|
if (!(tokens[tokens.length - 1] instanceof css.EOFToken))
|
||||||
tokens.push(new css.EOFToken());
|
tokens.push(new css.EOFToken());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const newMessage = e.message + ` while parsing selector "${selector}"`;
|
const newMessage = e.message + ` while parsing css selector "${selector}". Did you mean to CSS.escape it?`;
|
||||||
const index = (e.stack || '').indexOf(e.message);
|
const index = (e.stack || '').indexOf(e.message);
|
||||||
if (index !== -1)
|
if (index !== -1)
|
||||||
e.stack = e.stack.substring(0, index) + newMessage + e.stack.substring(index + e.message.length);
|
e.stack = e.stack.substring(0, index) + newMessage + e.stack.substring(index + e.message.length);
|
||||||
|
|
@ -68,13 +68,13 @@ export function parseCSS(selector: string, customNames: Set<string>): { selector
|
||||||
(token instanceof css.PercentageToken);
|
(token instanceof css.PercentageToken);
|
||||||
});
|
});
|
||||||
if (unsupportedToken)
|
if (unsupportedToken)
|
||||||
throw new InvalidSelectorError(`Unsupported token "${unsupportedToken.toSource()}" while parsing selector "${selector}"`);
|
throw new InvalidSelectorError(`Unsupported token "${unsupportedToken.toSource()}" while parsing css selector "${selector}". Did you mean to CSS.escape it?`);
|
||||||
|
|
||||||
let pos = 0;
|
let pos = 0;
|
||||||
const names = new Set<string>();
|
const names = new Set<string>();
|
||||||
|
|
||||||
function unexpected() {
|
function unexpected() {
|
||||||
return new InvalidSelectorError(`Unexpected token "${tokens[pos].toSource()}" while parsing selector "${selector}"`);
|
return new InvalidSelectorError(`Unexpected token "${tokens[pos].toSource()}" while parsing css selector "${selector}". Did you mean to CSS.escape it?`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function skipWhitespace() {
|
function skipWhitespace() {
|
||||||
|
|
@ -246,7 +246,7 @@ export function parseCSS(selector: string, customNames: Set<string>): { selector
|
||||||
if (!isEOF())
|
if (!isEOF())
|
||||||
throw unexpected();
|
throw unexpected();
|
||||||
if (result.some(arg => typeof arg !== 'object' || !('simples' in arg)))
|
if (result.some(arg => typeof arg !== 'object' || !('simples' in arg)))
|
||||||
throw new InvalidSelectorError(`Error while parsing selector "${selector}"`);
|
throw new InvalidSelectorError(`Error while parsing css selector "${selector}". Did you mean to CSS.escape it?`);
|
||||||
return { selector: result as CSSComplexSelector[], names: Array.from(names) };
|
return { selector: result as CSSComplexSelector[], names: Array.from(names) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,8 @@ it('should throw on malformed css', async () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
expect(error.message).toContain(`while parsing selector "${selector}"`);
|
expect(error.message).toContain(`while parsing css selector "${selector}"`);
|
||||||
|
expect(error.message).toContain(`Did you mean to CSS.escape it?`);
|
||||||
}
|
}
|
||||||
|
|
||||||
expectError('');
|
expectError('');
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,7 @@ test('should print unknown engine error', async ({ page }) => {
|
||||||
|
|
||||||
test('should print selector syntax error', async ({ page }) => {
|
test('should print selector syntax error', async ({ page }) => {
|
||||||
const error = await expect(page.locator('row]')).toBeVisible().catch(e => e);
|
const error = await expect(page.locator('row]')).toBeVisible().catch(e => e);
|
||||||
expect(error.message).toContain(`Unexpected token "]" while parsing selector "row]"`);
|
expect(error.message).toContain(`Unexpected token "]" while parsing css selector "row]"`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe(() => {
|
test.describe(() => {
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,7 @@ it('should work with internal:has=', async ({ page, server }) => {
|
||||||
const error3 = await page.$(`div >> internal:has=33`).catch(e => e);
|
const error3 = await page.$(`div >> internal:has=33`).catch(e => e);
|
||||||
expect(error3.message).toContain('Malformed selector: internal:has=33');
|
expect(error3.message).toContain('Malformed selector: internal:has=33');
|
||||||
const error4 = await page.$(`div >> internal:has="span!"`).catch(e => e);
|
const error4 = await page.$(`div >> internal:has="span!"`).catch(e => e);
|
||||||
expect(error4.message).toContain('Unexpected token "!" while parsing selector "span!"');
|
expect(error4.message).toContain('Unexpected token "!" while parsing css selector "span!"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with internal:has-not=', async ({ page }) => {
|
it('should work with internal:has-not=', async ({ page }) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue