Bug 1311700 - Part 1. add a test to confirm the correctness of video control in different sizes. r=jaws draft
authorRay Lin <ralin@mozilla.com>
Wed, 09 Nov 2016 10:19:02 +0800
changeset 444917 98459692c2b1b5115db05c4e3f39193e6d5a001a
parent 444725 8387a4ada9a5c4cab059d8fafe0f8c933e83c149
child 444918 25d03a82f259d390ea2521e213319f47c29de846
push id37403
push userbmo:ralin@mozilla.com
push dateTue, 29 Nov 2016 02:31:01 +0000
reviewersjaws
bugs1311700
milestone53.0a1
Bug 1311700 - Part 1. add a test to confirm the correctness of video control in different sizes. r=jaws MozReview-Commit-ID: CuCvDYkj3XK
toolkit/content/tests/widgets/mochitest.ini
toolkit/content/tests/widgets/test_videocontrols_size.html
--- a/toolkit/content/tests/widgets/mochitest.ini
+++ b/toolkit/content/tests/widgets/mochitest.ini
@@ -25,16 +25,18 @@ support-files =
 skip-if = toolkit == 'android'
 [test_mousecapture_area.html]
 [test_videocontrols.html]
 tags = fullscreen
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_videocontrols_vtt.html]
 skip-if = toolkit == 'android'
 [test_videocontrols_iframe_fullscreen.html]
+[test_videocontrols_size.html]
+skip-if = toolkit == 'android'
 [test_videocontrols_audio.html]
 [test_videocontrols_audio_direction.html]
 [test_videocontrols_jsdisabled.html]
 skip-if = toolkit == 'android' # bug 1272646
 [test_videocontrols_standalone.html]
 skip-if = toolkit == 'android' # bug 1075573
 [test_videocontrols_video_direction.html]
 skip-if = os == 'win'
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/widgets/test_videocontrols_size.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Video controls test - Size</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+
+<div id="content">
+  <video controls preload="auto" width="480" height="320"></video>
+  <video controls preload="auto" width="320" height="320"></video>
+  <video controls preload="auto" width="280" height="320"></video>
+  <video controls preload="auto" width="240" height="320"></video>
+  <video controls preload="auto" width="180" height="320"></video>
+  <video controls preload="auto" width="120" height="320"></video>
+  <video controls preload="auto" width="60" height="320"></video>
+  <video controls preload="auto" width="48" height="320"></video>
+  <video controls preload="auto" width="20" height="320"></video>
+
+  <video controls preload="auto" width="480" height="240"></video>
+  <video controls preload="auto" width="480" height="120"></video>
+  <video controls preload="auto" width="480" height="39"></video>
+</div>
+
+<pre id="test">
+<script clas="testbody" type="application/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  const domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
+    getService(SpecialPowers.Ci.inIDOMUtils);
+  const videoElems = [...document.getElementsByTagName("video")];
+  const testCases = [];
+
+  const buttonWidth = 30;
+  const minSrubberWidth = 48;
+  const minControlBarHeight = 40;
+  const minControlBarWidth = 48;
+  const minClickToPlaySize = 48;
+
+  function getElementName(elem) {
+    return elem.getAttribute("anonid") || elem.getAttribute("class");
+  }
+
+  function testButton(btn) {
+    if (btn.hidden) return;
+
+    const rect = btn.getBoundingClientRect();
+    const name = getElementName(btn);
+
+    is(rect.width, buttonWidth, `${name} should have correct width`);
+    is(rect.height, minControlBarHeight, `${name} should have correct height`);
+  }
+
+  function testScrubber(scrubber) {
+    if (scrubber.hidden) return;
+
+    const rect = scrubber.getBoundingClientRect();
+    const name = getElementName(scrubber);
+
+    ok(rect.width >= minSrubberWidth, `${name} should longer than ${minSrubberWidth}`);
+  }
+
+  function testUI(video) {
+    video.style.display = "block";
+    video.getBoundingClientRect();
+    video.style.display = "";
+
+    const videoRect = video.getBoundingClientRect();
+
+    const videoHeight = video.clientHeight;
+    const videoWidth = video.clientWidth;
+
+    const videoSizeMsg = `size:${videoRect.width}x${videoRect.height} -`;
+    const controlBar = getElementWithinVideoByAttribute(video, "anonid", "controlBar");
+    const playBtn = getElementWithinVideoByAttribute(video, "anonid", "playButton");
+    const scrubber = getElementWithinVideoByAttribute(video, "anonid", "scrubberStack");
+    const positionDurationBox = getElementWithinVideoByAttribute(video, "anonid", "positionDurationBox");
+    const durationLabel = positionDurationBox.getElementsByTagName("span")[0];
+    const muteBtn = getElementWithinVideoByAttribute(video, "anonid", "muteButton");
+    const volumeStack = getElementWithinVideoByAttribute(video, "anonid", "volumeStack");
+    const fullscreenBtn = getElementWithinVideoByAttribute(video, "anonid", "fullscreenButton");
+    const clickToPlay = getElementWithinVideoByAttribute(video, "anonid", "clickToPlay");
+
+
+    // Controls should show/hide according to the priority
+    const prioritizedControls = [
+      playBtn,
+      muteBtn,
+      fullscreenBtn,
+      positionDurationBox,
+      scrubber,
+      durationLabel,
+      volumeStack
+    ];
+
+    let stopAppend = false;
+    prioritizedControls.forEach(control => {
+      is(control.hidden, stopAppend = stopAppend || control.hidden,
+        `${videoSizeMsg} ${getElementName(control)} should ${stopAppend ? "hide" : "show"}`);
+    });
+
+
+    // All controls should fit in control bar container
+    const controls = [
+      playBtn,
+      scrubber,
+      positionDurationBox,
+      muteBtn,
+      volumeStack,
+      fullscreenBtn
+    ];
+
+    let widthSum = 0;
+    controls.forEach(control => {
+      widthSum += control.clientWidth;
+    });
+    ok(videoWidth >= widthSum,
+      `${videoSizeMsg} controlBar fit in video's width`);
+
+
+    // Control bar should show/hide according to video's dimensions
+    const shouldHideControlBar = videoHeight <= minControlBarHeight ||
+      videoWidth < minControlBarWidth;
+    is(controlBar.hidden, shouldHideControlBar, `${videoSizeMsg} controlBar show/hide`);
+
+    if (!shouldHideControlBar) {
+      is(controlBar.clientWidth, videoWidth, `control bar width should equal to video width`);
+
+      // Check all controls' dimensions
+      testButton(playBtn);
+      testButton(muteBtn);
+      testButton(fullscreenBtn);
+      testScrubber(scrubber);
+      testScrubber(volumeStack);
+    }
+
+
+    // ClickToPlay button should show if min size can fit in
+    const shouldHideClickToPlay = videoWidth <= minClickToPlaySize ||
+      (videoHeight - minClickToPlaySize) / 2 <= minControlBarHeight;
+    is(clickToPlay.hidden, shouldHideClickToPlay, `${videoSizeMsg} clickToPlay show/hide`);
+  }
+
+
+  testCases.push(() => Promise.all(videoElems.map(video => new Promise(resolve => {
+    video.addEventListener("loadedmetadata", resolve, false);
+    video.src = "seek_with_sound.ogg";
+  }))));
+
+  videoElems.forEach(video => {
+    testCases.push(() => new Promise(resolve => {
+      SimpleTest.executeSoon(() => {
+        testUI(video);
+        resolve();
+      });
+    }));
+  });
+
+  function executeTasks(tasks) {
+    return tasks.reduce((promise, task) => promise.then(task), Promise.resolve());
+  }
+
+  function getElementWithinVideoByAttribute(video, aName, aValue) {
+    const videoControl = domUtils.getChildrenForNode(video, true)[1];
+
+    return SpecialPowers.wrap(videoControl.ownerDocument)
+      .getAnonymousElementByAttribute(videoControl, aName, aValue);
+  }
+
+  function start() {
+    executeTasks(testCases).then(SimpleTest.finish);
+  }
+
+  function loadevent() {
+    SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, start);
+  }
+
+  window.addEventListener("load", loadevent, false);
+</script>
+</pre>
+</body>
+</html>