Bug 1888044 [wpt PR 45361] - [Invokers] Clean up invokers tests, a=testonly

Automatic update from web-platform-tests
[Invokers] Clean up invokers tests (#45361)

This change aims to tidy up the invokers tests to reduce the amount of
flakey builds from timeouts due to the amount of tests in each file.
It refactors all of the invokers tests to:

 - Use loops for repetitive tests
 - Try to consistently test the aliases of auto, explicit empty ("") vs
   named.
 - Mark any tests using clickOn as timeout long, to avoid flakiness in
   CI
 - Split the invalid no-ops, to reduce individual test time.

Bug: 40943183
Change-Id: I066b0a6e06143e562a3b0f4c7c1bbaeb309b68f6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5374369
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Keith Cirkel <chromium@keithcirkel.co.uk>
Cr-Commit-Position: refs/heads/main@{#1277818}

Co-authored-by: Keith Cirkel <chromium@keithcirkel.co.uk>
--

wpt-commits: 066ad51422c842bcc8c06c4a713821ebd121f690
wpt-pr: 45361
This commit is contained in:
An Sung 2024-03-27 23:12:00 +00:00 committed by moz-wptsync-bot
parent cfc61fe5b1
commit 86742daf76
12 changed files with 396 additions and 405 deletions

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<meta name="timeout" content="long" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>

View File

@ -26,7 +26,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -44,7 +44,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -60,7 +60,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
invokerbutton.click();
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -79,7 +79,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -92,12 +92,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play audio');
await test_driver.bless("play audio");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -115,7 +115,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -131,7 +131,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
invokerbutton.click();
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -150,7 +150,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -163,12 +163,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play audio');
await test_driver.bless("play audio");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -186,8 +186,8 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
requestAnimationFrame(resolve);
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
}, "invoking audio with pause action is a no-op");
@ -205,7 +205,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -218,12 +218,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play audio');
await test_driver.bless("play audio");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -241,7 +241,7 @@
assert_false(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.muted);
@ -260,7 +260,7 @@
assert_false(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.muted);
@ -277,10 +277,9 @@
assert_true(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.muted);
}, "invoking muted audio with toggleMuted action unmutes it");
</script>

View File

@ -0,0 +1,37 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<meta name="timeout" content="long" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<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>
<script src="resources/invoker-utils.js"></script>
<audio controls id="invokee" src="/media/sound_5.mp3"></audio>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
// invalid actions on audio
[
"foo-bar",
"showpopover",
"showmodal",
"showpicker",
"open",
"close",
].forEach((action) => {
promise_test(async function (t) {
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokerbutton.setAttribute("invokeaction", action);
assert_true(invokee.paused);
assert_false(invokee.muted);
await clickOn(invokerbutton);
await waitForRender();
assert_true(invokee.paused);
assert_false(invokee.muted);
}, `invoking (as ${action}) on audio does nothing`);
});
</script>

View File

@ -10,210 +10,136 @@
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/invoker-utils.js"></script>
<details id="invokee">
Details Contents
</details>
<details id="invokee">Details Contents</details>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
// auto
function resetState() {
invokerbutton.removeAttribute("invokeaction");
invokee.removeAttribute("open");
}
// Open actions
[
null,
"",
"toggle",
"open",
/* test case sensitivity */
"tOgGlE",
"oPeN",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed details opens`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches("[open]"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute("open"));
assert_false(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed details with preventDefault does not open`,
);
});
// Close actions
[
null,
"",
"toggle",
"close",
/* test case sensitivity */
"tOgGlE",
"cLoSe",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
invokee.setAttribute("open", "");
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open details closes`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
invokee.setAttribute("open", "");
invokerbutton.setAttribute("invokeaction", "toggle");
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open details with prevent default closes`,
);
});
// toggle specific
promise_test(async function (t) {
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking closed details with auto action opens");
promise_test(async function (t) {
assert_false(invokee.matches("[open]"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
t.add_cleanup(resetState);
invokerbutton.invokeAction = "toggle";
invokee.addEventListener(
"invoke",
(e) => {
invokee.setAttribute("open", "");
},
{
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_false(invokee.matches("[open]"));
}, "invoking closed details with auto action and preventDefault does not open");
promise_test(async function (t) {
invokee.setAttribute('open', '');
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking open details with auto action closes");
promise_test(async function (t) {
invokee.setAttribute('open', '');
t.add_cleanup(() => invokee.removeAttribute('open'));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, "invoking open details with auto action and preventDefault does not close");
promise_test(async function (t) {
t.add_cleanup(() => invokee.removeAttribute('open'));
invokee.addEventListener("invoke", (e) => {
invokee.setAttribute('open', '');
}, {
once: true,
});
},
);
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking details with auto action where event listener opens leads to a closed details");
}, "invoking (as toggle) closed details where event listener opens leads to a closed details");
// open specific
promise_test(async function (t) {
invokee.setAttribute('open', '');
t.add_cleanup(() => invokee.removeAttribute('open'));
invokee.addEventListener("invoke", (e) => {
invokee.removeAttribute('open');
}, {
once: true,
});
t.add_cleanup(resetState);
invokerbutton.invokeAction = "open";
invokee.setAttribute("open", "");
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, "invoking open details with auto action where event listener closes leads to an open details");
// toggle
promise_test(async function (t) {
assert_false(invokee.matches("[open]"));
invokerbutton.setAttribute("invokeaction", "toggle");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking closed details with toggle action opens");
promise_test(async function (t) {
assert_false(invokee.matches("[open]"));
invokerbutton.setAttribute("invokeaction", "tOgGlE");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking closed details with toggle (case-insensitive) action opens");
promise_test(async function (t) {
assert_false(invokee.matches("[open]"));
invokerbutton.setAttribute("invokeaction", "toggle");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_false(invokee.matches("[open]"));
}, "invoking closed details with toggle action and preventDefault does not open");
promise_test(async function (t) {
invokee.setAttribute('open', '');
invokerbutton.setAttribute("invokeaction", "toggle");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking open details with toggle action closes");
promise_test(async function (t) {
invokee.setAttribute('open', '');
t.add_cleanup(() => invokee.removeAttribute('open'));
invokerbutton.setAttribute("invokeaction", "toggle");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, "invoking open details with toggle action and preventDefault does not close");
// open
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "open");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking closed details with open action opens");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "oPeN");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking closed details with open (case insensitive) action opens");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "open");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.setAttribute('open', '');
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
}, "invoking open details with open action is noop");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "open");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches("[open]"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_false(invokee.matches("[open]"));
}, "invoking closed popover with open action and preventDefault does not open");
// close
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "close");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
t.add_cleanup(resetState);
invokerbutton.invokeAction = "close";
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking closed details with close action is noop");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "close");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.setAttribute('open', '');
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_false(invokee.matches("[open]"));
}, "invoking open details with close action closes");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "cLoSe");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.setAttribute('open', '');
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_false(invokee.matches("[open]"));
}, "invoking open details with close (case insensitive) action closes");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "close");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.setAttribute('open', '');
t.add_cleanup(() => invokee.removeAttribute('open'));
assert_true(invokee.matches("[open]"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, "invoking open details with close action with preventDefault does not close");
</script>

View File

@ -0,0 +1,49 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<meta name="timeout" content="long" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<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>
<script src="resources/invoker-utils.js"></script>
<details id="invokee">Details Contents</details>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
function resetState() {
invokerbutton.removeAttribute("invokeaction");
invokee.removeAttribute("open");
}
// invalid actions on details
[
"foo-bar",
"showpopover",
"showmodal",
"showpicker",
"hidepopover",
"hide",
"toggleopen",
].forEach((action) => {
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = action;
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, `invoking (as ${action}) on details does nothing`);
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = action;
invokee.setAttribute("open", "");
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, `invoking (as ${action}) on open details does nothing`);
});
</script>

View File

@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<meta name="timeout" content="long" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<script src="/resources/testharness.js"></script>
@ -11,30 +11,13 @@
<script src="resources/invoker-utils.js"></script>
<div id="invokee" popover>
<button id="invokerbutton2" invoketarget="invokee"></button>
<button id="containedinvoker" invoketarget="invokee"></button>
</div>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
// auto
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as auto) closed popover opens");
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_false(invokee.matches(":popover-open"));
}, "invoking (as auto) closed popover with preventDefault does not open");
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
invokee.addEventListener("invoke", (e) => { invokerbutton.setAttribute('invokeaction', 'hidepopover'); }, {
@ -48,176 +31,127 @@
assert_true(invokee.matches(":popover-open"));
}, "changing invokeaction attribute inside invokeevent doesn't impact the invocation");
function resetState() {
invokerbutton.removeAttribute("invokeaction");
containedinvoker.removeAttribute("invokeaction");
try {
invokee.hidePopover();
} catch {}
invokee.setAttribute("popover", "");
}
// Open actions
[
null,
"",
"togglepopover",
"showpopover",
/* test case sensitivity */
"tOgGlEpOpOvEr",
"sHoWpOpOvEr",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_true(invokee.matches(":popover-open"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed popover opens`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches(":popover-open"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed popover with preventDefault does not open`,
);
});
// Close actions
[
null,
"",
"togglepopover",
"hidepopover",
/* test case sensitivity */
"tOgGlEpOpOvEr",
"hIdEpOpOvEr",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open popover closes`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) containedinvoker.invokeAction = action;
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(containedinvoker);
assert_false(invokee.matches(":popover-open"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) from within open popover closes`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invcontainedinvokervokeaction = action;
invokee.showPopover();
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches(":popover-open"));
await clickOn(containedinvoker);
assert_true(invokee.matches(":popover-open"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open popover with preventDefault does not close`,
);
});
// showpopover specific
promise_test(async function (t) {
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
}, "invoking (as auto) open popover closes");
promise_test(async function (t) {
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
assert_false(invokee.matches(":popover-open"));
}, "invoking (as auto) from within open popover closes");
promise_test(async function (t) {
invokee.showPopover();
t.add_cleanup(() => invokee.hidePopover());
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
assert_true(invokee.matches(":popover-open"));
}, "invoking (as auto) open popover with preventDefault does not close");
// togglepopover
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
invokerbutton.setAttribute("invokeaction", "togglepopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as togglepopover) closed popover opens");
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
invokerbutton.setAttribute("invokeaction", "tOgGlEpOpOvEr");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as togglepopover - case insensitive) closed popover opens");
promise_test(async function (t) {
assert_false(invokee.matches(":popover-open"));
invokerbutton.setAttribute("invokeaction", "togglepopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_false(invokee.matches(":popover-open"));
}, "invoking (as togglepopover) closed popover with preventDefault does not open");
promise_test(async function (t) {
invokee.showPopover();
invokerbutton2.setAttribute("invokeaction", "togglepopover");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
}, "invoking (as togglepopover) open popover closes");
promise_test(async function (t) {
invokee.showPopover();
invokerbutton2.setAttribute("invokeaction", "togglepopover");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
assert_false(invokee.matches(":popover-open"));
}, "invoking (as togglepopover) from within open popover closes");
promise_test(async function (t) {
invokee.showPopover();
t.add_cleanup(() => invokee.hidePopover());
invokerbutton2.setAttribute("invokeaction", "togglepopover");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
assert_true(invokee.matches(":popover-open"));
}, "invoking (as togglepopover) open popover with preventDefault does not close");
// showpopover
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.setAttribute("invokeaction", "showpopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as showpopover) closed popover opens");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "sHoWpOpOvEr");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as showpopover - case insensitive) closed popover opens");
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "showpopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
}, "invoking (as showpopover) open popover is noop");
// hidepopover specific
promise_test(async function (t) {
invokerbutton.setAttribute("invokeaction", "showpopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches(":popover-open"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.hidePopover());
assert_false(invokee.matches(":popover-open"));
}, "invoking (as showpopover) closed popover with preventDefault does not open");
// hidepopover
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.setAttribute("invokeaction", "hidepopover");
t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
}, "invoking (as hidepopover) closed popover is noop");
promise_test(async function (t) {
invokerbutton2.setAttribute("invokeaction", "hidepopover");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
t.add_cleanup(() => invokee.hidePopover());
assert_false(invokee.matches(":popover-open"));
}, "invoking (as hidepopover) open popover closes");
promise_test(async function (t) {
invokerbutton2.setAttribute("invokeaction", "hIdEpOpOvEr");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton2);
t.add_cleanup(() => invokee.hidePopover());
assert_false(invokee.matches(":popover-open"));
}, "invoking (as hidepopover - case insensitive) open popover closes");
promise_test(async function (t) {
invokerbutton2.setAttribute("invokeaction", "hidepopover");
t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
invokee.showPopover();
t.add_cleanup(() => invokee.hidePopover());
assert_true(invokee.matches(":popover-open"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton2);
assert_true(invokee.matches(":popover-open"));
}, "invoking (as hidepopover) open popover with preventDefault does not close");
</script>

View File

@ -0,0 +1,47 @@
<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
<meta name="timeout" content="long" />
<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
<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>
<script src="resources/invoker-utils.js"></script>
<div id="invokee" popover>
<button id="containedinvoker" invoketarget="invokee"></button>
</div>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
function resetState() {
invokerbutton.removeAttribute("invokeaction");
containedinvoker.removeAttribute("invokeaction");
try {
invokee.hidePopover();
} catch {}
invokee.setAttribute("popover", "");
}
// invalid actions on showpopover
["foo-bar", "showmodal", "showpicker", "open", "close"].forEach((action) => {
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = action;
assert_false(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_false(invokee.matches(":popover-open"));
}, `invoking (as ${action}) on popover does nothing`);
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = action;
invokee.showPopover();
assert_true(invokee.matches(":popover-open"));
await clickOn(invokerbutton);
assert_true(invokee.matches(":popover-open"));
}, `invoking (as ${action}) on open popover does nothing`);
});
</script>

View File

@ -26,7 +26,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -44,7 +44,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -63,7 +63,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -76,12 +76,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play video');
await test_driver.bless("play video");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "playpause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -99,7 +99,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -113,12 +113,12 @@
invokee.muted = false;
});
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
once: true,
});
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -131,12 +131,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play video');
await test_driver.bless("play video");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "play");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.paused);
@ -154,7 +154,7 @@
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -168,12 +168,12 @@
invokee.muted = false;
});
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
once: true,
});
assert_true(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -186,12 +186,12 @@
invokee.currentTime = 0;
invokee.muted = false;
});
await test_driver.bless('play video');
await test_driver.bless("play video");
invokee.play();
assert_false(invokee.paused);
invokerbutton.setAttribute("invokeaction", "pause");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.paused);
@ -209,7 +209,7 @@
assert_false(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_true(invokee.muted);
@ -223,12 +223,12 @@
invokee.muted = false;
});
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
once: true,
});
assert_false(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.muted);
@ -245,10 +245,9 @@
assert_true(invokee.muted);
invokerbutton.setAttribute("invokeaction", "toggleMuted");
await clickOn(invokerbutton);
await new Promise(resolve => {
await new Promise((resolve) => {
requestAnimationFrame(resolve);
});
assert_false(invokee.muted);
}, "invoking muted video with toggleMuted action unmutes it");
</script>