mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-12 20:03:03 +03:00
fix(css selector): absolutize relative CSS selectors (#9088)
Selectors like `> div` are replaced by `:scope > div`, which is useful for combining them with parent selectors. This is a part of CSS Level 4 spec.
This commit is contained in:
parent
79eb7744bc
commit
f0d23b5d4d
@ -133,8 +133,14 @@ export function parseCSS(selector: string, customNames: Set<string>): { selector
|
||||
}
|
||||
|
||||
function consumeComplexSelector(): CSSComplexSelector {
|
||||
const result: CSSComplexSelector = { simples: [] };
|
||||
skipWhitespace();
|
||||
const result = { simples: [{ selector: consumeSimpleSelector(), combinator: '' as ClauseCombinator }] };
|
||||
if (isClauseCombinator()) {
|
||||
// Put implicit ":scope" at the start. https://drafts.csswg.org/selectors-4/#absolutize
|
||||
result.simples.push({ selector: { functions: [{ name: 'scope', args: [] }] }, combinator: '' });
|
||||
} else {
|
||||
result.simples.push({ selector: consumeSimpleSelector(), combinator: '' });
|
||||
}
|
||||
while (true) {
|
||||
skipWhitespace();
|
||||
if (isClauseCombinator()) {
|
||||
|
@ -156,7 +156,6 @@ test('should support slowmo option', async ({browserType, startRemoteServer}) =>
|
||||
const start = Date.now();
|
||||
await browser1.newContext();
|
||||
await browser1.close();
|
||||
console.log(Date.now() - start);
|
||||
expect(Date.now() - start).toBeGreaterThan(199);
|
||||
});
|
||||
|
||||
|
@ -18,7 +18,7 @@ import { playwrightTest as it, expect } from './config/browserTest';
|
||||
import { parseCSS, serializeSelector as serialize } from '../src/server/common/cssParser';
|
||||
|
||||
const parse = (selector: string) => {
|
||||
return parseCSS(selector, new Set(['text', 'not', 'has', 'react', 'scope', 'right-of', 'scope', 'is'])).selector;
|
||||
return parseCSS(selector, new Set(['text', 'not', 'has', 'react', 'scope', 'right-of', 'is'])).selector;
|
||||
};
|
||||
|
||||
it('should parse css', async () => {
|
||||
@ -48,6 +48,7 @@ it('should parse css', async () => {
|
||||
expect(serialize(parse('div~ span'))).toBe('div ~ span');
|
||||
expect(serialize(parse('div >.class #id+ span'))).toBe('div > .class #id + span');
|
||||
expect(serialize(parse('div>span+.class'))).toBe('div > span + .class');
|
||||
expect(serialize(parse('>span'))).toBe(':scope() > span');
|
||||
|
||||
expect(serialize(parse('div:not(span)'))).toBe('div:not(span)');
|
||||
expect(serialize(parse(':not(span)#id'))).toBe('#id:not(span)');
|
||||
|
@ -385,6 +385,14 @@ it('should work with :scope', async ({page, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should absolutize relative selectors', async ({page, server}) => {
|
||||
await page.setContent(`<div><span>Hi</span></div>`);
|
||||
expect(await page.$eval('div >> >span', e => e.textContent)).toBe('Hi');
|
||||
expect(await page.locator('div').locator('>span').textContent()).toBe('Hi');
|
||||
expect(await page.$eval('div:has(> span)', e => e.outerHTML)).toBe('<div><span>Hi</span></div>');
|
||||
expect(await page.$('div:has(> div)')).toBe(null);
|
||||
});
|
||||
|
||||
it('css on the handle should be relative', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<span class="find-me" id=target1>1</span>
|
||||
|
Loading…
Reference in New Issue
Block a user