Bug 1830798 [wpt PR 39788] - Add popover hover triggering to buttons, a=testonly
[gecko.git] / testing / web-platform / tests / html / semantics / popovers / popover-hover-hide.tentative.html
blobed647a7d7d8f9c2598cf2c69c21f84ec455f5994
1 <!DOCTYPE html>
2 <meta charset="utf-8" />
3 <title>The popover-hide-delay CSS property</title>
4 <link rel="author" href="mailto:masonf@chromium.org">
5 <link rel=help href="https://open-ui.org/components/popover.research.explainer">
6 <meta name="timeout" content="long">
7 <script src="/resources/testharness.js"></script>
8 <script src="/resources/testharnessreport.js"></script>
9 <script src="/resources/testdriver.js"></script>
10 <script src="/resources/testdriver-actions.js"></script>
11 <script src="/resources/testdriver-vendor.js"></script>
12 <script src="resources/popover-utils.js"></script>
14 <style>
15 [popover] {
16 top:100px;
17 popover-hide-delay: 100ms;
19 [popovertargetaction=hover] {
20 top:200px;
21 popover-show-delay: 100ms;
23 #unrelated {top: 300px;}
24 div {
25 /* Fixed position everything to ensure nothing overlaps */
26 position: fixed;
28 </style>
29 <div id=unrelated>Unrelated element</div>
31 <div popover id=example1>Popover</div>
32 <button popovertarget=example1 popovertargetaction=hover id=invoker1>Hover me</button>
34 <script>
35 const hoverDelays = 100; // This needs to match the style block above.
36 const hoverWaitTime = 200; // How long to wait to cover the delay for sure.
38 // NOTE about testing methodology:
39 // This test checks whether popovers are hidden *after* the appropriate de-hover
40 // delay. The delay used for testing is kept low, to avoid this test taking too
41 // long, but that means that sometimes on a slow bot/client, the delay can
42 // elapse before we are able to check the popover status. And that can make this
43 // test flaky. To avoid that, the msSinceMouseOver() function is used to check
44 // that not-too-much time has passed, and if it has, the test is simply skipped.
46 const unrelated = document.getElementById('unrelated');
48 function getComputedStyleTimeMs(element,property) {
49 // Times are in seconds, so just strip off the 's'.
50 return Number(getComputedStyle(element)[property].slice(0,-1))*1000;
53 promise_test(async (t) => {
54 await mouseOver(unrelated);
55 const popover = document.getElementById('example1');
56 assert_false(popover.matches(':popover-open'));
57 popover.showPopover();
58 assert_true(popover.matches(':popover-open'));
59 await waitForHoverTime(hoverWaitTime);
60 assert_false(popover.matches(':popover-open'));
61 assert_true(msSinceMouseOver() >= hoverWaitTime,'waitForHoverTime should wait the specified time');
62 assert_true(hoverWaitTime > hoverDelays,'hoverDelays is the value from CSS, hoverWaitTime should be longer than that');
63 assert_equals(getComputedStyleTimeMs(invoker1,'popoverShowDelay'),hoverDelays,'popover-show-delay is incorrect');
64 assert_equals(getComputedStyleTimeMs(popover,'popoverHideDelay'),hoverDelays,'popover-hide-delay is incorrect');
65 },`The popover-hide-delay causes a popover to be hidden after a delay`);
67 promise_test(async (t) => {
68 await mouseOver(unrelated);
69 const popover = document.getElementById('example1');
70 assert_false(popover.matches(':popover-open'));
71 popover.showPopover();
72 await mouseOver(popover);
73 await waitForHoverTime(hoverWaitTime);
74 assert_true(popover.matches(':popover-open'),'hovering the popover should keep it showing');
75 await mouseOver(unrelated);
76 let showing = popover.matches(':popover-open');
77 if (msSinceMouseOver() >= hoverDelays)
78 return; // The WPT runner was too slow.
79 assert_true(showing,'hovering unrelated element shouldn\'t immediately hide the popover');
80 await waitForHoverTime(hoverWaitTime);
81 assert_false(popover.matches(':popover-open'),'hovering unrelated element should hide popover after delay');
82 },`hovering the popover keeps it from being hidden`);
84 promise_test(async (t) => {
85 await mouseOver(unrelated);
86 const popover = document.getElementById('example1');
87 const invoker = document.getElementById('invoker1');
88 assert_false(popover.matches(':popover-open'));
89 await mouseOver(invoker);
90 await waitForHoverTime(hoverWaitTime);
91 assert_true(popover.matches(':popover-open'));
92 await waitForHoverTime(hoverWaitTime);
93 assert_true(popover.matches(':popover-open'),'While still hovering the invoker, popover should not be hidden');
94 await mouseOver(popover);
95 await waitForHoverTime(hoverWaitTime);
96 await mouseOver(invoker);
97 await waitForHoverTime(hoverWaitTime);
98 assert_true(popover.matches(':popover-open'),'Moving hover between invoker and popover should keep popover from being hidden');
99 await mouseOver(unrelated);
100 await waitForHoverTime(hoverWaitTime);
101 assert_false(popover.matches(':popover-open'),'Moving hover to unrelated should finally hide the popover');
102 },`hovering a popovertargetaction=hover invoking element keeps the popover from being hidden`);
103 </script>
106 <div popover id=example2>Popover</div>
107 <button popovertarget=example2 popovertargetaction=toggle><span><span data-note=nested_element id=invoker2>Click me</span></span></button>
109 <script>
110 promise_test(async (t) => {
111 await mouseOver(unrelated);
112 const popover = document.getElementById('example2');
113 const invoker = document.getElementById('invoker2');
114 assert_equals(getComputedStyleTimeMs(popover,'popoverHideDelay'),hoverDelays,'popover-hide-delay is incorrect');
115 assert_false(popover.matches(':popover-open'));
116 await mouseOver(invoker);
117 popover.showPopover();
118 await waitForHoverTime(hoverWaitTime);
119 assert_true(popover.matches(':popover-open'),'While hovering an invoker element, popover should not be hidden');
120 await mouseOver(popover);
121 await waitForHoverTime(hoverWaitTime);
122 await mouseOver(invoker);
123 await waitForHoverTime(hoverWaitTime);
124 assert_true(popover.matches(':popover-open'),'Moving hover between invoker and popover should keep popover from being hidden');
125 await mouseOver(unrelated);
126 await waitForHoverTime(hoverWaitTime);
127 assert_false(popover.matches(':popover-open'),'Moving hover to unrelated should finally hide the popover');
128 },`hovering a popovertargetaction=toggle invoking element keeps the popover from being hidden`);
129 </script>