Tests: Import some selector pseudo-class parsing tests

This commit is contained in:
Sam Atkins 2025-05-16 13:36:05 +01:00 committed by Andreas Kling
commit eb98bd1a36
Notes: github-actions[bot] 2025-05-16 22:32:20 +00:00
6 changed files with 233 additions and 0 deletions

View file

@ -0,0 +1,35 @@
Harness status: OK
Found 29 tests
6 Pass
23 Fail
Fail ":has(a)" should be a valid selector
Fail ":has(#a)" should be a valid selector
Fail ":has(.a)" should be a valid selector
Fail ":has([a])" should be a valid selector
Fail ":has([a=\"b\"])" should be a valid selector
Fail ":has([a|=\"b\"])" should be a valid selector
Fail ":has(:hover)" should be a valid selector
Fail "*:has(.a)" should be a valid selector
Fail ".a:has(.b)" should be a valid selector
Fail ".a:has(> .b)" should be a valid selector
Fail ".a:has(~ .b)" should be a valid selector
Fail ".a:has(+ .b)" should be a valid selector
Fail ".a:has(.b) .c" should be a valid selector
Fail ".a .b:has(.c)" should be a valid selector
Fail ".a .b:has(.c .d)" should be a valid selector
Fail ".a .b:has(.c .d) .e" should be a valid selector
Fail ".a:has(.b:is(.c .d))" should be a valid selector
Fail ".a:is(.b:has(.c) .d)" should be a valid selector
Fail ".a:not(:has(.b))" should be a valid selector
Fail ".a:has(:not(.b))" should be a valid selector
Fail ".a:has(.b):has(.c)" should be a valid selector
Fail "*|*:has(*)" should be a valid selector
Fail ":has(*|*)" should be a valid selector
Pass ":has" should be an invalid selector
Pass ".a:has" should be an invalid selector
Pass ".a:has b" should be an invalid selector
Pass ":has()" should be an invalid selector
Pass ":has(123)" should be an invalid selector
Pass ":has(.a, 123)" should be an invalid selector

View file

@ -0,0 +1,39 @@
Harness status: OK
Found 33 tests
24 Pass
9 Fail
Pass ":is(div )" should be a valid selector
Pass ":where(div )" should be a valid selector
Pass ":is(div + bar, div ~ .baz)" should be a valid selector
Pass ":where(div + bar, div ~ .baz)" should be a valid selector
Pass ":is(:is(div))" should be a valid selector
Pass ":where(:is(div))" should be a valid selector
Pass ":is(:where(div))" should be a valid selector
Pass ":where(:where(div))" should be a valid selector
Pass ":host(:is(div))" should be a valid selector
Pass ":host(:where(div))" should be a valid selector
Pass ":host(:is(div ))" should be a valid selector
Pass ":host(:where(div ))" should be a valid selector
Fail ":host(:is(div .foo))" should be a valid selector
Fail ":host(:where(div .foo))" should be a valid selector
Pass ":is(:hover, :active)" should be a valid selector
Pass ":where(:hover, :active)" should be a valid selector
Pass ":is(div):hover" should be a valid selector
Pass ":where(div):hover" should be a valid selector
Pass ":is(div)::before" should be a valid selector
Pass ":where(div)::before" should be a valid selector
Fail ":is(::before)" should be a valid selector
Fail ":where(::before)" should be a valid selector
Pass ":is(div) + bar" should be a valid selector
Pass ":where(div) + bar" should be a valid selector
Fail "::part(foo):is(:hover)" should be a valid selector
Fail "::part(foo):where(:hover)" should be a valid selector
Fail "::part(foo):is([attr='value'])" should be a valid selector
Fail "::part(foo):where([attr='value'])" should be a valid selector
Pass ":not(:is(div))" should be a valid selector
Pass ":not(:where(div))" should be a valid selector
Pass ":not(:is(div .foo))" should be a valid selector
Pass ":not(:where(div .foo))" should be a valid selector
Fail ":is(# C4єанйтж╕/┘ГЁжЮХєа▓┐ЁЭБМєаСеЁЭЖА%=[ямм0)" should be an invalid selector

View file

@ -0,0 +1,32 @@
Harness status: OK
Found 26 tests
23 Pass
3 Fail
Pass "button:not([disabled])" should be a valid selector
Pass "*:not(foo)" should be a valid selector
Pass ":not(:link):not(:visited)" should be a valid selector
Fail "*|*:not(*)" should be a valid selector
Pass ":not(:hover)" should be a valid selector
Pass ":not(*|*)" should be a valid selector
Pass "foo:not(bar)" should be a valid selector
Pass ":not(:not(foo))" should be a valid selector
Pass ":not(.a .b)" should be a valid selector
Pass ":not(.a + .b)" should be a valid selector
Pass ":not(.a .b ~ c)" should be a valid selector
Pass ":not(span.a, div.b)" should be a valid selector
Pass ":not(.a .b ~ c, .d .e)" should be a valid selector
Pass ":not(:host)" should be a valid selector
Pass ":not(:host(.a))" should be a valid selector
Pass ":host(:not(.a))" should be a valid selector
Pass ":not(:host(:not(.a)))" should be a valid selector
Pass ":not([disabled][selected])" should be a valid selector
Pass ":not([disabled],[selected])" should be a valid selector
Pass ":not()" should be an invalid selector
Pass ":not(:not())" should be an invalid selector
Fail ":not(::before)" should be an invalid selector
Pass ":not(:unknownpseudo)" should be an invalid selector
Pass ":not(.a, :unknownpseudo)" should be an invalid selector
Pass ":not(:unknownpseudo, .a)" should be an invalid selector
Fail ":host(:not(.a .b))" should be an invalid selector

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Selectors: The relational pseudo-class</title>
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
<link rel="help" href="https://drafts.csswg.org/selectors-4/#has-pseudo">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
<script>
test_valid_selector(':has(a)');
test_valid_selector(':has(#a)');
test_valid_selector(':has(.a)');
test_valid_selector(':has([a])');
test_valid_selector(':has([a="b"])');
test_valid_selector(':has([a|="b"])');
test_valid_selector(':has(:hover)');
test_valid_selector('*:has(.a)', ['*:has(.a)', ':has(.a)']);
test_valid_selector('.a:has(.b)');
test_valid_selector('.a:has(> .b)');
test_valid_selector('.a:has(~ .b)');
test_valid_selector('.a:has(+ .b)');
test_valid_selector('.a:has(.b) .c');
test_valid_selector('.a .b:has(.c)');
test_valid_selector('.a .b:has(.c .d)');
test_valid_selector('.a .b:has(.c .d) .e');
test_valid_selector('.a:has(.b:is(.c .d))');
test_valid_selector('.a:is(.b:has(.c) .d)');
test_valid_selector('.a:not(:has(.b))');
test_valid_selector('.a:has(:not(.b))');
test_valid_selector('.a:has(.b):has(.c)');
test_valid_selector('*|*:has(*)', ':has(*)');
test_valid_selector(':has(*|*)', ':has(*)');
test_invalid_selector(':has');
test_invalid_selector('.a:has');
test_invalid_selector('.a:has b');
/* :has() is unforgiving, but :is() can still forgive */
test_invalid_selector(':has()');
test_invalid_selector(':has(123)');
test_invalid_selector(':has(.a, 123)');
</script>

View file

@ -0,0 +1,50 @@
<!doctype html>
<title>CSS Selectors: :is() and :where() parsing</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="help" href="https://drafts.csswg.org/selectors-4/#matches">
<link rel="help" href="https://drafts.csswg.org/selectors-4/#zero-matches">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
<script>
function assert_valid(valid, pattern, expected_pattern, description) {
for (let pseudo of ["is", "where"]) {
let selector = pattern.replace("{}", ":" + pseudo);
let expected_selector = selector;
if (expected_pattern != null)
expected_selector = expected_pattern.replace("{}", ":" + pseudo);
if (valid) {
test_valid_selector(selector, expected_selector);
} else {
test_valid_forgiving_selector(selector);
}
}
}
assert_valid(true, "{}(div )", "{}(div)", "Trailing whitespace");
assert_valid(true, "{}(div + bar, div ~ .baz)", null, "Multiple selectors with combinators");
assert_valid(true, "{}(:is(div))", null, "Nested :is");
assert_valid(true, "{}(:where(div))", null, "Nested :where");
assert_valid(true, ":host({}(div))", null, "Nested inside :host, without combinators");
assert_valid(true, ":host({}(div ))", ":host({}(div))", "Nested inside :host, with trailing whitespace");
// See https://github.com/w3c/csswg-drafts/issues/5093
assert_valid(false, ":host({}(div .foo))", null, "Nested inside :host, with combinators");
assert_valid(true, "{}(:hover, :active)", null, "Pseudo-classes inside");
assert_valid(true, "{}(div):hover", null, "Pseudo-classes after");
assert_valid(true, "{}(div)::before", null, "Pseudo-elements after");
assert_valid(false, "{}(::before)", null, "Pseudo-elements inside");
assert_valid(true, "{}(div) + bar", null, "Combinators after");
assert_valid(true, "::part(foo){}(:hover)", null, "After part with simple pseudo-class");
assert_valid(false, "::part(foo){}([attr='value'])", null, "After part with invalid selector after");
assert_valid(true, ":not({}(div))", null, "Nested inside :not, without combinators");
assert_valid(true, ":not({}(div .foo))", null, "Nested inside :not, with combinators");
// This should be invalid even with the forgiving behavior because
// `<any-value>` doesn't allow bad tokens:
// https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value
test_invalid_selector(`:is(# C4єанйтж╕/┘ГЁжЮХєа▓┐ЁЭБМєаСеЁЭЖА%=[ямм0)`);
</script>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Selectors: The negation pseudo-class</title>
<link rel="help" href="https://drafts.csswg.org/selectors-3/#negation">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
<script>
test_valid_selector('button:not([disabled])');
test_valid_selector('*:not(foo)',
['*:not(foo)', ':not(foo)']);
test_valid_selector(':not(:link):not(:visited)');
test_valid_selector('*|*:not(*)', ':not(*)');
test_valid_selector(':not(:hover)');
test_valid_selector(':not(*|*)', ':not(*)');
test_valid_selector('foo:not(bar)');
test_valid_selector(':not(:not(foo))');
test_valid_selector(':not(.a .b)');
test_valid_selector(':not(.a + .b)');
test_valid_selector(':not(.a .b ~ c)');
test_valid_selector(':not(span.a, div.b)');
test_valid_selector(':not(.a .b ~ c, .d .e)');
test_valid_selector(':not(:host)');
test_valid_selector(':not(:host(.a))');
test_valid_selector(':host(:not(.a))');
test_valid_selector(':not(:host(:not(.a)))');
test_valid_selector(':not([disabled][selected])', ':not([disabled][selected])');
test_valid_selector(':not([disabled],[selected])', ':not([disabled], [selected])');
test_invalid_selector(':not()');
test_invalid_selector(':not(:not())');
test_invalid_selector(':not(::before)');
test_invalid_selector(':not(:unknownpseudo)');
test_invalid_selector(':not(.a, :unknownpseudo)');
test_invalid_selector(':not(:unknownpseudo, .a)');
test_invalid_selector(':host(:not(.a .b))');
</script>