fix(css selector): handle missing spaces between [] and > (#2612)
This commit is contained in:
parent
082bb3c3c4
commit
f581e84829
|
|
@ -221,7 +221,6 @@ function split(selector: string): string[][] {
|
||||||
let quote: string | undefined;
|
let quote: string | undefined;
|
||||||
let insideAttr = false;
|
let insideAttr = false;
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let space: 'none' | 'before' | 'after' = 'none';
|
|
||||||
const result: string[][] = [];
|
const result: string[][] = [];
|
||||||
let current: string[] = [];
|
let current: string[] = [];
|
||||||
const appendToCurrent = () => {
|
const appendToCurrent = () => {
|
||||||
|
|
@ -234,24 +233,23 @@ function split(selector: string): string[][] {
|
||||||
result.push(current);
|
result.push(current);
|
||||||
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) {
|
while (index < selector.length) {
|
||||||
const c = selector[index];
|
const c = selector[index];
|
||||||
if (!quote && !insideAttr && c === ' ') {
|
if (!quote && !insideAttr && c === ' ' && !isCombinator(peekForward()) && !isCombinator(peekBackward())) {
|
||||||
if (space === 'none' || space === 'before')
|
appendToCurrent();
|
||||||
space = 'before';
|
start = index;
|
||||||
index++;
|
index++;
|
||||||
} else {
|
} 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) {
|
if (c === '\\' && index + 1 < selector.length) {
|
||||||
index += 2;
|
index += 2;
|
||||||
} else if (c === quote) {
|
} else if (c === quote) {
|
||||||
|
|
|
||||||
|
|
@ -662,6 +662,24 @@ describe('css selector', () => {
|
||||||
expect(await root3.$(`css:light=[attr*="value"]`)).toBe(null);
|
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}) => {
|
it('should work with comma separated list', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/deep-shadow.html');
|
await page.goto(server.PREFIX + '/deep-shadow.html');
|
||||||
expect(await page.$$eval(`css=span,section #root1`, els => els.length)).toBe(5);
|
expect(await page.$$eval(`css=span,section #root1`, els => els.length)).toBe(5);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue