Bug 1531567 - fix intermittent in Event-dispatch-on-disabled-elements.html r=birtles
authorMarcos Cáceres <mcaceres@mozilla.com>
Thu, 07 Mar 2019 05:18:46 +0000
changeset 520706 1d56a0d3a3236253b297d9928083175c2d1b403e
parent 520705 47dfb7c2aa932121e3eb769c87f7d206ab059437
child 520707 6a3b22130b996d2ea931525093f3e6103ed13d20
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles
bugs1531567
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1531567 - fix intermittent in Event-dispatch-on-disabled-elements.html r=birtles change how transitions are triggered and extend the animation/transition time. Differential Revision: https://phabricator.services.mozilla.com/D22251
testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html
--- a/testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html
+++ b/testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html
@@ -1,15 +1,25 @@
 <!doctype html>
 <meta charset="utf8">
 <title>Events must dispatch on disabled elements</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<style>
+  @keyframes fade {
+    0% {
+      opacity: 1;
+    }
+    100% {
+      opacity: 0;
+    }
+  }
+</style>
 <body>
 <script>
 // HTML elements that can be disabled
 const formElements = ["button", "fieldset", "input", "select", "textarea"];
 
 test(() => {
   for (const localName of formElements) {
     const elem = document.createElement(localName);
@@ -94,155 +104,112 @@ test(() => {
       `.click() must dispatch "click" event on enabled ${
         elem.constructor.name
       }.`
     );
   }
 }, "Calling click() on disabled elements must not dispatch events.");
 
 promise_test(async () => {
-  // Style sheet that controls transition.
-  const style = document.createElement("style");
-  style.innerText = `
-    ${formElements.join(", ")} {
-      opacity: 0.1;
-      transition-property: opacity;
-      transition-duration: .1s;
-    }
-    .transition {
-      opacity: 1;
-    }
-  `;
-  document.head.appendChild(style);
-
-  // Triggers the transition in the element being tested.
-  const transitionTrigger = document.createElement("button");
-  transitionTrigger.innerText = "Trigger button";
-  document.body.appendChild(transitionTrigger);
-
   // For each form element type, set up transition event handlers.
   for (const localName of formElements) {
     const elem = document.createElement(localName);
     elem.disabled = true;
     document.body.appendChild(elem);
-    const transitionPromises = [
+    const eventPromises = [
       "transitionrun",
       "transitionstart",
       "transitionend",
     ].map(eventType => {
       return new Promise(r => {
-        const handlerName = `on${eventType}`;
-        elem[handlerName] = ev => {
-          elem[handlerName] = null;
-          r();
-        };
+        elem.addEventListener(eventType, r);
       });
     });
-
-    // Trigger transitions specifically on this element
-    // it requires a trusted event.
-    transitionTrigger.onclick = () => {
-      elem.classList.toggle("transition");
-    };
-    await test_driver.click(transitionTrigger);
-
+    // Flushing style triggers transition.
+    getComputedStyle(elem).opacity;
+    elem.style.transition = "opacity .1s";
+    elem.style.opacity = 0;
+    getComputedStyle(elem).opacity;
     // All the events fire...
-    await Promise.all(transitionPromises);
-    elem.classList.remove("transition");
+    await Promise.all(eventPromises);
+    elem.remove();
+  }
+}, "CSS Transitions transitionrun, transitionstart, transitionend events fire on disabled form elements");
 
-    // Let's now test the "transitioncancel" event.
+promise_test(async () => {
+  // For each form element type, set up transition event handlers.
+  for (const localName of formElements) {
+    const elem = document.createElement(localName);
+    elem.disabled = true;
+    document.body.appendChild(elem);
+    getComputedStyle(elem).opacity;
+    elem.style.transition = "opacity 100s";
+    // We use ontransitionstart to cancel the event.
     elem.ontransitionstart = () => {
-      // Cancel the transition by hiding it.
       elem.style.display = "none";
-      elem.classList.remove("transition");
     };
-
-    // Trigger the transition again!
     const promiseToCancel = new Promise(r => {
       elem.ontransitioncancel = r;
     });
-    await test_driver.click(transitionTrigger);
+    // Flushing style triggers the transition.
+    elem.style.opacity = 0;
+    getComputedStyle(elem).opacity;
     await promiseToCancel;
     // And we are done with this element.
     elem.remove();
   }
-  // And we are done with the test... clean up.
-  transitionTrigger.remove();
-  style.remove();
-}, "CSS Transitions events fire on disabled form elements");
+}, "CSS Transitions transitioncancel event fires on disabled form elements");
 
 promise_test(async () => {
-  const style = document.createElement("style");
-  style.innerText = `
-    .animate {
-      animation: fade .1s 2;
-    }
-    @keyframes fade {
-      0% { opacity: 1; }
-      100% { opacity: 0.2; }
-    }
-  `;
-  document.head.appendChild(style);
   // For each form element type, set up transition event handlers.
   for (const localName of formElements) {
     const elem = document.createElement(localName);
     document.body.appendChild(elem);
     elem.disabled = true;
-    const transitionPromises = [
+    const eventPromises = [
       "animationstart",
       "animationiteration",
       "animationend",
     ].map(eventType => {
       return new Promise(r => {
         elem.addEventListener(eventType, r, { once: true });
       });
     });
+    elem.style.animation = "fade .1s 2";
     elem.classList.add("animate");
     // All the events fire...
-    await Promise.all(transitionPromises);
+    await Promise.all(eventPromises);
     elem.remove();
   }
-  // And we are done with the test... clean up.
-  style.remove();
-}, "CSS Animation events fire on disabled form elements");
+}, "CSS Animation animationstart, animationiteration, animationend fire on disabled form elements");
 
 promise_test(async () => {
-  const style = document.createElement("style");
-  style.innerText = `
-    .animate {
-      animation: fade .1s 2;
-    }
-    @keyframes fade {
-      0% { opacity: 1; }
-      100% { opacity: 0.2; }
-    }
-  `;
-  document.head.appendChild(style);
   // For each form element type, set up transition event handlers.
   for (const localName of formElements) {
     const elem = document.createElement(localName);
     document.body.appendChild(elem);
     elem.disabled = true;
-    // Let's now test the "animationcancel" event
+
     const promiseToCancel = new Promise(r => {
       elem.addEventListener("animationcancel", r);
     });
+
     elem.addEventListener("animationstart", () => {
       // Cancel the animation by hiding it.
       elem.style.display = "none";
     });
+
+    // Trigger the animation
+    elem.style.animation = "fade 100s";
     elem.classList.add("animate");
-    // Trigger the animation again!
     await promiseToCancel;
     // And we are done with this element.
     elem.remove();
   }
-  // And we are done with the test... clean up.
-  style.remove();
-}, "CSS Animation's cancel events fire on disabled form elements");
+}, "CSS Animation's animationcancel event fires on disabled form elements");
 
 promise_test(async () => {
   for (const localName of formElements) {
     const elem = document.createElement(localName);
     elem.disabled = true;
     document.body.appendChild(elem);
     // Element is disabled, so clicking must not fire events
     let pass = true;