Bug 1769507 [wpt PR 34067] - Add wpt tests for tree-structural pseudo classes inside :has(), a=testonly
authorByungwoo Lee <blee@igalia.com>
Wed, 18 May 2022 03:32:35 +0000
changeset 618462 f56bcb2d0260c786dff0f7c74db4c95c9935e891
parent 618461 86ba865ee7171fab02d49395b9a6090d8760633e
child 618463 740b96fa48489814e36a551517d4119c2650221a
push id163295
push userwptsync@mozilla.com
push dateSun, 22 May 2022 08:42:45 +0000
treeherderautoland@28d8297085fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1769507, 34067, 669058, 3650110, 1003725
milestone102.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1769507 [wpt PR 34067] - Add wpt tests for tree-structural pseudo classes inside :has(), a=testonly Automatic update from web-platform-tests Add wpt tests for tree-structural pseudo classes inside :has() Add wpt tests to check invalidation with tree-structural pseudo classes inside :has(). - ':empty' pseudo-class - Child-indexed Pseudo-classes - Typed Child-indexed Pseudo-classes Bug: 669058 Change-Id: I806ccaaa6f9660bd0119c5e2b340928d154c47f5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3650110 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Byungwoo Lee <blee@igalia.com> Cr-Commit-Position: refs/heads/main@{#1003725} -- wpt-commits: 7a2489a00877a454082d618f19d52a66b11bd4b9 wpt-pr: 34067
testing/web-platform/tests/css/selectors/invalidation/child-indexed-pseudo-classes-in-has.html
testing/web-platform/tests/css/selectors/invalidation/empty-pseudo-in-has.html
testing/web-platform/tests/css/selectors/invalidation/typed-child-indexed-pseudo-classes-in-has.html
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/invalidation/child-indexed-pseudo-classes-in-has.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Selectors Invalidation: child-indexed pseudo classes in :has() argument</title>
+<link rel="author" title="Byungwoo Lee" href="blee@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #container ~ div { color: grey }
+  #container:has(:only-child) ~ #only_child { color: red }
+  #container:has(.orange:first-child) ~ #first_child { color: orange }
+  #container:has(.yellow:first-child) ~ #first_child { color: yellow }
+  #container:has(.green:first-child) ~ #first_child { color: green }
+  #container:has(.orange:last-child) ~ #last_child { color: orange }
+  #container:has(.yellow:last-child) ~ #last_child { color: yellow }
+  #container:has(.green:last-child) ~ #last_child { color: green }
+  #container:has(.orange:nth-child(3n)) ~ #nth_child_3n { color: orange }
+  #container:has(.yellow:nth-child(3n)) ~ #nth_child_3n { color: yellow }
+  #container:has(.green:nth-child(3n)) ~ #nth_child_3n { color: green }
+  #container:has(.orange:nth-child(3n+1)) ~ #nth_child_3n_1 { color: orange }
+  #container:has(.yellow:nth-child(3n+1)) ~ #nth_child_3n_1 { color: yellow }
+  #container:has(.green:nth-child(3n+1)) ~ #nth_child_3n_1 { color: green }
+  #container:has(.orange:nth-child(3n+2)) ~ #nth_child_3n_2 { color: orange }
+  #container:has(.yellow:nth-child(3n+2)) ~ #nth_child_3n_2 { color: yellow }
+  #container:has(.green:nth-child(3n+2)) ~ #nth_child_3n_2 { color: green }
+  #container:has(.orange:nth-child(3n)) ~ #nth_child_3n { color: orange }
+  #container:has(.yellow:nth-child(3n)) ~ #nth_child_3n { color: yellow }
+  #container:has(.green:nth-child(3n)) ~ #nth_child_3n { color: green }
+</style>
+<div id="container">
+</div>
+<div id="only_child"></div>
+<div id="first_child"></div>
+<div id="last_child"></div>
+<div id="nth_child_3n_1"></div>
+<div id="nth_child_3n_2"></div>
+<div id="nth_child_3n"></div>
+<script>
+const grey = "rgb(128, 128, 128)";
+const red = "rgb(255, 0, 0)";
+const orange = "rgb(255, 165, 0)";
+const yellow = "rgb(255, 255, 0)";
+const green = "rgb(0, 128, 0)";
+
+function testColors(test_name,
+                    only_child_color,
+                    first_child_color,
+                    last_child_color,
+                    nth_child_3n_1_color,
+                    nth_child_3n_2_color,
+                    nth_child_3n_color) {
+  test(function() {
+      assert_equals(getComputedStyle(only_child).color, only_child_color);
+  }, test_name + ": #only_child");
+  test(function() {
+      assert_equals(getComputedStyle(first_child).color, first_child_color);
+  }, test_name + ": #first_child");
+  test(function() {
+      assert_equals(getComputedStyle(last_child).color, last_child_color);
+  }, test_name + ": #last_child");
+  test(function() {
+      assert_equals(getComputedStyle(nth_child_3n_1).color, nth_child_3n_1_color);
+  }, test_name + ": #nth_child_3n_1");
+  test(function() {
+      assert_equals(getComputedStyle(nth_child_3n_2).color, nth_child_3n_2_color);
+  }, test_name + ": #nth_child_3n_2");
+  test(function() {
+      assert_equals(getComputedStyle(nth_child_3n).color, nth_child_3n_color);
+  }, test_name + ": #nth_child_3n");
+}
+
+testColors("Initial colors", grey, grey, grey, grey, grey, grey);
+
+let div1 = document.createElement("div");
+div1.id = "div1";
+div1.classList.add("green");
+container.insertBefore(div1, container.firstChild);
+testColors("Prepend #div1.green", red, green, green, green, grey, grey);
+
+let div2 = document.createElement("div");
+div2.id = "div2";
+div2.classList.add("yellow");
+container.insertBefore(div2, container.firstChild);
+testColors("Prepend #div2.yellow", grey, yellow, green, yellow, green, grey);
+
+let div3 = document.createElement("div");
+div3.id = "div3";
+div3.classList.add("orange");
+container.insertBefore(div3, container.firstChild);
+testColors("Prepend #div3.orange", grey, orange, green, orange, yellow, green);
+
+let div4 = document.createElement("div");
+div4.id = "div4";
+container.insertBefore(div4, container.firstChild);
+testColors("Prepend #div4", grey, grey, green, green, orange, yellow);
+
+let div5 = document.createElement("div");
+div5.id = "div5";
+container.insertBefore(div5, container.firstChild);
+testColors("Prepend #div5", grey, grey, green, yellow, green, orange);
+
+div1.remove();
+testColors("Remove #div1", grey, grey, yellow, yellow, grey, orange);
+
+div2.remove();
+testColors("Remove #div2", grey, grey, orange, grey, grey, orange);
+
+div3.remove();
+testColors("Remove #div3", grey, grey, grey, grey, grey, grey);
+
+div4.remove();
+testColors("Remove #div4", red, grey, grey, grey, grey, grey);
+
+div5.remove();
+testColors("Remove #div5", grey, grey, grey, grey, grey, grey);
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/invalidation/empty-pseudo-in-has.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Selectors Invalidation: :empty in :has() argument</title>
+<link rel="author" title="Byungwoo Lee" href="blee@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #subject { color: red }
+  #subject:has(:empty) { color: green }
+  #subject:has(:not(:empty)) { color: blue }
+</style>
+<div id="subject"></div>
+<script>
+const red = 'rgb(255, 0, 0)';
+const green = 'rgb(0, 128, 0)';
+const blue = 'rgb(0, 0, 255)';
+
+function testColor(test_name, color) {
+  test(function() {
+      assert_equals(getComputedStyle(subject).color, color);
+  }, test_name);
+}
+
+testColor("Empty #subject", red);
+
+let child = document.createElement("div");
+child.id = "child";
+subject.appendChild(child);
+
+testColor("Insert div#child to #subject", green);
+
+child.appendChild(document.createElement("div"));
+
+testColor("Insert div to div.#child", blue);
+
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/invalidation/typed-child-indexed-pseudo-classes-in-has.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Selectors Invalidation: typed child-indexed pseudo classes in :has() argument</title>
+<link rel="author" title="Byungwoo Lee" href="blee@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #container ~ div { color: grey }
+  #container:has(div:only-of-type) ~ #only_of_type { color: red }
+  #container:has(div.orange:first-of-type) ~ #first_of_type { color: orange }
+  #container:has(div.yellow:first-of-type) ~ #first_of_type { color: yellow }
+  #container:has(div.green:first-of-type) ~ #first_of_type { color: green }
+  #container:has(div.orange:last-of-type) ~ #last_of_type { color: orange }
+  #container:has(div.yellow:last-of-type) ~ #last_of_type { color: yellow }
+  #container:has(div.green:last-of-type) ~ #last_of_type { color: green }
+  #container:has(div.orange:nth-of-type(3n+1)) ~ #nth_of_type_3n_1 { color: orange }
+  #container:has(div.yellow:nth-of-type(3n+1)) ~ #nth_of_type_3n_1 { color: yellow }
+  #container:has(div.green:nth-of-type(3n+1)) ~ #nth_of_type_3n_1 { color: green }
+  #container:has(div.orange:nth-of-type(3n+2)) ~ #nth_of_type_3n_2 { color: orange }
+  #container:has(div.yellow:nth-of-type(3n+2)) ~ #nth_of_type_3n_2 { color: yellow }
+  #container:has(div.green:nth-of-type(3n+2)) ~ #nth_of_type_3n_2 { color: green }
+  #container:has(div.orange:nth-of-type(3n)) ~ #nth_of_type_3n { color: orange }
+  #container:has(div.yellow:nth-of-type(3n)) ~ #nth_of_type_3n { color: yellow }
+  #container:has(div.green:nth-of-type(3n)) ~ #nth_of_type_3n { color: green }
+</style>
+<div id="container">
+</div>
+<div id="only_of_type"></div>
+<div id="first_of_type"></div>
+<div id="last_of_type"></div>
+<div id="nth_of_type_3n_1"></div>
+<div id="nth_of_type_3n_2"></div>
+<div id="nth_of_type_3n"></div>
+<script>
+const grey = "rgb(128, 128, 128)";
+const red = "rgb(255, 0, 0)";
+const orange = "rgb(255, 165, 0)";
+const yellow = "rgb(255, 255, 0)";
+const green = "rgb(0, 128, 0)";
+
+function testColors(test_name,
+                    only_of_type_color,
+                    first_of_type_color,
+                    last_of_type_color,
+                    nth_of_type_3n_1_color,
+                    nth_of_type_3n_2_color,
+                    nth_of_type_3n_color) {
+  test(function() {
+      assert_equals(getComputedStyle(only_of_type).color, only_of_type_color);
+  }, test_name + ": #only_of_type");
+  test(function() {
+      assert_equals(getComputedStyle(first_of_type).color, first_of_type_color);
+  }, test_name + ": #first_of_type");
+  test(function() {
+      assert_equals(getComputedStyle(last_of_type).color, last_of_type_color);
+  }, test_name + ": #last_of_type");
+  test(function() {
+      assert_equals(getComputedStyle(nth_of_type_3n_1).color, nth_of_type_3n_1_color);
+  }, test_name + ": #nth_of_type_3n_1");
+  test(function() {
+      assert_equals(getComputedStyle(nth_of_type_3n_2).color, nth_of_type_3n_2_color);
+  }, test_name + ": #nth_of_type_3n_2");
+  test(function() {
+      assert_equals(getComputedStyle(nth_of_type_3n).color, nth_of_type_3n_color);
+  }, test_name + ": #nth_of_type_3n");
+}
+
+testColors("Initial colors", grey, grey, grey, grey, grey, grey);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (1)", grey, grey, grey, grey, grey, grey);
+
+let div1 = document.createElement("div");
+div1.id = "div1";
+div1.classList.add("green");
+container.insertBefore(div1, container.firstChild);
+testColors("Prepend #div1.green", red, green, green, green, grey, grey);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (2)", red, green, green, green, grey, grey);
+
+let div2 = document.createElement("div");
+div2.id = "div2";
+div2.classList.add("yellow");
+container.insertBefore(div2, container.firstChild);
+testColors("Prepend #div2.yellow", grey, yellow, green, yellow, green, grey);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (3)", grey, yellow, green, yellow, green, grey);
+
+let div3 = document.createElement("div");
+div3.id = "div3";
+div3.classList.add("orange");
+container.insertBefore(div3, container.firstChild);
+testColors("Prepend #div3.orange", grey, orange, green, orange, yellow, green);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (4)", grey, orange, green, orange, yellow, green);
+
+let div4 = document.createElement("div");
+div4.id = "div4";
+container.insertBefore(div4, container.firstChild);
+testColors("Prepend #div4", grey, grey, green, green, orange, yellow);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (5)", grey, grey, green, green, orange, yellow);
+
+let div5 = document.createElement("div");
+div5.id = "div5";
+container.insertBefore(div5, container.firstChild);
+testColors("Prepend #div5", grey, grey, green, yellow, green, orange);
+
+container.insertBefore(document.createElement("span"), container.firstChild);
+testColors("Prepend span (6)", grey, grey, green, yellow, green, orange);
+
+div1.remove();
+testColors("Remove #div1", grey, grey, yellow, yellow, grey, orange);
+
+div2.remove();
+testColors("Remove #div2", grey, grey, orange, grey, grey, orange);
+
+div3.remove();
+testColors("Remove #div3", grey, grey, grey, grey, grey, grey);
+
+div4.remove();
+testColors("Remove #div4", red, grey, grey, grey, grey, grey);
+
+div5.remove();
+testColors("Remove #div5", grey, grey, grey, grey, grey, grey);
+</script>
\ No newline at end of file