[@scope] Improve testing for :not() and the '&' pseudo-class

These tests were part of an abandoned effort to rework how
rule features are handled for @scope. In our current implementation,
tests with :not(:scope) aren't very interesting, but since they
were relevant in my alternative approach, they could be relevant
for other vendors.

Bug: 1280240
Change-Id: I9cbbf96fe6ff47d791a6eff43a1941a80cebe768
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4660701
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1165263}
diff --git a/css/css-cascade/scope-invalidation.html b/css/css-cascade/scope-invalidation.html
index 39d4a02..d41df57 100644
--- a/css/css-cascade/scope-invalidation.html
+++ b/css/css-cascade/scope-invalidation.html
@@ -425,3 +425,140 @@
   assert_not_green(c);
 }, 'Element becoming root via + combinator');
 </script>
+
+<template>
+  <style>
+    @scope (.root) {
+      :not(:scope) { background-color:green; }
+    }
+  </style>
+  <div class=root>
+    <div class=a></div>
+    <div class=b></div>
+    <div class=c></div>
+  </div>
+  <div class=a></div>
+</template>
+<script>
+test_scope_invalidation(document.currentScript, () => {
+  let root = main.querySelector('.root');
+  let a1 = main.querySelector('.root > .a');
+  let b = main.querySelector('.root > .b');
+  let c = main.querySelector('.root > .c');
+  let a2 = main.querySelector('main > .a');
+
+  assert_not_green(root);
+  assert_green(a1);
+  assert_green(b);
+  assert_green(c);
+  assert_not_green(a2);
+
+  root.classList.remove('root');
+  assert_not_green(root);
+  assert_not_green(a1);
+  assert_not_green(b);
+  assert_not_green(c);
+  assert_not_green(a2);
+
+  root.classList.add('root');
+  assert_not_green(root);
+  assert_green(a1);
+  assert_green(b);
+  assert_green(c);
+  assert_not_green(a2);
+}, ':not(scope) in subject');
+</script>
+
+<template>
+  <style>
+    @scope (.root) {
+      :not(:scope) > .a { background-color:green; }
+    }
+  </style>
+  <div class=root>
+    <div class=a></div>
+    <div>
+      <div class=a></div>
+    </div>
+  </div>
+</template>
+<script>
+test_scope_invalidation(document.currentScript, () => {
+  let root = main.querySelector('.root');
+  let outer_a = main.querySelector('.root > .a');
+  let inner_a = main.querySelector('.root > div > .a');
+
+  assert_not_green(outer_a);
+  assert_green(inner_a);
+
+  root.classList.remove('root');
+  assert_not_green(outer_a);
+  assert_not_green(inner_a);
+
+  root.classList.add('root');
+  assert_not_green(outer_a);
+  assert_green(inner_a);
+}, ':not(scope) in ancestor');
+</script>
+
+<template>
+  <style>
+    @scope (.root) to (:not(:scope)) {
+      :is(div, :scope) { background-color: green; }
+    }
+  </style>
+  <div class=root>
+    <div class=a></div>
+  </div>
+</template>
+<script>
+test_scope_invalidation(document.currentScript, () => {
+  let root = main.querySelector('.root');
+  let a = main.querySelector('.root > .a');
+
+  assert_green(root);
+  assert_not_green(a);
+
+  root.classList.remove('root');
+  assert_not_green(root);
+  assert_not_green(a);
+
+  root.classList.add('root');
+  assert_green(root);
+  assert_not_green(a);
+}, ':not(scope) in limit subject');
+</script>
+
+<template>
+  <style>
+    @scope (.root) to (:not(:scope) > .a) {
+      :is(div, :scope) { background-color: green; }
+    }
+  </style>
+  <div class=root>
+    <div class=a>
+      <div class=a></div>
+    </div>
+  </div>
+</template>
+<script>
+test_scope_invalidation(document.currentScript, () => {
+  let root = main.querySelector('.root');
+  let outer_a = main.querySelector('.root > .a');
+  let inner_a = main.querySelector('.root > .a > .a');
+
+  assert_green(root);
+  assert_green(outer_a);
+  assert_not_green(inner_a);
+
+  root.classList.remove('root');
+  assert_not_green(root);
+  assert_not_green(outer_a);
+  assert_not_green(inner_a);
+
+  root.classList.add('root');
+  assert_green(root);
+  assert_green(outer_a);
+  assert_not_green(inner_a);
+}, ':not(scope) in limit ancestor');
+</script>