chromium/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-nesting-parent-containing-complex.html

<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Selector Invalidation: :has() with nesting parent containing complex selector</title>
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
  .anchor { background-color: white; }

  .ancestor .descendant {
    .anchor:has(&) { background-color: blue; }
  }

  .ancestor .child {
    .anchor:has(> &) { background-color: lightblue; }
  }

  .ancestor_prev ~ div .descendant {
    .anchor:has(&) { background-color: yellow; }
  }

  .ancestor_prev ~ div.ancestor .descendant {
    .anchor:has(&) { background-color: yellowgreen; }
  }

  .prev ~ .indirect_next {
    .anchor:has(~ &) { background-color: green; }
  }

  .prev ~ .direct_next {
    .anchor:has(+ &) { background-color: lightgreen; }
  }
</style>
<div><div id="grand_parent1">
  <div id="parent1">
    <div id="anchor1" class="anchor">
      <div><div class="descendant"></div></div>
    </div>
  </div>
</div></div>
<div><div id="grand_parent2">
  <div id="parent2">
    <div id="anchor2" class="anchor">
      <div class="child"></div>
    </div>
  </div>
</div></div>
<div><div id="grand_parent_indirect_prev3"></div>
     <div id="grand_parent_direct_prev3"></div>
     <div id="grand_parent3">
       <div id="parent_indirect_prev3"></div>
       <div id="parent_direct_prev3"></div>
       <div id="parent3">
         <div id="anchor_indirect_prev3"></div>
         <div id="anchor_direct_prev3"></div>
         <div id="anchor3" class="anchor">
           <div><div class="descendant"></div></div>
         </div>
       </div>
</div></div>
<div><div id="indirect_prev4"></div>
     <div id="direct_prev4"></div>
     <div id="anchor4" class="anchor"></div>
     <div></div><div class="indirect_next">
</div></div>
<div><div id="indirect_prev5"></div>
     <div id="direct_prev5"></div>
     <div id="anchor5" class="anchor"></div>
     <div class="direct_next">
</div></div>
<script>
  const white = "rgb(255, 255, 255)";
  const blue = "rgb(0, 0, 255)";
  const lightblue = "rgb(173, 216, 230)";
  const yellow = "rgb(255, 255, 0)";
  const yellowgreen = "rgb(154, 205, 50)";
  const green = "rgb(0, 128, 0)";
  const lightgreen = "rgb(144, 238, 144)";

  function bg_color(element, color, message) {
    promise_test(async () => {
      assert_equals(getComputedStyle(element)['background-color'], color);
    }, message);
  }

  function add_class_and_check_bg_color(
      element_to_add, class_name, has_anchor, color) {
    promise_test(async () => {
      element_to_add.classList.add(class_name);
      assert_equals(getComputedStyle(has_anchor)['background-color'], color);
    }, `#${has_anchor.id} becomes ${color} after adding .${class_name} to #${element_to_add.id}`);
  }

  function remove_class_and_check_bg_color(
      element_to_remove, class_name, has_anchor, color) {
    promise_test(async () => {
      element_to_remove.classList.remove(class_name);
      assert_equals(getComputedStyle(has_anchor)['background-color'], color);
    }, `#${has_anchor.id} becomes ${color} after removing .${class_name} from #${element_to_remove.id}`);
  }

  bg_color(anchor1, white, "#anchor1 initially white");
  add_class_and_check_bg_color(grand_parent1, "ancestor", anchor1, blue);
  remove_class_and_check_bg_color(grand_parent1, "ancestor", anchor1, white);
  add_class_and_check_bg_color(parent1, "ancestor", anchor1, blue);
  remove_class_and_check_bg_color(parent1, "ancestor", anchor1, white);

  bg_color(anchor2, white, "#anchor2 initially white");
  add_class_and_check_bg_color(grand_parent2, "ancestor", anchor2, lightblue);
  remove_class_and_check_bg_color(grand_parent2, "ancestor", anchor2, white);
  add_class_and_check_bg_color(parent2, "ancestor", anchor2, lightblue);
  remove_class_and_check_bg_color(parent2, "ancestor", anchor2, white);

  bg_color(anchor3, white, "#anchor3 initially white");
  add_class_and_check_bg_color(grand_parent_indirect_prev3, "ancestor_prev",
                               anchor3, yellow);
  add_class_and_check_bg_color(grand_parent3, "ancestor", anchor3, yellowgreen);
  remove_class_and_check_bg_color(grand_parent3, "ancestor", anchor3, yellow);
  remove_class_and_check_bg_color(grand_parent_indirect_prev3, "ancestor_prev",
                                  anchor3, white);
  add_class_and_check_bg_color(grand_parent_direct_prev3, "ancestor_prev",
                               anchor3, yellow);
  remove_class_and_check_bg_color(grand_parent_direct_prev3, "ancestor_prev",
                                  anchor3, white);
  add_class_and_check_bg_color(parent_indirect_prev3, "ancestor_prev",
                               anchor3, yellow);
  add_class_and_check_bg_color(parent3, "ancestor", anchor3, yellowgreen);
  remove_class_and_check_bg_color(parent3, "ancestor", anchor3, yellow);
  remove_class_and_check_bg_color(parent_indirect_prev3, "ancestor_prev",
                                  anchor3, white);
  add_class_and_check_bg_color(parent_direct_prev3, "ancestor_prev",
                               anchor3, yellow);
  remove_class_and_check_bg_color(parent_direct_prev3, "ancestor_prev",
                                  anchor3, white);
  add_class_and_check_bg_color(anchor_indirect_prev3, "ancestor_prev",
                               anchor3, yellow);
  remove_class_and_check_bg_color(anchor_indirect_prev3, "ancestor_prev",
                                  anchor3, white);
  add_class_and_check_bg_color(anchor_direct_prev3, "ancestor_prev",
                               anchor3, yellow);
  remove_class_and_check_bg_color(anchor_direct_prev3, "ancestor_prev",
                                  anchor3, white);

  bg_color(anchor4, white, "#anchor4 initially white");
  add_class_and_check_bg_color(indirect_prev4, "prev", anchor4, green);
  remove_class_and_check_bg_color(indirect_prev4, "prev", anchor4, white);
  add_class_and_check_bg_color(direct_prev4, "prev", anchor4, green);
  remove_class_and_check_bg_color(direct_prev4, "prev", anchor4, white);

  bg_color(anchor5, white, "#anchor5 initially white");
  add_class_and_check_bg_color(indirect_prev5, "prev", anchor5, lightgreen);
  remove_class_and_check_bg_color(indirect_prev5, "prev", anchor5, white);
  add_class_and_check_bg_color(direct_prev5, "prev", anchor5, lightgreen);
  remove_class_and_check_bg_color(direct_prev5, "prev", anchor5, white);
</script>