Commit fd64969d authored by Mason Freed's avatar Mason Freed Committed by Chromium LUCI CQ

Fix the slotchange WPT test - it previously didn't catch bugs

The slotchange event is fired on slots the first time they
receive assignedNodes. This is the case on all browsers. The
previous test just checked that *any* slotchange event was
fired, which always passed. The conditions being checked could
be removed from the tests and they would mostly all pass.
With this CL, the assignedNodes() are compared to the
expectations, to ensure a pass. The tests that check multiple
slots are a bit of a hack, since the slotchange events come
asynchronously. But this still seems better than the prior
test.

Another note: despite documentation [1] saying that the
assignedNodes() accessor should return fallback content,
it does not. This is also the case for WebKit and Gecko.
Further, the prior test strongly implied that 'slotchange'
should be fired for changes to the fallback content, but
due to the above fact, no such event is fired, since the
assignedNodes() value does not change.

[1] https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedNodes

Bug: 1158001
Change-Id: I2ce15d53239f2c9204d1f1633f333897139e337a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587711
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Commit-Queue: Yu Han <yuzhehan@chromium.org>
Reviewed-by: default avatarYu Han <yuzhehan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836784}
parent 2e0b01fd
......@@ -15,13 +15,21 @@
</div>
<script>
function doneIfSlotChange(slots, test) {
let fired = new Set();
for (let slot of slots) {
slot.addEventListener('slotchange', test.step_func((e) => {
assert_false(fired.has(slot.id));
fired.add(slot.id);
if (fired.size == slots.length) {
function arraysEqual(a, b) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length !== b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
function doneIfSlotChange(slots, expectedAssignedNodes, test) {
let matched = Array(slots.length).fill(false);
for (let i=0; i<slots.length; i++) {
slots[i].addEventListener('slotchange', test.step_func((e) => {
matched[i] = arraysEqual(slots[i].assignedNodes(), expectedAssignedNodes[i]);
if (matched.every(v => v)) {
test.done();
}
}))
......@@ -32,10 +40,11 @@ async_test((test) => {
let n = createTestTree(test1);
removeWhiteSpaceOnlyTextNodes(n.test1);
doneIfSlotChange([n.s1], test);
let d1 = document.createElement('div');
d1.setAttribute('slot', 'slot1');
doneIfSlotChange([n.s1], [[n.c1, d1]], test);
n.host1.appendChild(d1);
}, 'slotchange event: Append a child to a host.');
......@@ -43,7 +52,7 @@ async_test((test) => {
let n = createTestTree(test1);
removeWhiteSpaceOnlyTextNodes(n.test1);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
n.c1.remove();
}, 'slotchange event: Remove a child from a host.');
......@@ -54,14 +63,14 @@ async_test((test) => {
n.c1.remove();
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
}, 'slotchange event: Remove a child before adding an event listener.');
async_test((test) => {
let n = createTestTree(test1);
removeWhiteSpaceOnlyTextNodes(n.test1);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
n.c1.setAttribute('slot', 'slot-none');
}, 'slotchange event: Change slot= attribute to make it un-assigned.');
......@@ -70,7 +79,7 @@ async_test((test) => {
let n = createTestTree(test1);
removeWhiteSpaceOnlyTextNodes(n.test1);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
n.s1.setAttribute('name', 'slot-none');
}, 'slotchange event: Change slot\'s name= attribute so that none is assigned.');
......@@ -90,7 +99,7 @@ async_test((test) => {
let n = createTestTree(test2);
removeWhiteSpaceOnlyTextNodes(n.test2);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[n.c2]], test);
n.c2.setAttribute('slot', 'slot1');
}, 'slotchange event: Change slot= attribute to make it assigned.');
......@@ -99,7 +108,7 @@ async_test((test) => {
let n = createTestTree(test2);
removeWhiteSpaceOnlyTextNodes(n.test2);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[n.c2]], test);
n.s1.setAttribute('name', 'slot2');
}, 'slotchange event: Change slot\'s name= attribute so that a node is assigned to the slot.');
......@@ -118,10 +127,10 @@ async_test((test) => {
let n = createTestTree(test_fallback);
removeWhiteSpaceOnlyTextNodes(n.test_fallback);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
n.s1.appendChild(document.createElement('div'));
}, 'slotchange event: Add a fallback content.');
}, 'slotchange event: Change fallback content - assignedNodes still empty.');
</script>
<div id="test_fallback2">
......@@ -139,10 +148,10 @@ async_test((test) => {
let n = createTestTree(test_fallback2);
removeWhiteSpaceOnlyTextNodes(n.test_fallback2);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
n.f1.remove();
}, 'slotchange event: Remove a fallback content.');
}, 'slotchange event: Remove a fallback content - assignedNodes still empty.');
</script>
<div id="test_fallback3">
......@@ -162,19 +171,19 @@ async_test((test) => {
let n = createTestTree(test_fallback3);
removeWhiteSpaceOnlyTextNodes(n.test_fallback3);
doneIfSlotChange([n.s1, n.s2], test);
doneIfSlotChange([n.s1, n.s2], [[],[]], test);
n.s1.appendChild(document.createElement('div'));
}, 'slotchange event: Add a fallback content to nested slots.');
}, 'slotchange event: Add a fallback content to nested slots - assignedNodes still empty.');
async_test((test) => {
let n = createTestTree(test_fallback3);
removeWhiteSpaceOnlyTextNodes(n.test_fallback3);
doneIfSlotChange([n.s1, n.s2], test);
doneIfSlotChange([n.s1, n.s2], [[],[]], test);
n.f1.remove();
}, 'slotchange event: Remove a fallback content from nested slots.');
}, 'slotchange event: Remove a fallback content from nested slots - assignedNodes still empty.');
</script>
<div id="test3">
......@@ -191,7 +200,7 @@ async_test((test) => {
let n = createTestTree(test3);
removeWhiteSpaceOnlyTextNodes(n.test3);
doneIfSlotChange([n.s1], test);
doneIfSlotChange([n.s1], [[]], test);
let slot = document.createElement('slot');
slot.setAttribute('name', 'slot1');
......@@ -214,7 +223,7 @@ async_test((test) => {
let n = createTestTree(test4);
removeWhiteSpaceOnlyTextNodes(n.test4);
doneIfSlotChange([n.s2], test);
doneIfSlotChange([n.s2], [[n.c1]], test);
n.s1.remove();
}, "slotchange event: Remove a preceding slot.");
......@@ -239,7 +248,7 @@ async_test((test) => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
doneIfSlotChange([n.s1, n.s2], test);
doneIfSlotChange([n.s1, n.s2], [[],[n.s1]], test);
n.c1.remove();
}, "slotchange event: A slot is assigned to another slot.");
......@@ -263,8 +272,34 @@ async_test((test) => {
let n = createTestTree(test6);
removeWhiteSpaceOnlyTextNodes(n.test6);
doneIfSlotChange([n.s2], test);
doneIfSlotChange([n.s2], [[]], test);
n.s1.remove();
}, "slotchange event: Even if distributed nodes do not change, slotchange should be fired if assigned nodes are changed.");
}, "slotchange event: Slotchange should be fired if assigned nodes are changed.");
</script>
<div id="test7">
<div id="host1">
<template data-mode="open">
<div id="host2">
<template data-mode="open">
<slot id="s2" name="slot2"></slot>
</template>
<slot id="s1" name="slot1" slot="slot2"></slot>
</div>
</template>
</div>
</div>
<script>
async_test((test) => {
let n = createTestTree(test7);
removeWhiteSpaceOnlyTextNodes(n.test7);
let d1 = document.createElement('div');
d1.setAttribute('slot', 'slot1');
doneIfSlotChange([n.s1, n.s2], [[d1],[n.s1]], test);
n.host1.appendChild(d1);
}, "slotchange event: Child content is added to nested slots.");
</script>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment