Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/server/common/cssParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
1 change: 0 additions & 1 deletion tests/browsertype-connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});

Expand Down
3 changes: 2 additions & 1 deletion tests/css-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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)');
Expand Down
8 changes: 8 additions & 0 deletions tests/page/selectors-css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down