mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 15:10:19 +00:00
LibWeb: Import a bunch of :has() selector tests from WPT
This commit is contained in:
parent
9e080e197c
commit
a640fcc693
Notes:
github-actions[bot]
2024-10-27 12:34:43 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/a640fcc693c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1997
44 changed files with 4493 additions and 0 deletions
|
@ -0,0 +1,24 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 13 tests
|
||||
|
||||
12 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessagePass :has(:scope) matches expected elements on scope1
|
||||
Pass :has(:scope .c) matches expected elements on scope1
|
||||
Pass :has(.a :scope) matches expected elements on scope1
|
||||
Fail .a:has(:scope) .c matches expected elements on scope1 assert_equals: expected "d02,d03" but got ""
|
||||
Pass .a:has(:scope) .c and :is(.a :scope .c) returns same elements on scope1
|
||||
Pass .a:has(:scope) .c matches expected elements on scope2
|
||||
Pass .a:has(:scope) .c and :is(.a :scope .c) returns same elements on scope2
|
||||
Pass .c:has(:is(:scope .d)) matches expected elements on scope1
|
||||
Pass .c:has(:is(:scope .d)) and :scope .c:has(.d) returns same elements on scope1
|
||||
Pass .c:has(:is(:scope .d)) and .c:has(.d) returns same elements on scope1
|
||||
Pass .c:has(:is(:scope .d)) matches expected elements on scope2
|
||||
Pass .c:has(:is(:scope .d)) and :scope .c:has(.d) returns same elements on scope2
|
||||
Pass .c:has(:is(:scope .d)) and .c:has(.d) returns same elements on scope2
|
|
@ -0,0 +1,28 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 18 tests
|
||||
|
||||
18 Pass
|
||||
Details
|
||||
Result Test Name MessagePass :has(#a) matches expected elements
|
||||
Pass :has(.ancestor) matches expected elements
|
||||
Pass :has(.target) matches expected elements
|
||||
Pass :has(.descendant) matches expected elements
|
||||
Pass .parent:has(.target) matches expected elements
|
||||
Pass :has(.sibling ~ .target) matches expected elements
|
||||
Pass .parent:has(.sibling ~ .target) matches expected elements
|
||||
Pass :has(:is(.target ~ .sibling .descendant)) matches expected elements
|
||||
Pass .parent:has(:is(.target ~ .sibling .descendant)) matches expected elements
|
||||
Pass .sibling:has(.descendant) ~ .target matches expected elements
|
||||
Pass :has(> .parent) matches expected elements
|
||||
Pass :has(> .target) matches expected elements
|
||||
Pass :has(> .parent, > .target) matches expected elements
|
||||
Pass :has(+ #h) matches expected elements
|
||||
Pass .parent:has(~ #h) matches expected elements
|
||||
Pass .sibling:has(.descendant) matches expected element
|
||||
Pass closest(.ancestor:has(.descendant)) returns expected element
|
||||
Pass :has(.target ~ .sibling .descendant) matches expectedly
|
|
@ -0,0 +1,22 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 12 tests
|
||||
|
||||
12 Pass
|
||||
Details
|
||||
Result Test Name MessagePass :has(child) matches expectedly
|
||||
Pass :has(> child) matches expectedly
|
||||
Pass :has(descendant) matches expectedly
|
||||
Pass :has(> descendant) matches expectedly
|
||||
Pass :has(~ direct_sibling) matches expectedly
|
||||
Pass :has(+ direct_sibling) matches expectedly
|
||||
Pass :has(~ indirect_sibling) matches expectedly
|
||||
Pass :has(+ indirect_sibling) matches expectedly
|
||||
Pass :has(*) matches expectedly
|
||||
Pass :has(> *) matches expectedly
|
||||
Pass :has(~ *) matches expectedly
|
||||
Pass :has(+ *) matches expectedly
|
|
@ -0,0 +1,45 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 35 tests
|
||||
|
||||
35 Pass
|
||||
Details
|
||||
Result Test Name MessagePass .x:has(.a) matches expected elements
|
||||
Pass .x:has(.a > .b) matches expected elements
|
||||
Pass .x:has(.a .b) matches expected elements
|
||||
Pass .x:has(.a + .b) matches expected elements
|
||||
Pass .x:has(.a ~ .b) matches expected elements
|
||||
Pass .x:has(> .a) matches expected elements
|
||||
Pass .x:has(> .a > .b) matches expected elements
|
||||
Pass .x:has(> .a .b) matches expected elements
|
||||
Pass .x:has(> .a + .b) matches expected elements
|
||||
Pass .x:has(> .a ~ .b) matches expected elements
|
||||
Pass .x:has(+ .a) matches expected elements
|
||||
Pass .x:has(+ .a > .b) matches expected elements
|
||||
Pass .x:has(+ .a .b) matches expected elements
|
||||
Pass .x:has(+ .a + .b) matches expected elements
|
||||
Pass .x:has(+ .a ~ .b) matches expected elements
|
||||
Pass .x:has(~ .a) matches expected elements
|
||||
Pass .x:has(~ .a > .b) matches expected elements
|
||||
Pass .x:has(~ .a .b) matches expected elements
|
||||
Pass .x:has(~ .a + .b) matches expected elements
|
||||
Pass .x:has(~ .a + .b > .c) matches expected elements
|
||||
Pass .x:has(~ .a + .b .c) matches expected elements
|
||||
Pass .x:has(.d .e) matches expected elements
|
||||
Pass .x:has(.d .e) .f matches expected elements
|
||||
Pass .x:has(> .d) matches expected elements
|
||||
Pass .x:has(> .d) .f matches expected elements
|
||||
Pass .x:has(~ .d ~ .e) matches expected elements
|
||||
Pass .x:has(~ .d ~ .e) ~ .f matches expected elements
|
||||
Pass .x:has(+ .d ~ .e) matches expected elements
|
||||
Pass .x:has(+ .d ~ .e) ~ .f matches expected elements
|
||||
Pass .y:has(> .g .h) matches expected elements
|
||||
Pass .y:has(.g .h) matches expected elements
|
||||
Pass .y:has(> .g .h) .i matches expected elements
|
||||
Pass .y:has(.g .h) .i matches expected elements
|
||||
Pass .d .x:has(.e) matches expected elements
|
||||
Pass .d ~ .x:has(~ .e) matches expected elements
|
|
@ -0,0 +1 @@
|
|||
PASS
|
|
@ -0,0 +1,18 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 8 tests
|
||||
|
||||
8 Fail
|
||||
Details
|
||||
Result Test Name MessageFail :has(#foo) wins over :has(.foo) assert_equals: expected "PASS" but got ""
|
||||
Fail :has(span#foo) wins over :has(#foo) assert_equals: expected "PASS" but got ""
|
||||
Fail :has(.bar, #foo) has same specificity as :has(#foo, .bar) assert_equals: expected "PASS" but got ""
|
||||
Fail :has(.bar, #foo) wins over :has(.foo, .bar) assert_equals: expected "PASS" but got ""
|
||||
Fail :has(span + span) wins over :has(span) assert_equals: expected "PASS" but got ""
|
||||
Fail :has(span, li, p) wins over :has(span, lo, p) assert_equals: expected "PASS" but got ""
|
||||
Fail latter .baz wins over :has(.foo) assert_equals: expected "PASS" but got ""
|
||||
Fail latter :has(.foo) wins over .baz assert_equals: expected "PASS" but got ""
|
|
@ -0,0 +1,22 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 12 tests
|
||||
|
||||
12 Pass
|
||||
Details
|
||||
Result Test Name MessagePass add .test to trigger1 - check subject1_1
|
||||
Pass add .test to trigger1 - check subject1_2
|
||||
Pass remove .test from trigger1 - check subject1_1
|
||||
Pass remove .test from trigger1 - check subject1_2
|
||||
Pass add .test to trigger2 - check subject2_1
|
||||
Pass add .test to trigger2 - check subject2_2
|
||||
Pass remove .test from trigger2 - check subject2_1
|
||||
Pass remove .test from trigger2 - check subject2_2
|
||||
Pass add .test to trigger3 - check subject3_1
|
||||
Pass add .test to trigger3 - check subject3_2
|
||||
Pass remove .test from trigger3 - check subject3_1
|
||||
Pass remove .test from trigger3 - check subject3_2
|
|
@ -0,0 +1,305 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 295 tests
|
||||
|
||||
295 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass add .test to previous_sibling
|
||||
Pass remove .test from previous_sibling
|
||||
Pass add .test to previous_sibling_child
|
||||
Pass remove .test from previous_sibling_child
|
||||
Pass add .test to previous_sibling_descendant
|
||||
Pass remove .test from previous_sibling_descendant
|
||||
Pass add .test to subject
|
||||
Pass remove .test from subject
|
||||
Pass add .test to next_sibling
|
||||
Pass remove .test from next_sibling
|
||||
Pass add .test to next_sibling_child
|
||||
Pass remove .test from next_sibling_child
|
||||
Pass add .test to next_sibling_descendant
|
||||
Pass remove .test from next_sibling_descendant
|
||||
Pass insert element div.test before previous_sibling
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling
|
||||
Pass remove element div.test before previous_sibling
|
||||
Pass insert element div before previous_sibling
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling
|
||||
Pass remove element div before previous_sibling
|
||||
Pass insert element div[test_attr] before previous_sibling
|
||||
Pass remove element div[test_attr] before previous_sibling
|
||||
Pass insert element div.test before previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling_child
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling_child
|
||||
Pass remove element div.test before previous_sibling_child
|
||||
Pass insert element div before previous_sibling_child
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling_child
|
||||
Pass remove element div before previous_sibling_child
|
||||
Pass insert element div[test_attr] before previous_sibling_child
|
||||
Pass remove element div[test_attr] before previous_sibling_child
|
||||
Pass insert element div.test before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling_descendant
|
||||
Pass remove element div.test before previous_sibling_descendant
|
||||
Pass insert element div before previous_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling_descendant
|
||||
Pass remove element div before previous_sibling_descendant
|
||||
Pass insert element div[test_attr] before previous_sibling_descendant
|
||||
Pass remove element div[test_attr] before previous_sibling_descendant
|
||||
Pass insert element div.test before subject
|
||||
Pass remove the class 'test' from the element inserted before subject
|
||||
Pass add the class 'test' again to the element inserted before subject
|
||||
Pass remove element div.test before subject
|
||||
Pass insert element div before subject
|
||||
Pass add the class 'test' to the element inserted again before subject
|
||||
Pass remove the class 'test' from the element inserted again before subject
|
||||
Pass remove element div before subject
|
||||
Pass insert element div[test_attr] before subject
|
||||
Pass remove element div[test_attr] before subject
|
||||
Pass insert element div.test before next_sibling
|
||||
Pass remove the class 'test' from the element inserted before next_sibling
|
||||
Pass add the class 'test' again to the element inserted before next_sibling
|
||||
Pass remove element div.test before next_sibling
|
||||
Pass insert element div before next_sibling
|
||||
Pass add the class 'test' to the element inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling
|
||||
Pass remove element div before next_sibling
|
||||
Pass insert element div[test_attr] before next_sibling
|
||||
Pass remove element div[test_attr] before next_sibling
|
||||
Pass insert element div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_child
|
||||
Pass remove element div.test before next_sibling_child
|
||||
Pass insert element div before next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_child
|
||||
Pass remove element div before next_sibling_child
|
||||
Pass insert element div[test_attr] before next_sibling_child
|
||||
Pass remove element div[test_attr] before next_sibling_child
|
||||
Pass insert element div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_descendant
|
||||
Pass remove element div.test before next_sibling_descendant
|
||||
Pass insert element div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_descendant
|
||||
Pass remove element div before next_sibling_descendant
|
||||
Pass insert element div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div[test_attr] before next_sibling_descendant
|
||||
Pass insert element div.test after previous_sibling
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling
|
||||
Pass remove element div.test after previous_sibling
|
||||
Pass insert element div after previous_sibling
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling
|
||||
Pass remove element div after previous_sibling
|
||||
Pass insert element div[test_attr] after previous_sibling
|
||||
Pass remove element div[test_attr] after previous_sibling
|
||||
Pass insert element div.test after previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling_child
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling_child
|
||||
Pass remove element div.test after previous_sibling_child
|
||||
Pass insert element div after previous_sibling_child
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling_child
|
||||
Pass remove element div after previous_sibling_child
|
||||
Pass insert element div[test_attr] after previous_sibling_child
|
||||
Pass remove element div[test_attr] after previous_sibling_child
|
||||
Pass insert element div.test after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling_descendant
|
||||
Pass remove element div.test after previous_sibling_descendant
|
||||
Pass insert element div after previous_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling_descendant
|
||||
Pass remove element div after previous_sibling_descendant
|
||||
Pass insert element div[test_attr] after previous_sibling_descendant
|
||||
Pass remove element div[test_attr] after previous_sibling_descendant
|
||||
Pass insert element div.test after subject
|
||||
Pass remove the class 'test' from the element inserted after subject
|
||||
Pass add the class 'test' again to the element inserted after subject
|
||||
Pass remove element div.test after subject
|
||||
Pass insert element div after subject
|
||||
Pass add the class 'test' to the element inserted again after subject
|
||||
Pass remove the class 'test' from the element inserted again after subject
|
||||
Pass remove element div after subject
|
||||
Pass insert element div[test_attr] after subject
|
||||
Pass remove element div[test_attr] after subject
|
||||
Pass insert element div.test after next_sibling
|
||||
Pass remove the class 'test' from the element inserted after next_sibling
|
||||
Pass add the class 'test' again to the element inserted after next_sibling
|
||||
Pass remove element div.test after next_sibling
|
||||
Pass insert element div after next_sibling
|
||||
Pass add the class 'test' to the element inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling
|
||||
Pass remove element div after next_sibling
|
||||
Pass insert element div[test_attr] after next_sibling
|
||||
Pass remove element div[test_attr] after next_sibling
|
||||
Pass insert element div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_child
|
||||
Pass remove element div.test after next_sibling_child
|
||||
Pass insert element div after next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_child
|
||||
Pass remove element div after next_sibling_child
|
||||
Pass insert element div[test_attr] after next_sibling_child
|
||||
Pass remove element div[test_attr] after next_sibling_child
|
||||
Pass insert element div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_descendant
|
||||
Pass remove element div.test after next_sibling_descendant
|
||||
Pass insert element div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_descendant
|
||||
Pass remove element div after next_sibling_descendant
|
||||
Pass insert element div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div[test_attr] after next_sibling_descendant
|
||||
Pass insert tree div>div.test before previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling
|
||||
Pass remove tree div>div.test before previous_sibling
|
||||
Pass insert tree div>div before previous_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling
|
||||
Pass remove tree div>div before previous_sibling
|
||||
Pass insert element div>div[test_attr] before previous_sibling
|
||||
Pass remove element div>div[test_attr] before previous_sibling
|
||||
Pass insert tree div>div.test before previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling_child
|
||||
Pass remove tree div>div.test before previous_sibling_child
|
||||
Pass insert tree div>div before previous_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling_child
|
||||
Pass remove tree div>div before previous_sibling_child
|
||||
Pass insert element div>div[test_attr] before previous_sibling_child
|
||||
Pass remove element div>div[test_attr] before previous_sibling_child
|
||||
Pass insert tree div>div.test before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling_descendant
|
||||
Pass remove tree div>div.test before previous_sibling_descendant
|
||||
Pass insert tree div>div before previous_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling_descendant
|
||||
Pass remove tree div>div before previous_sibling_descendant
|
||||
Pass insert element div>div[test_attr] before previous_sibling_descendant
|
||||
Pass remove element div>div[test_attr] before previous_sibling_descendant
|
||||
Pass insert tree div>div.test before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject
|
||||
Pass remove tree div>div.test before subject
|
||||
Pass insert tree div>div before subject
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject
|
||||
Pass remove tree div>div before subject
|
||||
Pass insert element div>div[test_attr] before subject
|
||||
Pass remove element div>div[test_attr] before subject
|
||||
Pass insert tree div>div.test before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling
|
||||
Pass remove tree div>div.test before next_sibling
|
||||
Pass insert tree div>div before next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling
|
||||
Pass remove tree div>div before next_sibling
|
||||
Pass insert element div>div[test_attr] before next_sibling
|
||||
Pass remove element div>div[test_attr] before next_sibling
|
||||
Pass insert tree div>div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_child
|
||||
Pass remove tree div>div.test before next_sibling_child
|
||||
Pass insert tree div>div before next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_child
|
||||
Pass remove tree div>div before next_sibling_child
|
||||
Pass insert element div>div[test_attr] before next_sibling_child
|
||||
Pass remove element div>div[test_attr] before next_sibling_child
|
||||
Pass insert tree div>div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_descendant
|
||||
Pass remove tree div>div.test before next_sibling_descendant
|
||||
Pass insert tree div>div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove tree div>div before next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] before next_sibling_descendant
|
||||
Pass insert tree div>div.test after previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling
|
||||
Pass remove tree div>div.test after previous_sibling
|
||||
Pass insert tree div>div after previous_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling
|
||||
Pass remove tree div>div after previous_sibling
|
||||
Pass insert element div>div[test_attr] after previous_sibling
|
||||
Pass remove element div>div[test_attr] after previous_sibling
|
||||
Pass insert tree div>div.test after previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling_child
|
||||
Pass remove tree div>div.test after previous_sibling_child
|
||||
Pass insert tree div>div after previous_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling_child
|
||||
Pass remove tree div>div after previous_sibling_child
|
||||
Pass insert element div>div[test_attr] after previous_sibling_child
|
||||
Pass remove element div>div[test_attr] after previous_sibling_child
|
||||
Pass insert tree div>div.test after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling_descendant
|
||||
Pass remove tree div>div.test after previous_sibling_descendant
|
||||
Pass insert tree div>div after previous_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling_descendant
|
||||
Pass remove tree div>div after previous_sibling_descendant
|
||||
Pass insert element div>div[test_attr] after previous_sibling_descendant
|
||||
Pass remove element div>div[test_attr] after previous_sibling_descendant
|
||||
Pass insert tree div>div.test after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject
|
||||
Pass remove tree div>div.test after subject
|
||||
Pass insert tree div>div after subject
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject
|
||||
Pass remove tree div>div after subject
|
||||
Pass insert element div>div[test_attr] after subject
|
||||
Pass remove element div>div[test_attr] after subject
|
||||
Pass insert tree div>div.test after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling
|
||||
Pass remove tree div>div.test after next_sibling
|
||||
Pass insert tree div>div after next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling
|
||||
Pass remove tree div>div after next_sibling
|
||||
Pass insert element div>div[test_attr] after next_sibling
|
||||
Pass remove element div>div[test_attr] after next_sibling
|
||||
Pass insert tree div>div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_child
|
||||
Pass remove tree div>div.test after next_sibling_child
|
||||
Pass insert tree div>div after next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_child
|
||||
Pass remove tree div>div after next_sibling_child
|
||||
Pass insert element div>div[test_attr] after next_sibling_child
|
||||
Pass remove element div>div[test_attr] after next_sibling_child
|
||||
Pass insert tree div>div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_descendant
|
||||
Pass remove tree div>div.test after next_sibling_descendant
|
||||
Pass insert tree div>div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove tree div>div after next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] after next_sibling_descendant
|
|
@ -0,0 +1,347 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 337 tests
|
||||
|
||||
337 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass add .test to subject_ancestor
|
||||
Pass remove .test from subject_ancestor
|
||||
Pass add .test to subject_parent
|
||||
Pass remove .test from subject_parent
|
||||
Pass add .test to subject
|
||||
Pass remove .test from subject
|
||||
Pass add .test to subject_child
|
||||
Pass remove .test from subject_child
|
||||
Pass add .test to subject_descendant
|
||||
Pass remove .test from subject_descendant
|
||||
Pass add .test to next_sibling
|
||||
Pass remove .test from next_sibling
|
||||
Pass add .test to next_sibling_child
|
||||
Pass remove .test from next_sibling_child
|
||||
Pass add .test to next_sibling_descendant
|
||||
Pass remove .test from next_sibling_descendant
|
||||
Pass insert element div.test before subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted before subject_ancestor
|
||||
Pass add the class 'test' again to the element inserted before subject_ancestor
|
||||
Pass remove element div.test before subject_ancestor
|
||||
Pass insert element div before subject_ancestor
|
||||
Pass add the class 'test' to the element inserted again before subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted again before subject_ancestor
|
||||
Pass remove element div before subject_ancestor
|
||||
Pass insert element div[test_attr] before subject_ancestor
|
||||
Pass remove element div[test_attr] before subject_ancestor
|
||||
Pass insert element div.test before subject_parent
|
||||
Pass remove the class 'test' from the element inserted before subject_parent
|
||||
Pass add the class 'test' again to the element inserted before subject_parent
|
||||
Pass remove element div.test before subject_parent
|
||||
Pass insert element div before subject_parent
|
||||
Pass add the class 'test' to the element inserted again before subject_parent
|
||||
Pass remove the class 'test' from the element inserted again before subject_parent
|
||||
Pass remove element div before subject_parent
|
||||
Pass insert element div[test_attr] before subject_parent
|
||||
Pass remove element div[test_attr] before subject_parent
|
||||
Pass insert element div.test before subject
|
||||
Pass remove the class 'test' from the element inserted before subject
|
||||
Pass add the class 'test' again to the element inserted before subject
|
||||
Pass remove element div.test before subject
|
||||
Pass insert element div before subject
|
||||
Pass add the class 'test' to the element inserted again before subject
|
||||
Pass remove the class 'test' from the element inserted again before subject
|
||||
Pass remove element div before subject
|
||||
Pass insert element div[test_attr] before subject
|
||||
Pass remove element div[test_attr] before subject
|
||||
Pass insert element div.test before subject_child
|
||||
Pass remove the class 'test' from the element inserted before subject_child
|
||||
Pass add the class 'test' again to the element inserted before subject_child
|
||||
Pass remove element div.test before subject_child
|
||||
Pass insert element div before subject_child
|
||||
Pass add the class 'test' to the element inserted again before subject_child
|
||||
Pass remove the class 'test' from the element inserted again before subject_child
|
||||
Pass remove element div before subject_child
|
||||
Pass insert element div[test_attr] before subject_child
|
||||
Pass remove element div[test_attr] before subject_child
|
||||
Pass insert element div.test before subject_descendant
|
||||
Pass remove the class 'test' from the element inserted before subject_descendant
|
||||
Pass add the class 'test' again to the element inserted before subject_descendant
|
||||
Pass remove element div.test before subject_descendant
|
||||
Pass insert element div before subject_descendant
|
||||
Pass add the class 'test' to the element inserted again before subject_descendant
|
||||
Pass remove the class 'test' from the element inserted again before subject_descendant
|
||||
Pass remove element div before subject_descendant
|
||||
Pass insert element div[test_attr] before subject_descendant
|
||||
Pass remove element div[test_attr] before subject_descendant
|
||||
Pass insert element div.test before next_sibling
|
||||
Pass remove the class 'test' from the element inserted before next_sibling
|
||||
Pass add the class 'test' again to the element inserted before next_sibling
|
||||
Pass remove element div.test before next_sibling
|
||||
Pass insert element div before next_sibling
|
||||
Pass add the class 'test' to the element inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling
|
||||
Pass remove element div before next_sibling
|
||||
Pass insert element div[test_attr] before next_sibling
|
||||
Pass remove element div[test_attr] before next_sibling
|
||||
Pass insert element div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_child
|
||||
Pass remove element div.test before next_sibling_child
|
||||
Pass insert element div before next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_child
|
||||
Pass remove element div before next_sibling_child
|
||||
Pass insert element div[test_attr] before next_sibling_child
|
||||
Pass remove element div[test_attr] before next_sibling_child
|
||||
Pass insert element div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_descendant
|
||||
Pass remove element div.test before next_sibling_descendant
|
||||
Pass insert element div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_descendant
|
||||
Pass remove element div before next_sibling_descendant
|
||||
Pass insert element div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div[test_attr] before next_sibling_descendant
|
||||
Pass insert element div.test after subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted after subject_ancestor
|
||||
Pass add the class 'test' again to the element inserted after subject_ancestor
|
||||
Pass remove element div.test after subject_ancestor
|
||||
Pass insert element div after subject_ancestor
|
||||
Pass add the class 'test' to the element inserted again after subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted again after subject_ancestor
|
||||
Pass remove element div after subject_ancestor
|
||||
Pass insert element div[test_attr] after subject_ancestor
|
||||
Pass remove element div[test_attr] after subject_ancestor
|
||||
Pass insert element div.test after subject_parent
|
||||
Pass remove the class 'test' from the element inserted after subject_parent
|
||||
Pass add the class 'test' again to the element inserted after subject_parent
|
||||
Pass remove element div.test after subject_parent
|
||||
Pass insert element div after subject_parent
|
||||
Pass add the class 'test' to the element inserted again after subject_parent
|
||||
Pass remove the class 'test' from the element inserted again after subject_parent
|
||||
Pass remove element div after subject_parent
|
||||
Pass insert element div[test_attr] after subject_parent
|
||||
Pass remove element div[test_attr] after subject_parent
|
||||
Pass insert element div.test after subject
|
||||
Pass remove the class 'test' from the element inserted after subject
|
||||
Pass add the class 'test' again to the element inserted after subject
|
||||
Pass remove element div.test after subject
|
||||
Pass insert element div after subject
|
||||
Pass add the class 'test' to the element inserted again after subject
|
||||
Pass remove the class 'test' from the element inserted again after subject
|
||||
Pass remove element div after subject
|
||||
Pass insert element div[test_attr] after subject
|
||||
Pass remove element div[test_attr] after subject
|
||||
Pass insert element div.test after subject_child
|
||||
Pass remove the class 'test' from the element inserted after subject_child
|
||||
Pass add the class 'test' again to the element inserted after subject_child
|
||||
Pass remove element div.test after subject_child
|
||||
Pass insert element div after subject_child
|
||||
Pass add the class 'test' to the element inserted again after subject_child
|
||||
Pass remove the class 'test' from the element inserted again after subject_child
|
||||
Pass remove element div after subject_child
|
||||
Pass insert element div[test_attr] after subject_child
|
||||
Pass remove element div[test_attr] after subject_child
|
||||
Pass insert element div.test after subject_descendant
|
||||
Pass remove the class 'test' from the element inserted after subject_descendant
|
||||
Pass add the class 'test' again to the element inserted after subject_descendant
|
||||
Pass remove element div.test after subject_descendant
|
||||
Pass insert element div after subject_descendant
|
||||
Pass add the class 'test' to the element inserted again after subject_descendant
|
||||
Pass remove the class 'test' from the element inserted again after subject_descendant
|
||||
Pass remove element div after subject_descendant
|
||||
Pass insert element div[test_attr] after subject_descendant
|
||||
Pass remove element div[test_attr] after subject_descendant
|
||||
Pass insert element div.test after next_sibling
|
||||
Pass remove the class 'test' from the element inserted after next_sibling
|
||||
Pass add the class 'test' again to the element inserted after next_sibling
|
||||
Pass remove element div.test after next_sibling
|
||||
Pass insert element div after next_sibling
|
||||
Pass add the class 'test' to the element inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling
|
||||
Pass remove element div after next_sibling
|
||||
Pass insert element div[test_attr] after next_sibling
|
||||
Pass remove element div[test_attr] after next_sibling
|
||||
Pass insert element div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_child
|
||||
Pass remove element div.test after next_sibling_child
|
||||
Pass insert element div after next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_child
|
||||
Pass remove element div after next_sibling_child
|
||||
Pass insert element div[test_attr] after next_sibling_child
|
||||
Pass remove element div[test_attr] after next_sibling_child
|
||||
Pass insert element div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_descendant
|
||||
Pass remove element div.test after next_sibling_descendant
|
||||
Pass insert element div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_descendant
|
||||
Pass remove element div after next_sibling_descendant
|
||||
Pass insert element div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div[test_attr] after next_sibling_descendant
|
||||
Pass insert tree div>div.test before subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_ancestor
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_ancestor
|
||||
Pass remove tree div>div.test before subject_ancestor
|
||||
Pass insert tree div>div before subject_ancestor
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_ancestor
|
||||
Pass remove tree div>div before subject_ancestor
|
||||
Pass insert element div>div[test_attr] before subject_ancestor
|
||||
Pass remove element div>div[test_attr] before subject_ancestor
|
||||
Pass insert tree div>div.test before subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_parent
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_parent
|
||||
Pass remove tree div>div.test before subject_parent
|
||||
Pass insert tree div>div before subject_parent
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_parent
|
||||
Pass remove tree div>div before subject_parent
|
||||
Pass insert element div>div[test_attr] before subject_parent
|
||||
Pass remove element div>div[test_attr] before subject_parent
|
||||
Pass insert tree div>div.test before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject
|
||||
Pass remove tree div>div.test before subject
|
||||
Pass insert tree div>div before subject
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject
|
||||
Pass remove tree div>div before subject
|
||||
Pass insert element div>div[test_attr] before subject
|
||||
Pass remove element div>div[test_attr] before subject
|
||||
Pass insert tree div>div.test before subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_child
|
||||
Pass remove tree div>div.test before subject_child
|
||||
Pass insert tree div>div before subject_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_child
|
||||
Pass remove tree div>div before subject_child
|
||||
Pass insert element div>div[test_attr] before subject_child
|
||||
Pass remove element div>div[test_attr] before subject_child
|
||||
Pass insert tree div>div.test before subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_descendant
|
||||
Pass remove tree div>div.test before subject_descendant
|
||||
Pass insert tree div>div before subject_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_descendant
|
||||
Pass remove tree div>div before subject_descendant
|
||||
Pass insert element div>div[test_attr] before subject_descendant
|
||||
Pass remove element div>div[test_attr] before subject_descendant
|
||||
Pass insert tree div>div.test before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling
|
||||
Pass remove tree div>div.test before next_sibling
|
||||
Pass insert tree div>div before next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling
|
||||
Pass remove tree div>div before next_sibling
|
||||
Pass insert element div>div[test_attr] before next_sibling
|
||||
Pass remove element div>div[test_attr] before next_sibling
|
||||
Pass insert tree div>div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_child
|
||||
Pass remove tree div>div.test before next_sibling_child
|
||||
Pass insert tree div>div before next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_child
|
||||
Pass remove tree div>div before next_sibling_child
|
||||
Pass insert element div>div[test_attr] before next_sibling_child
|
||||
Pass remove element div>div[test_attr] before next_sibling_child
|
||||
Pass insert tree div>div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_descendant
|
||||
Pass remove tree div>div.test before next_sibling_descendant
|
||||
Pass insert tree div>div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove tree div>div before next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] before next_sibling_descendant
|
||||
Pass insert tree div>div.test after subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_ancestor
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_ancestor
|
||||
Pass remove tree div>div.test after subject_ancestor
|
||||
Pass insert tree div>div after subject_ancestor
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_ancestor
|
||||
Pass remove tree div>div after subject_ancestor
|
||||
Pass insert element div>div[test_attr] after subject_ancestor
|
||||
Pass remove element div>div[test_attr] after subject_ancestor
|
||||
Pass insert tree div>div.test after subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_parent
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_parent
|
||||
Pass remove tree div>div.test after subject_parent
|
||||
Pass insert tree div>div after subject_parent
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_parent
|
||||
Pass remove tree div>div after subject_parent
|
||||
Pass insert element div>div[test_attr] after subject_parent
|
||||
Pass remove element div>div[test_attr] after subject_parent
|
||||
Pass insert tree div>div.test after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject
|
||||
Pass remove tree div>div.test after subject
|
||||
Pass insert tree div>div after subject
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject
|
||||
Pass remove tree div>div after subject
|
||||
Pass insert element div>div[test_attr] after subject
|
||||
Pass remove element div>div[test_attr] after subject
|
||||
Pass insert tree div>div.test after subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_child
|
||||
Pass remove tree div>div.test after subject_child
|
||||
Pass insert tree div>div after subject_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_child
|
||||
Pass remove tree div>div after subject_child
|
||||
Pass insert element div>div[test_attr] after subject_child
|
||||
Pass remove element div>div[test_attr] after subject_child
|
||||
Pass insert tree div>div.test after subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_descendant
|
||||
Pass remove tree div>div.test after subject_descendant
|
||||
Pass insert tree div>div after subject_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_descendant
|
||||
Pass remove tree div>div after subject_descendant
|
||||
Pass insert element div>div[test_attr] after subject_descendant
|
||||
Pass remove element div>div[test_attr] after subject_descendant
|
||||
Pass insert tree div>div.test after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling
|
||||
Pass remove tree div>div.test after next_sibling
|
||||
Pass insert tree div>div after next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling
|
||||
Pass remove tree div>div after next_sibling
|
||||
Pass insert element div>div[test_attr] after next_sibling
|
||||
Pass remove element div>div[test_attr] after next_sibling
|
||||
Pass insert tree div>div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_child
|
||||
Pass remove tree div>div.test after next_sibling_child
|
||||
Pass insert tree div>div after next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_child
|
||||
Pass remove tree div>div after next_sibling_child
|
||||
Pass insert element div>div[test_attr] after next_sibling_child
|
||||
Pass remove element div>div[test_attr] after next_sibling_child
|
||||
Pass insert tree div>div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_descendant
|
||||
Pass remove tree div>div.test after next_sibling_descendant
|
||||
Pass insert tree div>div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove tree div>div after next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] after next_sibling_descendant
|
|
@ -0,0 +1,221 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 211 tests
|
||||
|
||||
211 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass add .test to subject_ancestor
|
||||
Pass remove .test from subject_ancestor
|
||||
Pass add .test to subject_parent
|
||||
Pass remove .test from subject_parent
|
||||
Pass add .test to subject
|
||||
Pass remove .test from subject
|
||||
Pass add .test to subject_child
|
||||
Pass remove .test from subject_child
|
||||
Pass add .test to subject_descendant
|
||||
Pass remove .test from subject_descendant
|
||||
Pass insert element div.test before subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted before subject_ancestor
|
||||
Pass add the class 'test' again to the element inserted before subject_ancestor
|
||||
Pass remove element div.test before subject_ancestor
|
||||
Pass insert element div before subject_ancestor
|
||||
Pass add the class 'test' to the element inserted again before subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted again before subject_ancestor
|
||||
Pass remove element div before subject_ancestor
|
||||
Pass insert element div[test_attr] before subject_ancestor
|
||||
Pass remove element div[test_attr] before subject_ancestor
|
||||
Pass insert element div.test before subject_parent
|
||||
Pass remove the class 'test' from the element inserted before subject_parent
|
||||
Pass add the class 'test' again to the element inserted before subject_parent
|
||||
Pass remove element div.test before subject_parent
|
||||
Pass insert element div before subject_parent
|
||||
Pass add the class 'test' to the element inserted again before subject_parent
|
||||
Pass remove the class 'test' from the element inserted again before subject_parent
|
||||
Pass remove element div before subject_parent
|
||||
Pass insert element div[test_attr] before subject_parent
|
||||
Pass remove element div[test_attr] before subject_parent
|
||||
Pass insert element div.test before subject
|
||||
Pass remove the class 'test' from the element inserted before subject
|
||||
Pass add the class 'test' again to the element inserted before subject
|
||||
Pass remove element div.test before subject
|
||||
Pass insert element div before subject
|
||||
Pass add the class 'test' to the element inserted again before subject
|
||||
Pass remove the class 'test' from the element inserted again before subject
|
||||
Pass remove element div before subject
|
||||
Pass insert element div[test_attr] before subject
|
||||
Pass remove element div[test_attr] before subject
|
||||
Pass insert element div.test before subject_child
|
||||
Pass remove the class 'test' from the element inserted before subject_child
|
||||
Pass add the class 'test' again to the element inserted before subject_child
|
||||
Pass remove element div.test before subject_child
|
||||
Pass insert element div before subject_child
|
||||
Pass add the class 'test' to the element inserted again before subject_child
|
||||
Pass remove the class 'test' from the element inserted again before subject_child
|
||||
Pass remove element div before subject_child
|
||||
Pass insert element div[test_attr] before subject_child
|
||||
Pass remove element div[test_attr] before subject_child
|
||||
Pass insert element div.test before subject_descendant
|
||||
Pass remove the class 'test' from the element inserted before subject_descendant
|
||||
Pass add the class 'test' again to the element inserted before subject_descendant
|
||||
Pass remove element div.test before subject_descendant
|
||||
Pass insert element div before subject_descendant
|
||||
Pass add the class 'test' to the element inserted again before subject_descendant
|
||||
Pass remove the class 'test' from the element inserted again before subject_descendant
|
||||
Pass remove element div before subject_descendant
|
||||
Pass insert element div[test_attr] before subject_descendant
|
||||
Pass remove element div[test_attr] before subject_descendant
|
||||
Pass insert element div.test after subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted after subject_ancestor
|
||||
Pass add the class 'test' again to the element inserted after subject_ancestor
|
||||
Pass remove element div.test after subject_ancestor
|
||||
Pass insert element div after subject_ancestor
|
||||
Pass add the class 'test' to the element inserted again after subject_ancestor
|
||||
Pass remove the class 'test' from the element inserted again after subject_ancestor
|
||||
Pass remove element div after subject_ancestor
|
||||
Pass insert element div[test_attr] after subject_ancestor
|
||||
Pass remove element div[test_attr] after subject_ancestor
|
||||
Pass insert element div.test after subject_parent
|
||||
Pass remove the class 'test' from the element inserted after subject_parent
|
||||
Pass add the class 'test' again to the element inserted after subject_parent
|
||||
Pass remove element div.test after subject_parent
|
||||
Pass insert element div after subject_parent
|
||||
Pass add the class 'test' to the element inserted again after subject_parent
|
||||
Pass remove the class 'test' from the element inserted again after subject_parent
|
||||
Pass remove element div after subject_parent
|
||||
Pass insert element div[test_attr] after subject_parent
|
||||
Pass remove element div[test_attr] after subject_parent
|
||||
Pass insert element div.test after subject
|
||||
Pass remove the class 'test' from the element inserted after subject
|
||||
Pass add the class 'test' again to the element inserted after subject
|
||||
Pass remove element div.test after subject
|
||||
Pass insert element div after subject
|
||||
Pass add the class 'test' to the element inserted again after subject
|
||||
Pass remove the class 'test' from the element inserted again after subject
|
||||
Pass remove element div after subject
|
||||
Pass insert element div[test_attr] after subject
|
||||
Pass remove element div[test_attr] after subject
|
||||
Pass insert element div.test after subject_child
|
||||
Pass remove the class 'test' from the element inserted after subject_child
|
||||
Pass add the class 'test' again to the element inserted after subject_child
|
||||
Pass remove element div.test after subject_child
|
||||
Pass insert element div after subject_child
|
||||
Pass add the class 'test' to the element inserted again after subject_child
|
||||
Pass remove the class 'test' from the element inserted again after subject_child
|
||||
Pass remove element div after subject_child
|
||||
Pass insert element div[test_attr] after subject_child
|
||||
Pass remove element div[test_attr] after subject_child
|
||||
Pass insert element div.test after subject_descendant
|
||||
Pass remove the class 'test' from the element inserted after subject_descendant
|
||||
Pass add the class 'test' again to the element inserted after subject_descendant
|
||||
Pass remove element div.test after subject_descendant
|
||||
Pass insert element div after subject_descendant
|
||||
Pass add the class 'test' to the element inserted again after subject_descendant
|
||||
Pass remove the class 'test' from the element inserted again after subject_descendant
|
||||
Pass remove element div after subject_descendant
|
||||
Pass insert element div[test_attr] after subject_descendant
|
||||
Pass remove element div[test_attr] after subject_descendant
|
||||
Pass insert tree div>div.test before subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_ancestor
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_ancestor
|
||||
Pass remove tree div>div.test before subject_ancestor
|
||||
Pass insert tree div>div before subject_ancestor
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_ancestor
|
||||
Pass remove tree div>div before subject_ancestor
|
||||
Pass insert element div>div[test_attr] before subject_ancestor
|
||||
Pass remove element div>div[test_attr] before subject_ancestor
|
||||
Pass insert tree div>div.test before subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_parent
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_parent
|
||||
Pass remove tree div>div.test before subject_parent
|
||||
Pass insert tree div>div before subject_parent
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_parent
|
||||
Pass remove tree div>div before subject_parent
|
||||
Pass insert element div>div[test_attr] before subject_parent
|
||||
Pass remove element div>div[test_attr] before subject_parent
|
||||
Pass insert tree div>div.test before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject
|
||||
Pass remove tree div>div.test before subject
|
||||
Pass insert tree div>div before subject
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject
|
||||
Pass remove tree div>div before subject
|
||||
Pass insert element div>div[test_attr] before subject
|
||||
Pass remove element div>div[test_attr] before subject
|
||||
Pass insert tree div>div.test before subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_child
|
||||
Pass remove tree div>div.test before subject_child
|
||||
Pass insert tree div>div before subject_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_child
|
||||
Pass remove tree div>div before subject_child
|
||||
Pass insert element div>div[test_attr] before subject_child
|
||||
Pass remove element div>div[test_attr] before subject_child
|
||||
Pass insert tree div>div.test before subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject_descendant
|
||||
Pass remove tree div>div.test before subject_descendant
|
||||
Pass insert tree div>div before subject_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject_descendant
|
||||
Pass remove tree div>div before subject_descendant
|
||||
Pass insert element div>div[test_attr] before subject_descendant
|
||||
Pass remove element div>div[test_attr] before subject_descendant
|
||||
Pass insert tree div>div.test after subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_ancestor
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_ancestor
|
||||
Pass remove tree div>div.test after subject_ancestor
|
||||
Pass insert tree div>div after subject_ancestor
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_ancestor
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_ancestor
|
||||
Pass remove tree div>div after subject_ancestor
|
||||
Pass insert element div>div[test_attr] after subject_ancestor
|
||||
Pass remove element div>div[test_attr] after subject_ancestor
|
||||
Pass insert tree div>div.test after subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_parent
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_parent
|
||||
Pass remove tree div>div.test after subject_parent
|
||||
Pass insert tree div>div after subject_parent
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_parent
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_parent
|
||||
Pass remove tree div>div after subject_parent
|
||||
Pass insert element div>div[test_attr] after subject_parent
|
||||
Pass remove element div>div[test_attr] after subject_parent
|
||||
Pass insert tree div>div.test after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject
|
||||
Pass remove tree div>div.test after subject
|
||||
Pass insert tree div>div after subject
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject
|
||||
Pass remove tree div>div after subject
|
||||
Pass insert element div>div[test_attr] after subject
|
||||
Pass remove element div>div[test_attr] after subject
|
||||
Pass insert tree div>div.test after subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_child
|
||||
Pass remove tree div>div.test after subject_child
|
||||
Pass insert tree div>div after subject_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_child
|
||||
Pass remove tree div>div after subject_child
|
||||
Pass insert element div>div[test_attr] after subject_child
|
||||
Pass remove element div>div[test_attr] after subject_child
|
||||
Pass insert tree div>div.test after subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject_descendant
|
||||
Pass remove tree div>div.test after subject_descendant
|
||||
Pass insert tree div>div after subject_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject_descendant
|
||||
Pass remove tree div>div after subject_descendant
|
||||
Pass insert element div>div[test_attr] after subject_descendant
|
||||
Pass remove element div>div[test_attr] after subject_descendant
|
|
@ -0,0 +1,305 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 295 tests
|
||||
|
||||
295 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass add .test to previous_sibling
|
||||
Pass remove .test from previous_sibling
|
||||
Pass add .test to previous_sibling_child
|
||||
Pass remove .test from previous_sibling_child
|
||||
Pass add .test to previous_sibling_descendant
|
||||
Pass remove .test from previous_sibling_descendant
|
||||
Pass add .test to subject
|
||||
Pass remove .test from subject
|
||||
Pass add .test to next_sibling
|
||||
Pass remove .test from next_sibling
|
||||
Pass add .test to next_sibling_child
|
||||
Pass remove .test from next_sibling_child
|
||||
Pass add .test to next_sibling_descendant
|
||||
Pass remove .test from next_sibling_descendant
|
||||
Pass insert element div.test before previous_sibling
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling
|
||||
Pass remove element div.test before previous_sibling
|
||||
Pass insert element div before previous_sibling
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling
|
||||
Pass remove element div before previous_sibling
|
||||
Pass insert element div[test_attr] before previous_sibling
|
||||
Pass remove element div[test_attr] before previous_sibling
|
||||
Pass insert element div.test before previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling_child
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling_child
|
||||
Pass remove element div.test before previous_sibling_child
|
||||
Pass insert element div before previous_sibling_child
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling_child
|
||||
Pass remove element div before previous_sibling_child
|
||||
Pass insert element div[test_attr] before previous_sibling_child
|
||||
Pass remove element div[test_attr] before previous_sibling_child
|
||||
Pass insert element div.test before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted before previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted before previous_sibling_descendant
|
||||
Pass remove element div.test before previous_sibling_descendant
|
||||
Pass insert element div before previous_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again before previous_sibling_descendant
|
||||
Pass remove element div before previous_sibling_descendant
|
||||
Pass insert element div[test_attr] before previous_sibling_descendant
|
||||
Pass remove element div[test_attr] before previous_sibling_descendant
|
||||
Pass insert element div.test before subject
|
||||
Pass remove the class 'test' from the element inserted before subject
|
||||
Pass add the class 'test' again to the element inserted before subject
|
||||
Pass remove element div.test before subject
|
||||
Pass insert element div before subject
|
||||
Pass add the class 'test' to the element inserted again before subject
|
||||
Pass remove the class 'test' from the element inserted again before subject
|
||||
Pass remove element div before subject
|
||||
Pass insert element div[test_attr] before subject
|
||||
Pass remove element div[test_attr] before subject
|
||||
Pass insert element div.test before next_sibling
|
||||
Pass remove the class 'test' from the element inserted before next_sibling
|
||||
Pass add the class 'test' again to the element inserted before next_sibling
|
||||
Pass remove element div.test before next_sibling
|
||||
Pass insert element div before next_sibling
|
||||
Pass add the class 'test' to the element inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling
|
||||
Pass remove element div before next_sibling
|
||||
Pass insert element div[test_attr] before next_sibling
|
||||
Pass remove element div[test_attr] before next_sibling
|
||||
Pass insert element div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_child
|
||||
Pass remove element div.test before next_sibling_child
|
||||
Pass insert element div before next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_child
|
||||
Pass remove element div before next_sibling_child
|
||||
Pass insert element div[test_attr] before next_sibling_child
|
||||
Pass remove element div[test_attr] before next_sibling_child
|
||||
Pass insert element div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted before next_sibling_descendant
|
||||
Pass remove element div.test before next_sibling_descendant
|
||||
Pass insert element div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again before next_sibling_descendant
|
||||
Pass remove element div before next_sibling_descendant
|
||||
Pass insert element div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div[test_attr] before next_sibling_descendant
|
||||
Pass insert element div.test after previous_sibling
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling
|
||||
Pass remove element div.test after previous_sibling
|
||||
Pass insert element div after previous_sibling
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling
|
||||
Pass remove element div after previous_sibling
|
||||
Pass insert element div[test_attr] after previous_sibling
|
||||
Pass remove element div[test_attr] after previous_sibling
|
||||
Pass insert element div.test after previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling_child
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling_child
|
||||
Pass remove element div.test after previous_sibling_child
|
||||
Pass insert element div after previous_sibling_child
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling_child
|
||||
Pass remove element div after previous_sibling_child
|
||||
Pass insert element div[test_attr] after previous_sibling_child
|
||||
Pass remove element div[test_attr] after previous_sibling_child
|
||||
Pass insert element div.test after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted after previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted after previous_sibling_descendant
|
||||
Pass remove element div.test after previous_sibling_descendant
|
||||
Pass insert element div after previous_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again after previous_sibling_descendant
|
||||
Pass remove element div after previous_sibling_descendant
|
||||
Pass insert element div[test_attr] after previous_sibling_descendant
|
||||
Pass remove element div[test_attr] after previous_sibling_descendant
|
||||
Pass insert element div.test after subject
|
||||
Pass remove the class 'test' from the element inserted after subject
|
||||
Pass add the class 'test' again to the element inserted after subject
|
||||
Pass remove element div.test after subject
|
||||
Pass insert element div after subject
|
||||
Pass add the class 'test' to the element inserted again after subject
|
||||
Pass remove the class 'test' from the element inserted again after subject
|
||||
Pass remove element div after subject
|
||||
Pass insert element div[test_attr] after subject
|
||||
Pass remove element div[test_attr] after subject
|
||||
Pass insert element div.test after next_sibling
|
||||
Pass remove the class 'test' from the element inserted after next_sibling
|
||||
Pass add the class 'test' again to the element inserted after next_sibling
|
||||
Pass remove element div.test after next_sibling
|
||||
Pass insert element div after next_sibling
|
||||
Pass add the class 'test' to the element inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling
|
||||
Pass remove element div after next_sibling
|
||||
Pass insert element div[test_attr] after next_sibling
|
||||
Pass remove element div[test_attr] after next_sibling
|
||||
Pass insert element div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_child
|
||||
Pass remove element div.test after next_sibling_child
|
||||
Pass insert element div after next_sibling_child
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_child
|
||||
Pass remove element div after next_sibling_child
|
||||
Pass insert element div[test_attr] after next_sibling_child
|
||||
Pass remove element div[test_attr] after next_sibling_child
|
||||
Pass insert element div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element inserted after next_sibling_descendant
|
||||
Pass remove element div.test after next_sibling_descendant
|
||||
Pass insert element div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element inserted again after next_sibling_descendant
|
||||
Pass remove element div after next_sibling_descendant
|
||||
Pass insert element div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div[test_attr] after next_sibling_descendant
|
||||
Pass insert tree div>div.test before previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling
|
||||
Pass remove tree div>div.test before previous_sibling
|
||||
Pass insert tree div>div before previous_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling
|
||||
Pass remove tree div>div before previous_sibling
|
||||
Pass insert element div>div[test_attr] before previous_sibling
|
||||
Pass remove element div>div[test_attr] before previous_sibling
|
||||
Pass insert tree div>div.test before previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling_child
|
||||
Pass remove tree div>div.test before previous_sibling_child
|
||||
Pass insert tree div>div before previous_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling_child
|
||||
Pass remove tree div>div before previous_sibling_child
|
||||
Pass insert element div>div[test_attr] before previous_sibling_child
|
||||
Pass remove element div>div[test_attr] before previous_sibling_child
|
||||
Pass insert tree div>div.test before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before previous_sibling_descendant
|
||||
Pass remove tree div>div.test before previous_sibling_descendant
|
||||
Pass insert tree div>div before previous_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before previous_sibling_descendant
|
||||
Pass remove tree div>div before previous_sibling_descendant
|
||||
Pass insert element div>div[test_attr] before previous_sibling_descendant
|
||||
Pass remove element div>div[test_attr] before previous_sibling_descendant
|
||||
Pass insert tree div>div.test before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted before subject
|
||||
Pass add the class 'test' again to the element in the tree inserted before subject
|
||||
Pass remove tree div>div.test before subject
|
||||
Pass insert tree div>div before subject
|
||||
Pass add the class 'test' to the element in the tree inserted again before subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again before subject
|
||||
Pass remove tree div>div before subject
|
||||
Pass insert element div>div[test_attr] before subject
|
||||
Pass remove element div>div[test_attr] before subject
|
||||
Pass insert tree div>div.test before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling
|
||||
Pass remove tree div>div.test before next_sibling
|
||||
Pass insert tree div>div before next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling
|
||||
Pass remove tree div>div before next_sibling
|
||||
Pass insert element div>div[test_attr] before next_sibling
|
||||
Pass remove element div>div[test_attr] before next_sibling
|
||||
Pass insert tree div>div.test before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_child
|
||||
Pass remove tree div>div.test before next_sibling_child
|
||||
Pass insert tree div>div before next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_child
|
||||
Pass remove tree div>div before next_sibling_child
|
||||
Pass insert element div>div[test_attr] before next_sibling_child
|
||||
Pass remove element div>div[test_attr] before next_sibling_child
|
||||
Pass insert tree div>div.test before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted before next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted before next_sibling_descendant
|
||||
Pass remove tree div>div.test before next_sibling_descendant
|
||||
Pass insert tree div>div before next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again before next_sibling_descendant
|
||||
Pass remove tree div>div before next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] before next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] before next_sibling_descendant
|
||||
Pass insert tree div>div.test after previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling
|
||||
Pass remove tree div>div.test after previous_sibling
|
||||
Pass insert tree div>div after previous_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling
|
||||
Pass remove tree div>div after previous_sibling
|
||||
Pass insert element div>div[test_attr] after previous_sibling
|
||||
Pass remove element div>div[test_attr] after previous_sibling
|
||||
Pass insert tree div>div.test after previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling_child
|
||||
Pass remove tree div>div.test after previous_sibling_child
|
||||
Pass insert tree div>div after previous_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling_child
|
||||
Pass remove tree div>div after previous_sibling_child
|
||||
Pass insert element div>div[test_attr] after previous_sibling_child
|
||||
Pass remove element div>div[test_attr] after previous_sibling_child
|
||||
Pass insert tree div>div.test after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after previous_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after previous_sibling_descendant
|
||||
Pass remove tree div>div.test after previous_sibling_descendant
|
||||
Pass insert tree div>div after previous_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after previous_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after previous_sibling_descendant
|
||||
Pass remove tree div>div after previous_sibling_descendant
|
||||
Pass insert element div>div[test_attr] after previous_sibling_descendant
|
||||
Pass remove element div>div[test_attr] after previous_sibling_descendant
|
||||
Pass insert tree div>div.test after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted after subject
|
||||
Pass add the class 'test' again to the element in the tree inserted after subject
|
||||
Pass remove tree div>div.test after subject
|
||||
Pass insert tree div>div after subject
|
||||
Pass add the class 'test' to the element in the tree inserted again after subject
|
||||
Pass remove the class 'test' from the element in the tree inserted again after subject
|
||||
Pass remove tree div>div after subject
|
||||
Pass insert element div>div[test_attr] after subject
|
||||
Pass remove element div>div[test_attr] after subject
|
||||
Pass insert tree div>div.test after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling
|
||||
Pass remove tree div>div.test after next_sibling
|
||||
Pass insert tree div>div after next_sibling
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling
|
||||
Pass remove tree div>div after next_sibling
|
||||
Pass insert element div>div[test_attr] after next_sibling
|
||||
Pass remove element div>div[test_attr] after next_sibling
|
||||
Pass insert tree div>div.test after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_child
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_child
|
||||
Pass remove tree div>div.test after next_sibling_child
|
||||
Pass insert tree div>div after next_sibling_child
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_child
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_child
|
||||
Pass remove tree div>div after next_sibling_child
|
||||
Pass insert element div>div[test_attr] after next_sibling_child
|
||||
Pass remove element div>div[test_attr] after next_sibling_child
|
||||
Pass insert tree div>div.test after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted after next_sibling_descendant
|
||||
Pass add the class 'test' again to the element in the tree inserted after next_sibling_descendant
|
||||
Pass remove tree div>div.test after next_sibling_descendant
|
||||
Pass insert tree div>div after next_sibling_descendant
|
||||
Pass add the class 'test' to the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove the class 'test' from the element in the tree inserted again after next_sibling_descendant
|
||||
Pass remove tree div>div after next_sibling_descendant
|
||||
Pass insert element div>div[test_attr] after next_sibling_descendant
|
||||
Pass remove element div>div[test_attr] after next_sibling_descendant
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Details
|
||||
Result Test Name MessagePass initial_color: div#subject.color
|
||||
Pass remove descendant: div#subject.color
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass initial color: div#subject.color
|
||||
Pass color after inserting text and div > .descendant: div#subject.color
|
||||
Pass color after wiping #child to remove div > .descendant: div#subject.color
|
||||
Pass color after inserting text and #child > .descendant: div#subject.color
|
||||
Pass color after wiping #child to remove .descendant: div#subject.color
|
|
@ -0,0 +1,38 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 28 tests
|
||||
|
||||
28 Pass
|
||||
Details
|
||||
Result Test Name MessagePass subject1: initial color should be rgb(128, 128, 128)
|
||||
Pass subject1: color after #sibling1_1 inserted should be rgb(255, 0, 0)
|
||||
Pass subject2: initial color should be rgb(128, 128, 128)
|
||||
Pass subject2: color after #sibling2_1 removed should be rgb(0, 128, 0)
|
||||
Pass subject3: initial color should be rgb(128, 128, 128)
|
||||
Pass subject3: color after #sibling3_1 inserted should be rgb(0, 0, 255)
|
||||
Pass subject4: initial color should be rgb(128, 128, 128)
|
||||
Pass subject4: color after #sibling4_1 removed should be rgb(255, 255, 0)
|
||||
Pass subject5: initial color should be rgb(255, 0, 0)
|
||||
Pass subject5: color after #sibling5_1 removed should be rgb(128, 128, 128)
|
||||
Pass subject6: initial color should be rgb(0, 128, 0)
|
||||
Pass subject6: color after #sibling6_1 inserted should be rgb(128, 128, 128)
|
||||
Pass subject7: initial color should be rgb(0, 0, 255)
|
||||
Pass subject7: color after #sibling7_1 removed should be rgb(128, 128, 128)
|
||||
Pass subject8: initial color should be rgb(255, 255, 0)
|
||||
Pass subject8: color after #sibling8_1 inserted should be rgb(128, 128, 128)
|
||||
Pass subject9: initial color should be rgb(128, 128, 128)
|
||||
Pass subject9: color after #sibling9_1 inserted should be rgb(255, 0, 0)
|
||||
Pass subject10: initial color should be rgb(128, 128, 128)
|
||||
Pass subject10: color after #sibling10_1 removed should be rgb(0, 128, 0)
|
||||
Pass subject11: initial color should be rgb(128, 128, 128)
|
||||
Pass subject11: color after #sibling11_1 inserted should be rgb(0, 0, 255)
|
||||
Pass subject12: initial color should be rgb(128, 128, 128)
|
||||
Pass subject12: color after #sibling12_1 removed should be rgb(255, 255, 0)
|
||||
Pass subject13: initial color should be rgb(128, 128, 128)
|
||||
Pass subject13: color after #sibling12_1 removed should be rgb(0, 128, 0)
|
||||
Pass subject14: initial color should be rgb(0, 128, 0)
|
||||
Pass subject14: color after #sibling14_2 removed should be rgb(128, 128, 128)
|
|
@ -0,0 +1,81 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 71 tests
|
||||
|
||||
71 Pass
|
||||
Details
|
||||
Result Test Name MessagePass initial_color
|
||||
Pass add .test to first_sibling
|
||||
Pass remove .test from first_sibling
|
||||
Pass add .test to second_sibling
|
||||
Pass remove .test from second_sibling
|
||||
Pass add .test to third_sibling
|
||||
Pass remove .test from third_sibling
|
||||
Pass add .test to first_sibling_child
|
||||
Pass remove .test from first_sibling_child
|
||||
Pass add .test to first_sibling_descendant
|
||||
Pass remove .test from first_sibling_descendant
|
||||
Pass add .test to third_sibling_child
|
||||
Pass remove .test from third_sibling_child
|
||||
Pass add .test to third_sibling_descendant
|
||||
Pass remove .test from third_sibling_descendant
|
||||
Pass insert element div.test before first_sibling
|
||||
Pass remove element div.test before first_sibling
|
||||
Pass insert element div.test before second_sibling
|
||||
Pass remove element div.test before second_sibling
|
||||
Pass insert element div.test before third_sibling
|
||||
Pass remove element div.test before third_sibling
|
||||
Pass insert element div.test before first_sibling_child
|
||||
Pass remove element div.test before first_sibling_child
|
||||
Pass insert element div.test before first_sibling_descendant
|
||||
Pass remove element div.test before first_sibling_descendant
|
||||
Pass insert element div.test before third_sibling_child
|
||||
Pass remove element div.test before third_sibling_child
|
||||
Pass insert element div.test before third_sibling_descendant
|
||||
Pass remove element div.test before third_sibling_descendant
|
||||
Pass insert element div.test after first_sibling
|
||||
Pass remove element div.test after first_sibling
|
||||
Pass insert element div.test after second_sibling
|
||||
Pass remove element div.test after second_sibling
|
||||
Pass insert element div.test after third_sibling
|
||||
Pass remove element div.test after third_sibling
|
||||
Pass insert element div.test after first_sibling_child
|
||||
Pass remove element div.test after first_sibling_child
|
||||
Pass insert element div.test after first_sibling_descendant
|
||||
Pass remove element div.test after first_sibling_descendant
|
||||
Pass insert element div.test after third_sibling_child
|
||||
Pass remove element div.test after third_sibling_child
|
||||
Pass insert element div.test after third_sibling_descendant
|
||||
Pass remove element div.test after third_sibling_descendant
|
||||
Pass insert tree div>div.test before first_sibling
|
||||
Pass remove tree div>div.test before first_sibling
|
||||
Pass insert tree div>div.test before second_sibling
|
||||
Pass remove tree div>div.test before second_sibling
|
||||
Pass insert tree div>div.test before third_sibling
|
||||
Pass remove tree div>div.test before third_sibling
|
||||
Pass insert tree div>div.test before first_sibling_child
|
||||
Pass remove tree div>div.test before first_sibling_child
|
||||
Pass insert tree div>div.test before first_sibling_descendant
|
||||
Pass remove tree div>div.test before first_sibling_descendant
|
||||
Pass insert tree div>div.test before third_sibling_child
|
||||
Pass remove tree div>div.test before third_sibling_child
|
||||
Pass insert tree div>div.test before third_sibling_descendant
|
||||
Pass remove tree div>div.test before third_sibling_descendant
|
||||
Pass insert tree div>div.test after first_sibling
|
||||
Pass remove tree div>div.test after first_sibling
|
||||
Pass insert tree div>div.test after second_sibling
|
||||
Pass remove tree div>div.test after second_sibling
|
||||
Pass insert tree div>div.test after third_sibling
|
||||
Pass remove tree div>div.test after third_sibling
|
||||
Pass insert tree div>div.test after first_sibling_child
|
||||
Pass remove tree div>div.test after first_sibling_child
|
||||
Pass insert tree div>div.test after first_sibling_descendant
|
||||
Pass remove tree div>div.test after first_sibling_descendant
|
||||
Pass insert tree div>div.test after third_sibling_child
|
||||
Pass remove tree div>div.test after third_sibling_child
|
||||
Pass insert tree div>div.test after third_sibling_descendant
|
||||
Pass remove tree div>div.test after third_sibling_descendant
|
|
@ -0,0 +1,13 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
3 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial colors
|
||||
Pass Matches after #blocks_match removed
|
||||
Pass Does not match after #blocks_match added
|
|
@ -0,0 +1,19 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 9 tests
|
||||
|
||||
9 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass add test to subject_descendant
|
||||
Pass remove test from subject_descendant
|
||||
Pass add test to sibling_descendant
|
||||
Pass remove test from sibling_descendant
|
||||
Pass add test_inner to subject_child
|
||||
Pass remove test_inner from subject_child
|
||||
Pass add test_inner to sibling_child
|
||||
Pass remove test_inner from sibling_child
|
|
@ -0,0 +1,47 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 37 tests
|
||||
|
||||
37 Pass
|
||||
Details
|
||||
Result Test Name MessagePass #anchor1 initially white
|
||||
Pass #anchor1 becomes rgb(0, 0, 255) after adding .ancestor to #grand_parent1
|
||||
Pass #anchor1 becomes rgb(255, 255, 255) after removing .ancestor from #grand_parent1
|
||||
Pass #anchor1 becomes rgb(0, 0, 255) after adding .ancestor to #parent1
|
||||
Pass #anchor1 becomes rgb(255, 255, 255) after removing .ancestor from #parent1
|
||||
Pass #anchor2 initially white
|
||||
Pass #anchor2 becomes rgb(173, 216, 230) after adding .ancestor to #grand_parent2
|
||||
Pass #anchor2 becomes rgb(255, 255, 255) after removing .ancestor from #grand_parent2
|
||||
Pass #anchor2 becomes rgb(173, 216, 230) after adding .ancestor to #parent2
|
||||
Pass #anchor2 becomes rgb(255, 255, 255) after removing .ancestor from #parent2
|
||||
Pass #anchor3 initially white
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #grand_parent_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(154, 205, 50) after adding .ancestor to #grand_parent3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after removing .ancestor from #grand_parent3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #grand_parent_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #grand_parent_direct_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #grand_parent_direct_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #parent_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(154, 205, 50) after adding .ancestor to #parent3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after removing .ancestor from #parent3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #parent_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #parent_direct_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #parent_direct_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #anchor_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #anchor_indirect_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 0) after adding .ancestor_prev to #anchor_direct_prev3
|
||||
Pass #anchor3 becomes rgb(255, 255, 255) after removing .ancestor_prev from #anchor_direct_prev3
|
||||
Pass #anchor4 initially white
|
||||
Pass #anchor4 becomes rgb(0, 128, 0) after adding .prev to #indirect_prev4
|
||||
Pass #anchor4 becomes rgb(255, 255, 255) after removing .prev from #indirect_prev4
|
||||
Pass #anchor4 becomes rgb(0, 128, 0) after adding .prev to #direct_prev4
|
||||
Pass #anchor4 becomes rgb(255, 255, 255) after removing .prev from #direct_prev4
|
||||
Pass #anchor5 initially white
|
||||
Pass #anchor5 becomes rgb(144, 238, 144) after adding .prev to #indirect_prev5
|
||||
Pass #anchor5 becomes rgb(255, 255, 255) after removing .prev from #indirect_prev5
|
||||
Pass #anchor5 becomes rgb(144, 238, 144) after adding .prev to #direct_prev5
|
||||
Pass #anchor5 becomes rgb(255, 255, 255) after removing .prev from #direct_prev5
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessageFail CSS Selector Invalidation: :has() with nesting parent containing :hover promise_test: Unhandled rejection with value: object "ReferenceError: 'test_driver' is not defined"
|
|
@ -0,0 +1,31 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 21 tests
|
||||
|
||||
21 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial color
|
||||
Pass remove .test to subject_child
|
||||
Pass add .test from subject_child
|
||||
Pass remove .test to subject_descendant
|
||||
Pass add .test from subject_descendant
|
||||
Pass insert element div before subject_child
|
||||
Pass remove element div before subject_child
|
||||
Pass insert element div before subject_descendant
|
||||
Pass remove element div before subject_descendant
|
||||
Pass insert element div after subject_child
|
||||
Pass remove element div after subject_child
|
||||
Pass insert element div after subject_descendant
|
||||
Pass remove element div after subject_descendant
|
||||
Pass insert tree div>div before subject_child
|
||||
Pass remove tree div>div before subject_child
|
||||
Pass insert tree div>div before subject_descendant
|
||||
Pass remove tree div>div before subject_descendant
|
||||
Pass insert tree div.test after subject_child
|
||||
Pass remove tree div.test after subject_child
|
||||
Pass insert tree div.test after subject_descendant
|
||||
Pass remove tree div.test after subject_descendant
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initially red
|
||||
Pass :nth-child() no longer matching after removal
|
||||
Pass :nth-last-child() no longer matching after removal
|
||||
Pass :nth-child() in non-subject no longer matching after removal
|
||||
Pass :nth-last-child() in non-subject no longer matching after removal
|
|
@ -0,0 +1,52 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 41 tests
|
||||
|
||||
22 Pass
|
||||
19 Fail
|
||||
Details
|
||||
Result Test Name MessagePass Before set checked on checkbox, testing subject
|
||||
Fail Set checked on checkbox, testing subject assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)"
|
||||
Pass Unset checked on checkbox, testing subject
|
||||
Fail Set select on option assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)"
|
||||
Pass Reset select
|
||||
Pass Before set disabled on checkbox, testing subject
|
||||
Pass Set disabled on checkbox, testing subject
|
||||
Fail Unset disabled on checkbox, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Pass Before set disabled on checkbox, testing subject3
|
||||
Pass Set disabled on checkbox, testing subject3
|
||||
Pass Unset disabled on checkbox, testing subject3
|
||||
Fail Before set disabled on option, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Pass Set disabled on option, testing subject
|
||||
Fail Unset disabled on option, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Pass Before set disabled on option, testing subject3
|
||||
Pass Set disabled on option, testing subject3
|
||||
Pass Unset disabled on option, testing subject3
|
||||
Fail Before set disabled on optgroup, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Pass Set disabled on optgroup, testing subject
|
||||
Fail Unset disabled on optgroup, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Fail Before set disabled on optgroup, testing subject2 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Set disabled on optgroup, testing subject2
|
||||
Fail Unset disabled on optgroup, testing subject2 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Before set disabled on optgroup, testing subject3
|
||||
Pass Set disabled on optgroup, testing subject3
|
||||
Pass Unset disabled on optgroup, testing subject3
|
||||
Fail Before set disabled on optgroup, testing subject4 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Set disabled on optgroup, testing subject4
|
||||
Fail Unset disabled on optgroup, testing subject4 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Fail Before setting value of text_input, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Fail Set value of text_input, testing subject assert_equals: expected "rgb(255, 255, 0)" but got "rgb(255, 0, 0)"
|
||||
Fail Clear value of text_input, testing subject assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)"
|
||||
Fail Before setting value of text_input, testing subject2 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Set value of text_input, testing subject2
|
||||
Fail Clear value of text_input, testing subject2 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Before setting value of text_input, testing subject3
|
||||
Fail Set value of text_input, testing subject3 assert_equals: expected "rgb(255, 255, 0)" but got "rgb(128, 128, 128)"
|
||||
Pass Clear value of text_input, testing subject3
|
||||
Fail Before setting value of text_input, testing subject4 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
||||
Pass Set value of text_input, testing subject4
|
||||
Fail Clear value of text_input, testing subject4 assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)"
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has pseudo class behavior with explicit ':scope' in its argument</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto: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>
|
||||
|
||||
<main>
|
||||
<div id=d01 class="a">
|
||||
<div id=scope1 class="b">
|
||||
<div id=d02 class="c">
|
||||
<div id=d03 class="c">
|
||||
<div id=d04 class="d"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d05 class="e"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d06>
|
||||
<div id=scope2 class="b">
|
||||
<div id=d07 class="c">
|
||||
<div id=d08 class="c">
|
||||
<div id=d09></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function formatElements(elements) {
|
||||
return elements.map(e => e.id).sort().join();
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given elements in the given scope element
|
||||
function test_selector_all(scope, selector, expected) {
|
||||
test(function() {
|
||||
let actual = Array.from(scope.querySelectorAll(selector));
|
||||
assert_equals(formatElements(actual), formatElements(expected));
|
||||
}, `${selector} matches expected elements on ${scope.id}`);
|
||||
}
|
||||
|
||||
// Test that |selector1| and |selector2| returns same elements in the given scope element
|
||||
function compare_selector_all(scope, selector1, selector2) {
|
||||
test(function() {
|
||||
let result1 = Array.from(scope.querySelectorAll(selector1));
|
||||
let result2 = Array.from(scope.querySelectorAll(selector2));
|
||||
assert_equals(formatElements(result1), formatElements(result2));
|
||||
}, `${selector1} and ${selector2} returns same elements on ${scope.id}`);
|
||||
}
|
||||
|
||||
// descendants of a scope element cannot have the scope element as its descendant
|
||||
test_selector_all(scope1, ':has(:scope)', []);
|
||||
test_selector_all(scope1, ':has(:scope .c)', []);
|
||||
test_selector_all(scope1, ':has(.a :scope)', []);
|
||||
|
||||
// there can be more simple and efficient alternative for a ':scope' in ':has'
|
||||
test_selector_all(scope1, '.a:has(:scope) .c', [d02, d03]);
|
||||
compare_selector_all(scope1, '.a:has(:scope) .c', ':is(.a :scope .c)');
|
||||
test_selector_all(scope2, '.a:has(:scope) .c', []);
|
||||
compare_selector_all(scope2, '.a:has(:scope) .c', ':is(.a :scope .c)');
|
||||
test_selector_all(scope1, '.c:has(:is(:scope .d))', [d02, d03]);
|
||||
compare_selector_all(scope1, '.c:has(:is(:scope .d))', ':scope .c:has(.d)');
|
||||
compare_selector_all(scope1, '.c:has(:is(:scope .d))', '.c:has(.d)');
|
||||
test_selector_all(scope2, '.c:has(:is(:scope .d))', []);
|
||||
compare_selector_all(scope2, '.c:has(:is(:scope .d))', ':scope .c:has(.d)');
|
||||
compare_selector_all(scope2, '.c:has(:is(:scope .d))', '.c:has(.d)');
|
||||
</script>
|
|
@ -0,0 +1,81 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Basic matching behavior of :has pseudo class</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
|
||||
<main id=main>
|
||||
<div id=a class="ancestor">
|
||||
<div id=b class="parent ancestor">
|
||||
<div id=c class="sibling descendant">
|
||||
<div id=d class="descendant"></div>
|
||||
</div>
|
||||
<div id=e class="target descendant"></div>
|
||||
</div>
|
||||
<div id=f class="parent ancestor">
|
||||
<div id=g class="target descendant"></div>
|
||||
</div>
|
||||
<div id=h class="parent ancestor">
|
||||
<div id=i class="target descendant"></div>
|
||||
<div id=j class="sibling descendant">
|
||||
<div id=k class="descendant"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
function formatElements(elements) {
|
||||
return elements.map(e => e.id).sort().join();
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given elements in #main.
|
||||
function test_selector_all(selector, expected) {
|
||||
test(function() {
|
||||
let actual = Array.from(main.querySelectorAll(selector));
|
||||
assert_equals(formatElements(actual), formatElements(expected));
|
||||
}, `${selector} matches expected elements`);
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given element in #main.
|
||||
function test_selector(selector, expected) {
|
||||
test(function() {
|
||||
assert_equals(main.querySelector(selector), expected);
|
||||
}, `${selector} matches expected element`);
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given closest element.
|
||||
function test_closest(node, selector, expected) {
|
||||
test(function() {
|
||||
assert_equals(node.closest(selector), expected);
|
||||
}, `closest(${selector}) returns expected element`);
|
||||
}
|
||||
|
||||
// Test that |selector| returns matching status.
|
||||
function test_matches(node, selector, expected) {
|
||||
test(function() {
|
||||
assert_equals(node.matches(selector), expected);
|
||||
}, `${selector} matches expectedly`);
|
||||
}
|
||||
|
||||
test_selector_all(':has(#a)', []);
|
||||
test_selector_all(':has(.ancestor)', [a]);
|
||||
test_selector_all(':has(.target)', [a, b, f, h]);
|
||||
test_selector_all(':has(.descendant)', [a, b, c, f, h, j]);
|
||||
test_selector_all('.parent:has(.target)', [b, f, h]);
|
||||
test_selector_all(':has(.sibling ~ .target)', [a, b]);
|
||||
test_selector_all('.parent:has(.sibling ~ .target)', [b]);
|
||||
test_selector_all(':has(:is(.target ~ .sibling .descendant))', [a, h, j]);
|
||||
test_selector_all('.parent:has(:is(.target ~ .sibling .descendant))', [h]);
|
||||
test_selector_all('.sibling:has(.descendant) ~ .target', [e]);
|
||||
test_selector_all(':has(> .parent)', [a]);
|
||||
test_selector_all(':has(> .target)', [b, f, h]);
|
||||
test_selector_all(':has(> .parent, > .target)', [a, b, f, h]);
|
||||
test_selector_all(':has(+ #h)', [f]);
|
||||
test_selector_all('.parent:has(~ #h)', [b, f]);
|
||||
test_selector('.sibling:has(.descendant)', c);
|
||||
test_closest(k, '.ancestor:has(.descendant)', h);
|
||||
test_matches(h, ':has(.target ~ .sibling .descendant)', true);
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Matches :has pseudo class to uninserted elements</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
|
||||
<script>
|
||||
// Test that |selector| returns matching status.
|
||||
function test_matches(node, selector, expected) {
|
||||
test(function() {
|
||||
assert_equals(node.matches(selector), expected);
|
||||
}, `${selector} matches expectedly`);
|
||||
}
|
||||
|
||||
subject = document.createElement('subject');
|
||||
|
||||
subject.innerHTML = '<child></child>';
|
||||
test_matches(subject, ':has(child)', true);
|
||||
test_matches(subject, ':has(> child)', true);
|
||||
|
||||
subject.innerHTML = '<child><descendant></descendant></child>';
|
||||
test_matches(subject, ':has(descendant)', true);
|
||||
test_matches(subject, ':has(> descendant)', false);
|
||||
|
||||
subject.innerHTML = '<child></child><direct_sibling></direct_sibling><indirect_sibling></indirect_sibling>';
|
||||
test_matches(subject.firstChild, ':has(~ direct_sibling)', true);
|
||||
test_matches(subject.firstChild, ':has(+ direct_sibling)', true);
|
||||
test_matches(subject.firstChild, ':has(~ indirect_sibling)', true);
|
||||
test_matches(subject.firstChild, ':has(+ indirect_sibling)', false);
|
||||
|
||||
test_matches(subject, ':has(*)', true);
|
||||
test_matches(subject, ':has(> *)', true);
|
||||
test_matches(subject, ':has(~ *)', false);
|
||||
test_matches(subject, ':has(+ *)', false);
|
||||
</script>
|
|
@ -0,0 +1,184 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has pseudo class behavior with various relative arguments</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
|
||||
<main id=main>
|
||||
<div id=d01>
|
||||
<div id=d02 class="x">
|
||||
<div id=d03 class="a"></div>
|
||||
<div id=d04></div>
|
||||
<div id=d05 class="b"></div>
|
||||
</div>
|
||||
<div id=d06 class="x">
|
||||
<div id=d07 class="x">
|
||||
<div id=d08 class="a"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d09 class="x">
|
||||
<div id=d10 class="a">
|
||||
<div id=d11 class="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d12 class="x">
|
||||
<div id=d13 class="a">
|
||||
<div id=d14>
|
||||
<div id=d15 class="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d16 class="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d17>
|
||||
<div id=d18 class="x"></div>
|
||||
<div id=d19 class="x"></div>
|
||||
<div id=d20 class="a"></div>
|
||||
<div id=d21 class="x"></div>
|
||||
<div id=d22 class="a">
|
||||
<div id=d23 class="b"></div>
|
||||
</div>
|
||||
<div id=d24 class="x"></div>
|
||||
<div id=d25 class="a">
|
||||
<div id=d26>
|
||||
<div id=d27 class="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d28 class="x"></div>
|
||||
<div id=d29 class="a"></div>
|
||||
<div id=d30 class="b">
|
||||
<div id=d31 class="c"></div>
|
||||
</div>
|
||||
<div id=d32 class="x"></div>
|
||||
<div id=d33 class="a"></div>
|
||||
<div id=d34 class="b">
|
||||
<div id=d35>
|
||||
<div id=d36 class="c"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d37 class="x"></div>
|
||||
<div id=d38 class="a"></div>
|
||||
<div id=d39 class="b"></div>
|
||||
<div id=d40 class="x"></div>
|
||||
<div id=d41 class="a"></div>
|
||||
<div id=d42></div>
|
||||
<div id=d43 class="b">
|
||||
<div id=d44 class="x">
|
||||
<div id=d45 class="c"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d46 class="x"></div>
|
||||
<div id=d47 class="a">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div id=d48 class="x">
|
||||
<div id=d49 class="x">
|
||||
<div id=d50 class="x d">
|
||||
<div id=d51 class="x d">
|
||||
<div id=d52 class="x">
|
||||
<div id=d53 class="x e">
|
||||
<div id=d54 class="f"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d55 class="x"></div>
|
||||
<div id=d56 class="x d"></div>
|
||||
<div id=d57 class="x d"></div>
|
||||
<div id=d58 class="x"></div>
|
||||
<div id=d59 class="x e"></div>
|
||||
<div id=d60 class="f"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div id=d61 class="x"></div>
|
||||
<div id=d62 class="x y"></div>
|
||||
<div id=d63 class="x y">
|
||||
<div id=d64 class="y g">
|
||||
<div id=d65 class="y">
|
||||
<div id=d66 class="y h">
|
||||
<div id=d67 class="i"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d68 class="x y">
|
||||
<div id=d69 class="x"></div>
|
||||
<div id=d70 class="x"></div>
|
||||
<div id=d71 class="x y">
|
||||
<div id=d72 class="y g">
|
||||
<div id=d73 class="y">
|
||||
<div id=d74 class="y h">
|
||||
<div id=d75 class="i"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=d76 class="x"></div>
|
||||
<div id=d77 class="j"><div id=d78><div id=d79></div></div></div>
|
||||
</div>
|
||||
<div id=d80 class="j"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
function formatElements(elements) {
|
||||
return elements.map(e => e.id).sort().join();
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given elements in #main.
|
||||
function test_selector_all(selector, expected) {
|
||||
test(function() {
|
||||
let actual = Array.from(main.querySelectorAll(selector));
|
||||
assert_equals(formatElements(actual), formatElements(expected));
|
||||
}, `${selector} matches expected elements`);
|
||||
}
|
||||
|
||||
test_selector_all('.x:has(.a)', [d02, d06, d07, d09, d12]);
|
||||
test_selector_all('.x:has(.a > .b)', [d09]);
|
||||
test_selector_all('.x:has(.a .b)', [d09, d12]);
|
||||
test_selector_all('.x:has(.a + .b)', [d12]);
|
||||
test_selector_all('.x:has(.a ~ .b)', [d02, d12]);
|
||||
|
||||
test_selector_all('.x:has(> .a)', [d02, d07, d09, d12]);
|
||||
test_selector_all('.x:has(> .a > .b)', [d09]);
|
||||
test_selector_all('.x:has(> .a .b)', [d09, d12]);
|
||||
test_selector_all('.x:has(> .a + .b)', [d12]);
|
||||
test_selector_all('.x:has(> .a ~ .b)', [d02, d12]);
|
||||
|
||||
test_selector_all('.x:has(+ .a)', [d19, d21, d24, d28, d32, d37, d40, d46]);
|
||||
test_selector_all('.x:has(+ .a > .b)', [d21]);
|
||||
test_selector_all('.x:has(+ .a .b)', [d21, d24]);
|
||||
test_selector_all('.x:has(+ .a + .b)', [d28, d32, d37]);
|
||||
test_selector_all('.x:has(+ .a ~ .b)', [d19, d21, d24, d28, d32, d37, d40]);
|
||||
|
||||
test_selector_all('.x:has(~ .a)', [d18, d19, d21, d24, d28, d32, d37, d40, d46]);
|
||||
test_selector_all('.x:has(~ .a > .b)', [d18, d19, d21]);
|
||||
test_selector_all('.x:has(~ .a .b)', [d18, d19, d21, d24]);
|
||||
test_selector_all('.x:has(~ .a + .b)', [d18, d19, d21, d24, d28, d32, d37]);
|
||||
test_selector_all('.x:has(~ .a + .b > .c)', [d18, d19, d21, d24, d28]);
|
||||
test_selector_all('.x:has(~ .a + .b .c)', [d18, d19, d21, d24, d28, d32]);
|
||||
|
||||
test_selector_all('.x:has(.d .e)', [d48, d49, d50]);
|
||||
test_selector_all('.x:has(.d .e) .f', [d54]);
|
||||
test_selector_all('.x:has(> .d)', [d49, d50]);
|
||||
test_selector_all('.x:has(> .d) .f', [d54]);
|
||||
test_selector_all('.x:has(~ .d ~ .e)', [d48, d55, d56]);
|
||||
test_selector_all('.x:has(~ .d ~ .e) ~ .f', [d60]);
|
||||
test_selector_all('.x:has(+ .d ~ .e)', [d55, d56]);
|
||||
test_selector_all('.x:has(+ .d ~ .e) ~ .f', [d60]);
|
||||
|
||||
test_selector_all('.y:has(> .g .h)', [d63, d71])
|
||||
test_selector_all('.y:has(.g .h)', [d63, d68, d71])
|
||||
test_selector_all('.y:has(> .g .h) .i', [d67, d75])
|
||||
test_selector_all('.y:has(.g .h) .i', [d67, d75])
|
||||
|
||||
test_selector_all('.d .x:has(.e)', [d51, d52])
|
||||
|
||||
test_selector_all('.d ~ .x:has(~ .e)', [d57, d58])
|
||||
|
||||
</script>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Selectors Test: Chrome crash issue 1470477</title>
|
||||
<link rel="help" href="https://crbug.com/1470477">
|
||||
<style>
|
||||
:has(> :where(label:first-child + [a="a"]:only-of-type,
|
||||
[a="a"]:only-of-type + label:last-child)) label:last-child {
|
||||
margin-inline: 1em;
|
||||
}
|
||||
</style>
|
||||
<p>PASS if this tests does not crash</p>
|
||||
<script>
|
||||
if (window.internals)
|
||||
window.internals.signalTextTestIsDone("PASS");
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Specificity for complex :has selectors</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#specificity-rules">
|
||||
<style>
|
||||
main :has(#foo) { --t0:PASS; }
|
||||
main :has(.foo) { --t0:FAIL; }
|
||||
|
||||
main :has(span#foo) { --t1:PASS; }
|
||||
main :has(#foo) { --t1:FAIL; }
|
||||
|
||||
main :has(.bar, #foo) { --t2:FAIL; }
|
||||
main :has(#foo, .bar) { --t2:PASS; }
|
||||
|
||||
main :has(.bar, #foo) { --t3:PASS; }
|
||||
main :has(.foo, .bar) { --t3:FAIL; }
|
||||
|
||||
main :has(span + span) { --t4:PASS; }
|
||||
main :has(span) { --t4:FAIL; }
|
||||
|
||||
main :has(span, li, #foo) { --t5:PASS; }
|
||||
main :has(span, li, p) { --t5:FAIL; }
|
||||
|
||||
main div:has(.foo) { --t6:FAIL; }
|
||||
main div.baz { --t6:PASS; }
|
||||
|
||||
main div.baz { --t7:FAIL; }
|
||||
main div:has(.foo) { --t7:PASS; }
|
||||
</style>
|
||||
<main id=main>
|
||||
<div id=div class=baz><p><span id=foo class=foo></span><span class=bar></span><li></li></p></div>
|
||||
</main>
|
||||
<script>
|
||||
function test_value(name, description) {
|
||||
test(function() {
|
||||
let actual = getComputedStyle(div).getPropertyValue(name);
|
||||
assert_equals(actual, 'PASS');
|
||||
}, description);
|
||||
}
|
||||
|
||||
test_value('--t0', ':has(#foo) wins over :has(.foo)');
|
||||
test_value('--t1', ':has(span#foo) wins over :has(#foo)');
|
||||
test_value('--t2', ':has(.bar, #foo) has same specificity as :has(#foo, .bar)');
|
||||
test_value('--t3', ':has(.bar, #foo) wins over :has(.foo, .bar)');
|
||||
test_value('--t4', ':has(span + span) wins over :has(span)');
|
||||
test_value('--t5', ':has(span, li, p) wins over :has(span, lo, p)');
|
||||
test_value('--t6', 'latter .baz wins over :has(.foo)');
|
||||
test_value('--t7', 'latter :has(.foo) wins over .baz');
|
||||
</script>
|
|
@ -0,0 +1,105 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has() invalidation with nesting where the selector is shared</title>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#outer1:has(.test) {
|
||||
& #subject1_1 {
|
||||
color: red;
|
||||
}
|
||||
& + #subject1_2 {
|
||||
color: orangered;
|
||||
}
|
||||
}
|
||||
|
||||
#outer2:has(.test) {
|
||||
& .ancestor {
|
||||
& #subject2_1 {
|
||||
color: green;
|
||||
}
|
||||
& + #subject2_2 {
|
||||
color: lightgreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#outer3:is(:has(.test) .outer) {
|
||||
& #subject3_1 {
|
||||
color: blue;
|
||||
}
|
||||
& + #subject3_2 {
|
||||
color: skyblue;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<main id="main">
|
||||
<div>
|
||||
<div id="outer1">
|
||||
<div id="trigger1"></div>
|
||||
<div id="subject1_1"></div>
|
||||
</div>
|
||||
<div id="subject1_2"></div>
|
||||
</div>
|
||||
<div id="outer2">
|
||||
<div id="trigger2"></div>
|
||||
<div class="ancestor">
|
||||
<div id="subject2_1"></div>
|
||||
</div>
|
||||
<div id="subject2_2"></div>
|
||||
</div>
|
||||
<div id="trigger3">
|
||||
<div id="outer3" class="outer">
|
||||
<div id="subject3_1"></div>
|
||||
</div>
|
||||
<div id="subject3_2"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const orangered = 'rgb(255, 69, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const lightgreen = 'rgb(144, 238, 144)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const skyblue = 'rgb(135, 206, 235)';
|
||||
|
||||
const colors = {
|
||||
red: {
|
||||
descendant: red,
|
||||
sibling: orangered,
|
||||
},
|
||||
green: {
|
||||
descendant: green,
|
||||
sibling: lightgreen,
|
||||
},
|
||||
blue: {
|
||||
descendant: blue,
|
||||
sibling: skyblue,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(testName, element, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(element).color, color);
|
||||
}, testName);
|
||||
}
|
||||
|
||||
function testClassChange(trigger, targetDescendant, targetSibling, expected)
|
||||
{
|
||||
trigger.classList.add('test');
|
||||
testColor(`add .test to ${trigger.id} - check ${targetDescendant.id}`, targetDescendant, colors[expected].descendant);
|
||||
testColor(`add .test to ${trigger.id} - check ${targetSibling.id}`, targetSibling, colors[expected].sibling);
|
||||
trigger.classList.remove('test');
|
||||
testColor(`remove .test from ${trigger.id} - check ${targetDescendant.id}`, targetDescendant, grey);
|
||||
testColor(`remove .test from ${trigger.id} - check ${targetSibling.id}`, targetSibling, grey);
|
||||
}
|
||||
|
||||
testClassChange(trigger1, subject1_1, subject1_2, 'red');
|
||||
testClassChange(trigger2, subject2_1, subject2_2, 'green');
|
||||
testClassChange(trigger3, subject3_1, subject3_2, 'blue');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,312 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() in adjacent position</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
div:has(.test) + #subject { color: red }
|
||||
div:has([test_attr]) + #subject { color: orangered }
|
||||
div:has(> .test) + #subject { color: green }
|
||||
div:has(> [test_attr]) + #subject { color: lightgreen }
|
||||
div:has(~ .test) + #subject { color: yellow }
|
||||
div:has(~ [test_attr]) + #subject { color: ivory }
|
||||
div:has(+ .test) + #subject { color: blue }
|
||||
div:has(+ [test_attr]) + #subject { color: skyblue }
|
||||
div:has(~ div .test) + #subject { color: purple }
|
||||
div:has(~ div [test_attr]) + #subject { color: violet }
|
||||
div:has(+ div .test) + #subject { color: pink }
|
||||
div:has(+ div [test_attr]) + #subject { color: lightpink }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=previous_sibling>
|
||||
<div id=previous_sibling_child>
|
||||
<div id=previous_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=subject></div>
|
||||
<div id=next_sibling>
|
||||
<div id=next_sibling_child>
|
||||
<div id=next_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const orangered = 'rgb(255, 69, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const lightgreen = 'rgb(144, 238, 144)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const skyblue = 'rgb(135, 206, 235)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const ivory = 'rgb(255, 255, 240)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const violet = 'rgb(238, 130, 238)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
const lightpink = 'rgb(255, 182, 193)';
|
||||
const colors = {
|
||||
grey: {
|
||||
classTest: grey,
|
||||
attributeTest: grey,
|
||||
},
|
||||
red: {
|
||||
classTest: red,
|
||||
attributeTest: orangered,
|
||||
},
|
||||
green: {
|
||||
classTest: green,
|
||||
attributeTest: lightgreen,
|
||||
},
|
||||
blue: {
|
||||
classTest: blue,
|
||||
attributeTest: skyblue,
|
||||
},
|
||||
yellow: {
|
||||
classTest: yellow,
|
||||
attributeTest: ivory,
|
||||
},
|
||||
purple: {
|
||||
classTest: purple,
|
||||
attributeTest: violet,
|
||||
},
|
||||
pink: {
|
||||
classTest: pink,
|
||||
attributeTest: lightpink,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
element.classList.add('test');
|
||||
testColor(`add .test to ${element.id}`, expectedColorForClassTest);
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div>div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div>div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(previous_sibling, "grey");
|
||||
testClassChange(previous_sibling_child, "green");
|
||||
testClassChange(previous_sibling_descendant, "red");
|
||||
testClassChange(subject, "blue");
|
||||
testClassChange(next_sibling, "yellow");
|
||||
testClassChange(next_sibling_child, "purple");
|
||||
testClassChange(next_sibling_descendant, "purple");
|
||||
|
||||
testElementInsertionBefore(previous_sibling, "grey");
|
||||
testElementInsertionBefore(previous_sibling_child, "green");
|
||||
testElementInsertionBefore(previous_sibling_descendant, "red");
|
||||
testElementInsertionBefore(subject, "grey");
|
||||
testElementInsertionBefore(next_sibling, "yellow");
|
||||
testElementInsertionBefore(next_sibling_child, "purple");
|
||||
testElementInsertionBefore(next_sibling_descendant, "purple");
|
||||
|
||||
testElementInsertionAfter(previous_sibling, "grey");
|
||||
testElementInsertionAfter(previous_sibling_child, "green");
|
||||
testElementInsertionAfter(previous_sibling_descendant, "red");
|
||||
testElementInsertionAfter(subject, "yellow");
|
||||
testElementInsertionAfter(next_sibling, "yellow");
|
||||
testElementInsertionAfter(next_sibling_child, "purple");
|
||||
testElementInsertionAfter(next_sibling_descendant, "purple");
|
||||
|
||||
testTreeInsertionBefore(previous_sibling, "grey");
|
||||
testTreeInsertionBefore(previous_sibling_child, "red");
|
||||
testTreeInsertionBefore(previous_sibling_descendant, "red");
|
||||
testTreeInsertionBefore(subject, "green");
|
||||
testTreeInsertionBefore(next_sibling, "purple");
|
||||
testTreeInsertionBefore(next_sibling_child, "purple");
|
||||
testTreeInsertionBefore(next_sibling_descendant, "purple");
|
||||
|
||||
testTreeInsertionAfter(previous_sibling, "green");
|
||||
testTreeInsertionAfter(previous_sibling_child, "red");
|
||||
testTreeInsertionAfter(previous_sibling_descendant, "red");
|
||||
testTreeInsertionAfter(subject, "purple");
|
||||
testTreeInsertionAfter(next_sibling, "purple");
|
||||
testTreeInsertionAfter(next_sibling_child, "purple");
|
||||
testTreeInsertionAfter(next_sibling_descendant, "purple");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,320 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() in ancestor position</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
div:has(.test) #subject { color: red }
|
||||
div:has([test_attr]) #subject { color: orangered }
|
||||
div:has(> .test) #subject { color: green }
|
||||
div:has(> [test_attr]) #subject { color: lightgreen }
|
||||
div:has(~ .test) #subject { color: yellow }
|
||||
div:has(~ [test_attr]) #subject { color: ivory }
|
||||
div:has(+ .test) #subject { color: blue }
|
||||
div:has(+ [test_attr]) #subject { color: skyblue }
|
||||
div:has(~ div .test) #subject { color: purple }
|
||||
div:has(~ div [test_attr]) #subject { color: violet }
|
||||
div:has(+ div .test) #subject { color: pink }
|
||||
div:has(+ div [test_attr]) #subject { color: lightpink }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=subject_ancestor>
|
||||
<div id=subject_parent>
|
||||
<div id=subject>
|
||||
<div id=subject_child>
|
||||
<div id=subject_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=next_sibling>
|
||||
<div id=next_sibling_child>
|
||||
<div id=next_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const orangered = 'rgb(255, 69, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const lightgreen = 'rgb(144, 238, 144)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const skyblue = 'rgb(135, 206, 235)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const ivory = 'rgb(255, 255, 240)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const violet = 'rgb(238, 130, 238)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
const lightpink = 'rgb(255, 182, 193)';
|
||||
const colors = {
|
||||
grey: {
|
||||
classTest: grey,
|
||||
attributeTest: grey,
|
||||
},
|
||||
red: {
|
||||
classTest: red,
|
||||
attributeTest: orangered,
|
||||
},
|
||||
green: {
|
||||
classTest: green,
|
||||
attributeTest: lightgreen,
|
||||
},
|
||||
blue: {
|
||||
classTest: blue,
|
||||
attributeTest: skyblue,
|
||||
},
|
||||
yellow: {
|
||||
classTest: yellow,
|
||||
attributeTest: ivory,
|
||||
},
|
||||
purple: {
|
||||
classTest: purple,
|
||||
attributeTest: violet,
|
||||
},
|
||||
pink: {
|
||||
classTest: pink,
|
||||
attributeTest: lightpink,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
element.classList.add('test');
|
||||
testColor(`add .test to ${element.id}`, expectedColorForClassTest);
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div>div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div>div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(subject_ancestor, "grey");
|
||||
testClassChange(subject_parent, "green");
|
||||
testClassChange(subject, "green");
|
||||
testClassChange(subject_child, "red");
|
||||
testClassChange(subject_descendant, "red");
|
||||
testClassChange(next_sibling, "blue");
|
||||
testClassChange(next_sibling_child, "pink");
|
||||
testClassChange(next_sibling_descendant, "pink");
|
||||
|
||||
testElementInsertionBefore(subject_ancestor, "grey");
|
||||
testElementInsertionBefore(subject_parent, "green");
|
||||
testElementInsertionBefore(subject, "green");
|
||||
testElementInsertionBefore(subject_child, "red");
|
||||
testElementInsertionBefore(subject_descendant, "red");
|
||||
testElementInsertionBefore(next_sibling, "blue");
|
||||
testElementInsertionBefore(next_sibling_child, "pink");
|
||||
testElementInsertionBefore(next_sibling_descendant, "pink");
|
||||
|
||||
testElementInsertionAfter(subject_ancestor, "blue");
|
||||
testElementInsertionAfter(subject_parent, "blue");
|
||||
testElementInsertionAfter(subject, "green");
|
||||
testElementInsertionAfter(subject_child, "red");
|
||||
testElementInsertionAfter(subject_descendant, "red");
|
||||
testElementInsertionAfter(next_sibling, "yellow");
|
||||
testElementInsertionAfter(next_sibling_child, "pink");
|
||||
testElementInsertionAfter(next_sibling_descendant, "pink");
|
||||
|
||||
testTreeInsertionBefore(subject_ancestor, "grey");
|
||||
testTreeInsertionBefore(subject_parent, "red");
|
||||
testTreeInsertionBefore(subject, "red");
|
||||
testTreeInsertionBefore(subject_child, "red");
|
||||
testTreeInsertionBefore(subject_descendant, "red");
|
||||
testTreeInsertionBefore(next_sibling, "pink");
|
||||
testTreeInsertionBefore(next_sibling_child, "pink");
|
||||
testTreeInsertionBefore(next_sibling_descendant, "pink");
|
||||
|
||||
testTreeInsertionAfter(subject_ancestor, "pink");
|
||||
testTreeInsertionAfter(subject_parent, "pink");
|
||||
testTreeInsertionAfter(subject, "red");
|
||||
testTreeInsertionAfter(subject_child, "red");
|
||||
testTreeInsertionAfter(subject_descendant, "red");
|
||||
testTreeInsertionAfter(next_sibling, "purple");
|
||||
testTreeInsertionAfter(next_sibling_child, "pink");
|
||||
testTreeInsertionAfter(next_sibling_descendant, "pink");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,300 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() in parent position</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
div:has(.test) > #subject { color: red }
|
||||
div:has([test_attr]) > #subject { color: orangered }
|
||||
div:has(> .test) > #subject { color: green }
|
||||
div:has(> [test_attr]) > #subject { color: lightgreen }
|
||||
div:has(~ .test) > #subject { color: yellow }
|
||||
div:has(~ [test_attr]) > #subject { color: ivory }
|
||||
div:has(+ .test) > #subject { color: blue }
|
||||
div:has(+ [test_attr]) > #subject { color: skyblue }
|
||||
div:has(~ div .test) > #subject { color: purple }
|
||||
div:has(~ div [test_attr]) > #subject { color: violet }
|
||||
div:has(+ div .test) > #subject { color: pink }
|
||||
div:has(+ div [test_attr]) > #subject { color: lightpink }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=subject_ancestor>
|
||||
<div id=subject_parent>
|
||||
<div id=subject>
|
||||
<div id=subject_child>
|
||||
<div id=subject_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const orangered = 'rgb(255, 69, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const lightgreen = 'rgb(144, 238, 144)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const skyblue = 'rgb(135, 206, 235)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const ivory = 'rgb(255, 255, 240)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const violet = 'rgb(238, 130, 238)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
const lightpink = 'rgb(255, 182, 193)';
|
||||
const colors = {
|
||||
grey: {
|
||||
classTest: grey,
|
||||
attributeTest: grey,
|
||||
},
|
||||
red: {
|
||||
classTest: red,
|
||||
attributeTest: orangered,
|
||||
},
|
||||
green: {
|
||||
classTest: green,
|
||||
attributeTest: lightgreen,
|
||||
},
|
||||
blue: {
|
||||
classTest: blue,
|
||||
attributeTest: skyblue,
|
||||
},
|
||||
yellow: {
|
||||
classTest: yellow,
|
||||
attributeTest: ivory,
|
||||
},
|
||||
purple: {
|
||||
classTest: purple,
|
||||
attributeTest: violet,
|
||||
},
|
||||
pink: {
|
||||
classTest: pink,
|
||||
attributeTest: lightpink,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
element.classList.add('test');
|
||||
testColor(`add .test to ${element.id}`, expectedColorForClassTest);
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div>div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div>div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(subject_ancestor, "grey");
|
||||
testClassChange(subject_parent, "grey");
|
||||
testClassChange(subject, "green");
|
||||
testClassChange(subject_child, "red");
|
||||
testClassChange(subject_descendant, "red");
|
||||
|
||||
testElementInsertionBefore(subject_ancestor, "grey");
|
||||
testElementInsertionBefore(subject_parent, "grey");
|
||||
testElementInsertionBefore(subject, "green");
|
||||
testElementInsertionBefore(subject_child, "red");
|
||||
testElementInsertionBefore(subject_descendant, "red");
|
||||
|
||||
testElementInsertionAfter(subject_ancestor, "grey");
|
||||
testElementInsertionAfter(subject_parent, "blue");
|
||||
testElementInsertionAfter(subject, "green");
|
||||
testElementInsertionAfter(subject_child, "red");
|
||||
testElementInsertionAfter(subject_descendant, "red");
|
||||
|
||||
testTreeInsertionBefore(subject_ancestor, "grey");
|
||||
testTreeInsertionBefore(subject_parent, "grey");
|
||||
testTreeInsertionBefore(subject, "red");
|
||||
testTreeInsertionBefore(subject_child, "red");
|
||||
testTreeInsertionBefore(subject_descendant, "red");
|
||||
|
||||
testTreeInsertionAfter(subject_ancestor, "grey");
|
||||
testTreeInsertionAfter(subject_parent, "pink");
|
||||
testTreeInsertionAfter(subject, "red");
|
||||
testTreeInsertionAfter(subject_child, "red");
|
||||
testTreeInsertionAfter(subject_descendant, "red");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,312 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() in sibling position</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
div:has(.test) ~ #subject { color: red }
|
||||
div:has([test_attr]) ~ #subject { color: orangered }
|
||||
div:has(> .test) ~ #subject { color: green }
|
||||
div:has(> [test_attr]) ~ #subject { color: lightgreen }
|
||||
div:has(~ .test) ~ #subject { color: yellow }
|
||||
div:has(~ [test_attr]) ~ #subject { color: ivory }
|
||||
div:has(+ .test) ~ #subject { color: blue }
|
||||
div:has(+ [test_attr]) ~ #subject { color: skyblue }
|
||||
div:has(~ div .test) ~ #subject { color: purple }
|
||||
div:has(~ div [test_attr]) ~ #subject { color: violet }
|
||||
div:has(+ div .test) ~ #subject { color: pink }
|
||||
div:has(+ div [test_attr]) ~ #subject { color: lightpink }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=previous_sibling>
|
||||
<div id=previous_sibling_child>
|
||||
<div id=previous_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=subject></div>
|
||||
<div id=next_sibling>
|
||||
<div id=next_sibling_child>
|
||||
<div id=next_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const orangered = 'rgb(255, 69, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const lightgreen = 'rgb(144, 238, 144)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const skyblue = 'rgb(135, 206, 235)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const ivory = 'rgb(255, 255, 240)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const violet = 'rgb(238, 130, 238)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
const lightpink = 'rgb(255, 182, 193)';
|
||||
const colors = {
|
||||
grey: {
|
||||
classTest: grey,
|
||||
attributeTest: grey,
|
||||
},
|
||||
red: {
|
||||
classTest: red,
|
||||
attributeTest: orangered,
|
||||
},
|
||||
green: {
|
||||
classTest: green,
|
||||
attributeTest: lightgreen,
|
||||
},
|
||||
blue: {
|
||||
classTest: blue,
|
||||
attributeTest: skyblue,
|
||||
},
|
||||
yellow: {
|
||||
classTest: yellow,
|
||||
attributeTest: ivory,
|
||||
},
|
||||
purple: {
|
||||
classTest: purple,
|
||||
attributeTest: violet,
|
||||
},
|
||||
pink: {
|
||||
classTest: pink,
|
||||
attributeTest: lightpink,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
element.classList.add('test');
|
||||
testColor(`add .test to ${element.id}`, expectedColorForClassTest);
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test')
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.classList.add('test');
|
||||
testColor(`add the class 'test' to the element inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div.test before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again before ${beforeElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again before ${beforeElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div before ${beforeElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div>div[test_attr] before ${beforeElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
const expectedColorForAttributeTest = colors[expectedColorName].attributeTest;
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div.test after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' again to the element in the tree inserted after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.classList.add('test');
|
||||
testColor(`add the class 'test' to the element in the tree inserted again after ${afterElement.id}`, expectedColorForClassTest);
|
||||
|
||||
newChild.classList.remove('test');
|
||||
testColor(`remove the class 'test' from the element in the tree inserted again after ${afterElement.id}`, grey);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div after ${afterElement.id}`, grey);
|
||||
|
||||
newChild.setAttribute('test_attr', '');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div>div[test_attr] after ${afterElement.id}`, expectedColorForAttributeTest);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div>div[test_attr] after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(previous_sibling, "grey");
|
||||
testClassChange(previous_sibling_child, "green");
|
||||
testClassChange(previous_sibling_descendant, "red");
|
||||
testClassChange(subject, "blue");
|
||||
testClassChange(next_sibling, "yellow");
|
||||
testClassChange(next_sibling_child, "purple");
|
||||
testClassChange(next_sibling_descendant, "purple");
|
||||
|
||||
testElementInsertionBefore(previous_sibling, "grey");
|
||||
testElementInsertionBefore(previous_sibling_child, "green");
|
||||
testElementInsertionBefore(previous_sibling_descendant, "red");
|
||||
testElementInsertionBefore(subject, "blue");
|
||||
testElementInsertionBefore(next_sibling, "yellow");
|
||||
testElementInsertionBefore(next_sibling_child, "purple");
|
||||
testElementInsertionBefore(next_sibling_descendant, "purple");
|
||||
|
||||
testElementInsertionAfter(previous_sibling, "blue");
|
||||
testElementInsertionAfter(previous_sibling_child, "green");
|
||||
testElementInsertionAfter(previous_sibling_descendant, "red");
|
||||
testElementInsertionAfter(subject, "yellow");
|
||||
testElementInsertionAfter(next_sibling, "yellow");
|
||||
testElementInsertionAfter(next_sibling_child, "purple");
|
||||
testElementInsertionAfter(next_sibling_descendant, "purple");
|
||||
|
||||
testTreeInsertionBefore(previous_sibling, "green");
|
||||
testTreeInsertionBefore(previous_sibling_child, "red");
|
||||
testTreeInsertionBefore(previous_sibling_descendant, "red");
|
||||
testTreeInsertionBefore(subject, "pink");
|
||||
testTreeInsertionBefore(next_sibling, "purple");
|
||||
testTreeInsertionBefore(next_sibling_child, "purple");
|
||||
testTreeInsertionBefore(next_sibling_descendant, "purple");
|
||||
|
||||
testTreeInsertionAfter(previous_sibling, "pink");
|
||||
testTreeInsertionAfter(previous_sibling_child, "red");
|
||||
testTreeInsertionAfter(previous_sibling_descendant, "red");
|
||||
testTreeInsertionAfter(subject, "purple");
|
||||
testTreeInsertionAfter(next_sibling, "purple");
|
||||
testTreeInsertionAfter(next_sibling_child, "purple");
|
||||
testTreeInsertionAfter(next_sibling_descendant, "purple");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has() invalidation after removing non-first element</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject:has(descendant) { color: red }
|
||||
</style>
|
||||
<main id="main">
|
||||
<div id="subject">
|
||||
<div></div>
|
||||
<descendant id="descendant"></descendant>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
let grey = 'rgb(128, 128, 128)';
|
||||
let red = 'rgb(255, 0, 0)';
|
||||
|
||||
function test_div(test_name, el, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(el).color, color);
|
||||
}, test_name + ': div#' + el.id + '.color');
|
||||
}
|
||||
|
||||
test_div('initial_color', subject, red);
|
||||
subject.removeChild(descendant);
|
||||
test_div('remove descendant', subject, grey);
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has() invalidation for wiping an element by means of innerHTML</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
.subject:has(.descendant) { color: green}
|
||||
</style>
|
||||
<main id=main>
|
||||
<div id="subject" class="subject"></div>
|
||||
</main>
|
||||
<script>
|
||||
let grey = 'rgb(128, 128, 128)';
|
||||
let green = 'rgb(0, 128, 0)';
|
||||
|
||||
function test_div(test_name, el, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(el).color, color);
|
||||
}, test_name + ': div#' + el.id + '.color');
|
||||
}
|
||||
|
||||
test_div('initial color', subject, grey);
|
||||
|
||||
subject.innerHTML = "This is a text <div><div class='descendant'></div></div>";
|
||||
|
||||
test_div('color after inserting text and div > .descendant', subject, green);
|
||||
|
||||
subject.innerHTML = "This is a text";
|
||||
|
||||
test_div('color after wiping #child to remove div > .descendant', subject, grey);
|
||||
|
||||
subject.innerHTML = "<div id='child'> This is a text <div class='descendant'></div></div>";
|
||||
|
||||
test_div('color after inserting text and #child > .descendant', subject, green);
|
||||
|
||||
child.innerHTML = "This is a text";
|
||||
|
||||
test_div('color after wiping #child to remove .descendant', subject, grey);
|
||||
</script>
|
|
@ -0,0 +1,209 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>:has() invalidation for sibling insertion and removal</title>
|
||||
<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject1:has(+ #sibling1_1 + #sibling1_2) { color: red }
|
||||
#subject2:has(+ #sibling2_2) { color: green }
|
||||
#subject3:has(+ #sibling3_1 + #sibling3_2 > #siblingchild3_2_1) { color: blue }
|
||||
#subject4:has(+ #sibling4_2 > #siblingchild4_2_1) { color: yellow }
|
||||
#subject5:has(+ #sibling5_1 + #sibling5_2) { color: red }
|
||||
#subject6:has(+ #sibling6_2) { color: green }
|
||||
#subject7:has(+ #sibling7_1 + #sibling7_2 > #siblingchild7_2_1) { color: blue }
|
||||
#subject8:has(+ #sibling8_2 > #siblingchild8_2_1) { color: yellow }
|
||||
#subject9:has(+ #sibling9_1 + #sibling9_2 ~ #sibling9_3) { color: red }
|
||||
#subject10:has(+ #sibling10_2 ~ #sibling10_3) { color: green }
|
||||
#subject11:has(+ #sibling11_1 + #sibling11_2 ~ #sibling11_3 > #siblingchild11_3_1) { color: blue }
|
||||
#subject12:has(+ #sibling12_2 ~ #sibling12_3 > #siblingchild12_3_1) { color: yellow }
|
||||
.sibling13:has(~ .sibling13) { color: green }
|
||||
#subject14:has(~ #sibling14_1 ~ #sibling14_2 ~ #sibling14_3) { color: green }
|
||||
</style>
|
||||
|
||||
<main id="main">
|
||||
<div id="parent1">
|
||||
<div id="subject1"></div>
|
||||
<div id="sibling1_2"></div>
|
||||
<div id="sibling1_3"></div>
|
||||
</div>
|
||||
<div id="parent2">
|
||||
<div id="subject2"></div>
|
||||
<div id="sibling2_1"></div>
|
||||
<div id="sibling2_2"></div>
|
||||
<div id="sibling2_3""></div>
|
||||
</div>
|
||||
<div id="parent3">
|
||||
<div id="subject3"></div>
|
||||
<div id="sibling3_2">
|
||||
<div id="siblingchild3_2_1"></div>
|
||||
</div>
|
||||
<div id="sibling3_3"></div>
|
||||
</div>
|
||||
<div id="parent4">
|
||||
<div id="subject4"></div>
|
||||
<div id="sibling4_1"></div>
|
||||
<div id="sibling4_2">
|
||||
<div id="siblingchild4_2_1"></div>
|
||||
</div>
|
||||
<div id="sibling4_3"></div>
|
||||
</div>
|
||||
<div id="parent5">
|
||||
<div id="subject5"></div>
|
||||
<div id="sibling5_1"></div>
|
||||
<div id="sibling5_2"></div>
|
||||
<div id="sibling5_3""></div>
|
||||
</div>
|
||||
<div id="parent6">
|
||||
<div id="subject6"></div>
|
||||
<div id="sibling6_2"></div>
|
||||
<div id="sibling6_3"></div>
|
||||
</div>
|
||||
<div id="parent7">
|
||||
<div id="subject7"></div>
|
||||
<div id="sibling7_1"></div>
|
||||
<div id="sibling7_2">
|
||||
<div id="siblingchild7_2_1"></div>
|
||||
</div>
|
||||
<div id="sibling7_3"></div>
|
||||
<div id="parent8">
|
||||
<div id="subject8"></div>
|
||||
<div id="sibling8_2">
|
||||
<div id="siblingchild8_2_1"></div>
|
||||
</div>
|
||||
<div id="sibling8_3"></div>
|
||||
</div>
|
||||
<div id="parent9">
|
||||
<div id="subject9"></div>
|
||||
<div id="sibling9_2"></div>
|
||||
<div id="sibling9_3"></div>
|
||||
<div id="sibling9_4"></div>
|
||||
</div>
|
||||
<div id="parent10">
|
||||
<div id="subject10"></div>
|
||||
<div id="sibling10_1"></div>
|
||||
<div id="sibling10_2"></div>
|
||||
<div id="sibling10_3""></div>
|
||||
<div id="sibling10_4""></div>
|
||||
</div>
|
||||
<div id="parent11">
|
||||
<div id="subject11"></div>
|
||||
<div id="sibling11_2"></div>
|
||||
<div id="sibling11_3">
|
||||
<div id="siblingchild11_3_1"></div>
|
||||
</div>
|
||||
<div id="sibling11_4"></div>
|
||||
</div>
|
||||
<div id="parent12">
|
||||
<div id="subject12"></div>
|
||||
<div id="sibling12_1"></div>
|
||||
<div id="sibling12_2"></div>
|
||||
<div id="sibling12_3">
|
||||
<div id="siblingchild12_3_1"></div>
|
||||
</div>
|
||||
<div id="sibling12_4"></div>
|
||||
</div>
|
||||
<div id="parent13">
|
||||
<div class="sibling13"></div>
|
||||
<div id="subject13" class="sibling13"></div>
|
||||
</div>
|
||||
<div id="parent14">
|
||||
<div id="subject14"></div>
|
||||
<div id="sibling14_1"></div>
|
||||
<div id="sibling14_2"></div>
|
||||
<div id="sibling14_3"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
|
||||
function testColor(test_name, element, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(element).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function insertBefore(parent, reference, child_id) {
|
||||
var child = document.createElement("div");
|
||||
child.id = child_id;
|
||||
parent.insertBefore(child, reference);
|
||||
}
|
||||
|
||||
testColor(`subject1: initial color should be ${grey}`, subject1, grey);
|
||||
insertBefore(parent1, sibling1_2, "sibling1_1");
|
||||
testColor(`subject1: color after #sibling1_1 inserted should be ${red}`,
|
||||
subject1, red);
|
||||
|
||||
testColor(`subject2: initial color should be ${grey}`, subject2, grey);
|
||||
sibling2_1.remove();
|
||||
testColor(`subject2: color after #sibling2_1 removed should be ${green}`,
|
||||
subject2, green);
|
||||
|
||||
testColor(`subject3: initial color should be ${grey}`, subject3, grey);
|
||||
insertBefore(parent3, sibling3_2, "sibling3_1");
|
||||
testColor(`subject3: color after #sibling3_1 inserted should be ${blue}`,
|
||||
subject3, blue);
|
||||
|
||||
testColor(`subject4: initial color should be ${grey}`, subject4, grey);
|
||||
sibling4_1.remove();
|
||||
testColor(`subject4: color after #sibling4_1 removed should be ${yellow}`,
|
||||
subject4, yellow);
|
||||
|
||||
testColor(`subject5: initial color should be ${red}`, subject5, red);
|
||||
sibling5_1.remove();
|
||||
testColor(`subject5: color after #sibling5_1 removed should be ${grey}`,
|
||||
subject5, grey);
|
||||
|
||||
testColor(`subject6: initial color should be ${green}`, subject6, green);
|
||||
insertBefore(parent6, sibling6_2, "sibling6_1");
|
||||
testColor(`subject6: color after #sibling6_1 inserted should be ${grey}`,
|
||||
subject6, grey);
|
||||
|
||||
testColor(`subject7: initial color should be ${blue}`, subject7, blue);
|
||||
sibling7_1.remove();
|
||||
testColor(`subject7: color after #sibling7_1 removed should be ${grey}`,
|
||||
subject7, grey);
|
||||
|
||||
testColor(`subject8: initial color should be ${yellow}`, subject8, yellow);
|
||||
insertBefore(parent8, sibling8_2, "sibling8_1");
|
||||
testColor(`subject8: color after #sibling8_1 inserted should be ${grey}`,
|
||||
subject8, grey);
|
||||
|
||||
testColor(`subject9: initial color should be ${grey}`, subject9, grey);
|
||||
insertBefore(parent9, sibling9_2, "sibling9_1");
|
||||
testColor(`subject9: color after #sibling9_1 inserted should be ${red}`,
|
||||
subject1, red);
|
||||
|
||||
testColor(`subject10: initial color should be ${grey}`, subject10, grey);
|
||||
sibling10_1.remove();
|
||||
testColor(`subject10: color after #sibling10_1 removed should be ${green}`,
|
||||
subject10, green);
|
||||
|
||||
testColor(`subject11: initial color should be ${grey}`, subject11, grey);
|
||||
insertBefore(parent11, sibling11_2, "sibling11_1");
|
||||
testColor(`subject11: color after #sibling11_1 inserted should be ${blue}`,
|
||||
subject11, blue);
|
||||
|
||||
testColor(`subject12: initial color should be ${grey}`, subject12, grey);
|
||||
sibling12_1.remove();
|
||||
testColor(`subject12: color after #sibling12_1 removed should be ${yellow}`,
|
||||
subject12, yellow);
|
||||
|
||||
testColor(`subject13: initial color should be ${grey}`, subject13, grey);
|
||||
const d = document.createElement("div");
|
||||
d.classList.add("sibling13");
|
||||
parent13.appendChild(d);
|
||||
testColor(`subject13: color after #sibling12_1 removed should be ${green}`,
|
||||
subject13, green);
|
||||
|
||||
testColor(`subject14: initial color should be ${green}`, subject14, green);
|
||||
sibling14_2.remove();
|
||||
testColor(`subject14: color after #sibling14_2 removed should be ${grey}`, subject14, grey);
|
||||
</script>
|
|
@ -0,0 +1,149 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() with sibling combinator argument</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject:has(~ .test) { color: red }
|
||||
#subject:has(+ .test) { color: green }
|
||||
#subject:has(~ div .test) { color: blue }
|
||||
#subject:has(~ div > .test) { color: purple }
|
||||
#subject:has(+ div .test) { color: yellow }
|
||||
#subject:has(+ div > .test) { color: pink }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=subject></div>
|
||||
<div id=first_sibling>
|
||||
<div id=first_sibling_child>
|
||||
<div id=first_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=second_sibling></div>
|
||||
<div id=third_sibling>
|
||||
<div id=third_sibling_child>
|
||||
<div id=third_sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColor)
|
||||
{
|
||||
element.classList.add('test');
|
||||
testColor(`add .test to ${element.id}`, expectedColor);
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div.test before ${beforeElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
newElement.classList.add('test')
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div.test after ${afterElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div.test after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div.test before ${beforeElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newChild.classList.add('test');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div>div.test after ${afterElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div.test after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('initial_color', grey);
|
||||
|
||||
testClassChange(first_sibling, green);
|
||||
testClassChange(second_sibling, red);
|
||||
testClassChange(third_sibling, red);
|
||||
testClassChange(first_sibling_child, pink);
|
||||
testClassChange(first_sibling_descendant, yellow);
|
||||
testClassChange(third_sibling_child, purple);
|
||||
testClassChange(third_sibling_descendant, blue);
|
||||
|
||||
testElementInsertionBefore(first_sibling, green);
|
||||
testElementInsertionBefore(second_sibling, red);
|
||||
testElementInsertionBefore(third_sibling, red);
|
||||
testElementInsertionBefore(first_sibling_child, pink);
|
||||
testElementInsertionBefore(first_sibling_descendant, yellow);
|
||||
testElementInsertionBefore(third_sibling_child, purple);
|
||||
testElementInsertionBefore(third_sibling_descendant, blue);
|
||||
|
||||
testElementInsertionAfter(first_sibling, red);
|
||||
testElementInsertionAfter(second_sibling, red);
|
||||
testElementInsertionAfter(third_sibling, red);
|
||||
testElementInsertionAfter(first_sibling_child, pink);
|
||||
testElementInsertionAfter(first_sibling_descendant, yellow);
|
||||
testElementInsertionAfter(third_sibling_child, purple);
|
||||
testElementInsertionAfter(third_sibling_descendant, blue);
|
||||
|
||||
testTreeInsertionBefore(first_sibling, pink);
|
||||
testTreeInsertionBefore(second_sibling, purple);
|
||||
testTreeInsertionBefore(third_sibling, purple);
|
||||
testTreeInsertionBefore(first_sibling_child, yellow);
|
||||
testTreeInsertionBefore(first_sibling_descendant, yellow);
|
||||
testTreeInsertionBefore(third_sibling_child, blue);
|
||||
testTreeInsertionBefore(third_sibling_descendant, blue);
|
||||
|
||||
testTreeInsertionAfter(first_sibling, purple);
|
||||
testTreeInsertionAfter(second_sibling, purple);
|
||||
testTreeInsertionAfter(third_sibling, purple);
|
||||
testTreeInsertionAfter(first_sibling_child, yellow);
|
||||
testTreeInsertionAfter(first_sibling_descendant, yellow);
|
||||
testTreeInsertionAfter(third_sibling_child, blue);
|
||||
testTreeInsertionAfter(third_sibling_descendant, blue);
|
||||
</script>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: Invalidate :has() as result of insertion/removal</title>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject:has(+ #next_sibling) { color: red; }
|
||||
#prev_sibling:has(+ #subject + #next_sibling) { color: green; }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=prev_sibling></div>
|
||||
<div id=subject></div>
|
||||
<div id=blocks_match></div>
|
||||
<div id=next_sibling></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
|
||||
function testColors(test_name, subject_color, prev_sibling_color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, subject_color);
|
||||
assert_equals(getComputedStyle(prev_sibling).color, prev_sibling_color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
testColors('Initial colors', grey, grey);
|
||||
|
||||
const d = blocks_match;
|
||||
d.remove();
|
||||
|
||||
testColors('Matches after #blocks_match removed', red, green);
|
||||
subject.after(d);
|
||||
|
||||
testColors('Does not match after #blocks_match added', grey, grey);
|
||||
</script>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() affected by unstyled elements</title>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
.none { display: none; }
|
||||
#subject:has(.test) { color: red; }
|
||||
#subject:has(~ #sibling .test) { color: green; }
|
||||
#subject:has(:is(.test_inner #subject_descendant)) { color: blue; }
|
||||
#subject:has(~ #sibling :is(.test_inner #sibling_descendant)) { color: yellow; }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=subject>
|
||||
<div id=subject_child class="none">
|
||||
<div id=subject_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=sibling class="none">
|
||||
<div id=sibling_child>
|
||||
<div id=sibling_descendant></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const yellow = "rgb(255, 255, 0)";
|
||||
const colors = {
|
||||
grey: {
|
||||
classTest: grey,
|
||||
},
|
||||
red: {
|
||||
classTest: red,
|
||||
},
|
||||
green: {
|
||||
classTest: green,
|
||||
},
|
||||
blue: {
|
||||
classTest: blue,
|
||||
},
|
||||
yellow: {
|
||||
classTest: yellow,
|
||||
},
|
||||
};
|
||||
|
||||
function testColor(test_name, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testClassChange(element, cls, expectedColorName)
|
||||
{
|
||||
const expectedColorForClassTest = colors[expectedColorName].classTest;
|
||||
element.classList.add(cls);
|
||||
testColor(`add ${cls} to ${element.id}`, expectedColorForClassTest);
|
||||
element.classList.remove(cls);
|
||||
testColor(`remove ${cls} from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(subject_descendant, 'test', 'red');
|
||||
testClassChange(sibling_descendant, 'test', 'green');
|
||||
testClassChange(subject_child, 'test_inner', 'blue');
|
||||
testClassChange(sibling_child, 'test_inner', 'yellow');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,158 @@
|
|||
<!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>
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() with nesting parent containing :hover</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>
|
||||
dd, dt { background: white; }
|
||||
dd:hover {
|
||||
dt:has(~ &) { background: lime; }
|
||||
}
|
||||
</style>
|
||||
<dt id=dt1>#dt1</dt>
|
||||
<dd id=dd1>#dd1, Hover me, the DT above should go lime</dd>
|
||||
<dt id=dt2>#dt2</dt>
|
||||
<dd id=dd2>#dd2, Hover me, both DTs above should go lime</dd>
|
||||
<script>
|
||||
const white = 'rgb(255, 255, 255)';
|
||||
const lime = 'rgb(0, 255, 0)';
|
||||
|
||||
function bg_color(element, color, message) {
|
||||
assert_equals(getComputedStyle(element)['background-color'], color, message);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
bg_color(dt1, white, "#dt1 initially white");
|
||||
bg_color(dd1, white, "#dd1 initially white");
|
||||
bg_color(dt2, white, "#dt2 initially white");
|
||||
bg_color(dd2, white, "#dd2 initially white");
|
||||
|
||||
await new test_driver.Actions().pointerMove(0, 0, {origin: dd1}).send();
|
||||
|
||||
bg_color(dt1, lime, "#dt1 should go lime when hover #dd1");
|
||||
bg_color(dd1, white, "#dd1 doesn't change when hover #dd1");
|
||||
bg_color(dt2, white, "#dt2 doesn't change when hover #dd1");
|
||||
bg_color(dd2, white, "#dd2 doesn't change when hover #dd1");
|
||||
|
||||
await new test_driver.Actions().pointerMove(0, 0, {origin: dt1}).send();
|
||||
|
||||
bg_color(dt1, white, "#dt1 should go white when hover #dt2");
|
||||
bg_color(dd1, white, "#dd1 doesn't change when hover #dt2");
|
||||
bg_color(dt2, white, "#dt2 doesn't change when hover #dt2");
|
||||
bg_color(dd2, white, "#dd2 doesn't change when hover #dt2");
|
||||
|
||||
await new test_driver.Actions().pointerMove(0, 0, {origin: dd2}).send();
|
||||
|
||||
bg_color(dt1, lime, "#dt1 should go lime when hover #dd2");
|
||||
bg_color(dd1, white, "#dd1 doesn't change when hover #dd2");
|
||||
bg_color(dt2, lime, "#dt2 should go lime when hover #dd2");
|
||||
bg_color(dd2, white, "#dd2 doesn't change when hover #dd2");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() with :not()</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject:has(:not(.test)) { color: green }
|
||||
#subject:has(.test :not(.test)) { color: red }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=subject>
|
||||
<div id=subject_child class=test>
|
||||
<div id=subject_descendant class=test></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
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);
|
||||
}
|
||||
|
||||
function testClassChange(element, expectedColor)
|
||||
{
|
||||
element.classList.remove('test');
|
||||
testColor(`remove .test to ${element.id}`, expectedColor);
|
||||
element.classList.add('test');
|
||||
testColor(`add .test from ${element.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionBefore(beforeElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert element div before ${beforeElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testElementInsertionAfter(afterElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert element div after ${afterElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove element div after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionBefore(beforeElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
beforeElement.before(newElement);
|
||||
testColor(`insert tree div>div before ${beforeElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div>div before ${beforeElement.id}`, grey);
|
||||
}
|
||||
|
||||
function testTreeInsertionAfter(afterElement, expectedColor)
|
||||
{
|
||||
const newElement = document.createElement('div');
|
||||
const newChild = document.createElement('div');
|
||||
newElement.appendChild(newChild);
|
||||
|
||||
afterElement.after(newElement);
|
||||
testColor(`insert tree div.test after ${afterElement.id}`, expectedColor);
|
||||
|
||||
newElement.remove();
|
||||
testColor(`remove tree div.test after ${afterElement.id}`, grey);
|
||||
}
|
||||
|
||||
testColor('Initial color', grey);
|
||||
|
||||
testClassChange(subject_child, green);
|
||||
testClassChange(subject_descendant, red);
|
||||
|
||||
testElementInsertionBefore(subject_child, green);
|
||||
testElementInsertionBefore(subject_descendant, red);
|
||||
|
||||
testElementInsertionAfter(subject_child, green);
|
||||
testElementInsertionAfter(subject_descendant, red);
|
||||
|
||||
testTreeInsertionBefore(subject_child, green);
|
||||
testTreeInsertionBefore(subject_descendant, red);
|
||||
|
||||
testTreeInsertionAfter(subject_child, green);
|
||||
testTreeInsertionAfter(subject_descendant, red);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors Test: :has(:nth-child()) invalidation for sibling change</title>
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
#test-container > div { background-color: green; }
|
||||
#target1:has(.item:nth-child(3)) { background-color: red; }
|
||||
#target2:has(.item:nth-last-child(3)) { background-color: red; }
|
||||
#target3:has(.item:nth-child(3) > .child) { background-color: red; }
|
||||
#target4:has(.item:nth-last-child(3) > .child) { background-color: red; }
|
||||
</style>
|
||||
<div id="test-container">
|
||||
<div id="target1">
|
||||
<div class="item" id="item1">FAIL if you see this text</div>
|
||||
<div class="item"></div>
|
||||
<div class="item">This text should have a green background</div>
|
||||
</div>
|
||||
<div id="target2">
|
||||
<div class="item">This text should have a green background</div>
|
||||
<div class="item"></div>
|
||||
<div class="item" id="item2">FAIL if you see this text</div>
|
||||
</div>
|
||||
<div id="target3">
|
||||
<div class="item" id="item3">FAIL if you see this text</div>
|
||||
<div class="item"></div>
|
||||
<div class="item">
|
||||
<span class="child">This text should have a green background<span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="target4">
|
||||
<div class="item">
|
||||
<span class="child">This text should have a green background<span>
|
||||
</div>
|
||||
<div class="item"></div>
|
||||
<div class="item" id="item4">FAIL if you see this text</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target1).backgroundColor, "rgb(255, 0, 0)");
|
||||
assert_equals(getComputedStyle(target2).backgroundColor, "rgb(255, 0, 0)");
|
||||
assert_equals(getComputedStyle(target3).backgroundColor, "rgb(255, 0, 0)");
|
||||
assert_equals(getComputedStyle(target4).backgroundColor, "rgb(255, 0, 0)");
|
||||
}, "Initially red");
|
||||
|
||||
test(() => {
|
||||
item1.remove();
|
||||
assert_equals(getComputedStyle(target1).backgroundColor, "rgb(0, 128, 0)");
|
||||
}, ":nth-child() no longer matching after removal");
|
||||
|
||||
test(() => {
|
||||
item2.remove();
|
||||
assert_equals(getComputedStyle(target2).backgroundColor, "rgb(0, 128, 0)");
|
||||
}, ":nth-last-child() no longer matching after removal");
|
||||
|
||||
test(() => {
|
||||
item3.remove();
|
||||
assert_equals(getComputedStyle(target3).backgroundColor, "rgb(0, 128, 0)");
|
||||
}, ":nth-child() in non-subject no longer matching after removal");
|
||||
|
||||
test(() => {
|
||||
item4.remove();
|
||||
assert_equals(getComputedStyle(target4).backgroundColor, "rgb(0, 128, 0)");
|
||||
}, ":nth-last-child() in non-subject no longer matching after removal");
|
||||
</script>
|
|
@ -0,0 +1,99 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: :has() with pseudo-classes</title>
|
||||
<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
main:has(input) div { color: grey }
|
||||
main:has(#checkbox:checked) > #subject { color: red }
|
||||
main:has(#option:checked) > #subject { color: red }
|
||||
main:has(#checkbox:disabled) > #subject { color: green }
|
||||
main:has(#option:disabled) > :is(#subject, #subject2) { color: green }
|
||||
main:has(#optgroup:disabled) > #subject { color: blue }
|
||||
main:not(:has(#checkbox:enabled)) > #subject3 { color: green }
|
||||
main:not(:has(#option:enabled)) :is(#subject3, #subject4) { color: green }
|
||||
main:not(:has(#optgroup:enabled)) > #subject3 { color: blue }
|
||||
main:has(#text_input:valid) > #subject { color: yellow }
|
||||
main:not(:has(#text_input:invalid)) > #subject2 { color: yellow }
|
||||
main:has(#form:valid) > #subject3 { color: yellow }
|
||||
main:not(:has(#form:invalid)) > #subject4 { color: yellow }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<form id=form>
|
||||
<input type=checkbox id=checkbox></input>
|
||||
<select id=select><optgroup id=optgroup><option>a</option><option id=option>b</option></optgroup></select>
|
||||
<input id=text_input type=text required></input>
|
||||
</form>
|
||||
<div id=subject></div>
|
||||
<div id=subject2></div>
|
||||
<div id=subject3></div>
|
||||
<div id=subject4></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
const blue = 'rgb(0, 0, 255)';
|
||||
const yellow = 'rgb(255, 255, 0)';
|
||||
const purple = 'rgb(128, 0, 128)';
|
||||
const pink = 'rgb(255, 192, 203)';
|
||||
|
||||
function testColor(test_name, subject_element, color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject_element).color, color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
function testPseudoClassChange(element, property, subject_element, expectedColor)
|
||||
{
|
||||
testColor(`Before set ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, grey);
|
||||
|
||||
element[property] = true;
|
||||
testColor(`Set ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, expectedColor);
|
||||
|
||||
element[property] = false;
|
||||
testColor(`Unset ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, grey);
|
||||
}
|
||||
|
||||
function testSelectedChange(option, subject_element, expectedColor)
|
||||
{
|
||||
const oldOption = select.selectedOptions[0];
|
||||
option.selected = true;
|
||||
testColor(`Set select on ${option.id}`, subject_element, expectedColor);
|
||||
oldOption.selected = true;
|
||||
testColor(`Reset select`, subject, grey);
|
||||
}
|
||||
|
||||
function testValueChange(input, subject_element, expectedColor)
|
||||
{
|
||||
testColor(`Before setting value of ${input.id}, testing ${subject_element.id}`, subject_element, grey);
|
||||
|
||||
input.value = "value";
|
||||
testColor(`Set value of ${input.id}, testing ${subject_element.id}`, subject_element, expectedColor);
|
||||
|
||||
input.value = "";
|
||||
testColor(`Clear value of ${input.id}, testing ${subject_element.id}`, subject_element, grey);
|
||||
}
|
||||
|
||||
testPseudoClassChange(checkbox, "checked", subject, red);
|
||||
testSelectedChange(option, subject, red);
|
||||
|
||||
testPseudoClassChange(checkbox, "disabled", subject, green);
|
||||
testPseudoClassChange(checkbox, "disabled", subject3, green);
|
||||
testPseudoClassChange(option, "disabled", subject, green);
|
||||
testPseudoClassChange(option, "disabled", subject3, green);
|
||||
|
||||
testPseudoClassChange(optgroup, "disabled", subject, blue);
|
||||
testPseudoClassChange(optgroup, "disabled", subject2, green);
|
||||
testPseudoClassChange(optgroup, "disabled", subject3, blue);
|
||||
testPseudoClassChange(optgroup, "disabled", subject4, green);
|
||||
|
||||
testValueChange(text_input, subject, yellow);
|
||||
testValueChange(text_input, subject2, yellow);
|
||||
testValueChange(text_input, subject3, yellow);
|
||||
testValueChange(text_input, subject4, yellow);
|
||||
</script>
|
Loading…
Reference in a new issue