fix(css selector): handle missing spaces between [] and > (#2612)
This commit is contained in:
Родитель
082bb3c3c4
Коммит
f581e84829
|
@ -221,7 +221,6 @@ function split(selector: string): string[][] {
|
|||
let quote: string | undefined;
|
||||
let insideAttr = false;
|
||||
let start = 0;
|
||||
let space: 'none' | 'before' | 'after' = 'none';
|
||||
const result: string[][] = [];
|
||||
let current: string[] = [];
|
||||
const appendToCurrent = () => {
|
||||
|
@ -234,24 +233,23 @@ function split(selector: string): string[][] {
|
|||
result.push(current);
|
||||
current = [];
|
||||
};
|
||||
const isCombinator = (char: string) => {
|
||||
return char === '>' || char === '+' || char === '~';
|
||||
};
|
||||
const peekForward = () => {
|
||||
return selector.substring(index).trim()[0];
|
||||
};
|
||||
const peekBackward = () => {
|
||||
const s = selector.substring(0, index).trim();
|
||||
return s[s.length - 1];
|
||||
};
|
||||
while (index < selector.length) {
|
||||
const c = selector[index];
|
||||
if (!quote && !insideAttr && c === ' ') {
|
||||
if (space === 'none' || space === 'before')
|
||||
space = 'before';
|
||||
if (!quote && !insideAttr && c === ' ' && !isCombinator(peekForward()) && !isCombinator(peekBackward())) {
|
||||
appendToCurrent();
|
||||
start = index;
|
||||
index++;
|
||||
} else {
|
||||
if (space === 'before') {
|
||||
if (c === '>' || c === '+' || c === '~') {
|
||||
space = 'after';
|
||||
} else {
|
||||
appendToCurrent();
|
||||
start = index;
|
||||
space = 'none';
|
||||
}
|
||||
} else {
|
||||
space = 'none';
|
||||
}
|
||||
if (c === '\\' && index + 1 < selector.length) {
|
||||
index += 2;
|
||||
} else if (c === quote) {
|
||||
|
|
|
@ -662,6 +662,24 @@ describe('css selector', () => {
|
|||
expect(await root3.$(`css:light=[attr*="value"]`)).toBe(null);
|
||||
});
|
||||
|
||||
it('should work with > combinator and spaces', async({page, server}) => {
|
||||
await page.setContent(`<div foo="bar" bar="baz"><span></span></div>`);
|
||||
expect(await page.$eval(`div[foo="bar"] > span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"]> span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"] >span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"]>span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"] > span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"]> span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"] >span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"] > span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"]> span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"] >span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"]>span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"] > span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"]> span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
expect(await page.$eval(`div[foo="bar"][bar="baz"] >span`, e => e.outerHTML)).toBe(`<span></span>`);
|
||||
});
|
||||
|
||||
it('should work with comma separated list', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/deep-shadow.html');
|
||||
expect(await page.$$eval(`css=span,section #root1`, els => els.length)).toBe(5);
|
||||
|
|
Загрузка…
Ссылка в новой задаче