summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/widgets/test_videocontrols.html
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/tests/widgets/test_videocontrols.html')
-rw-r--r--toolkit/content/tests/widgets/test_videocontrols.html411
1 files changed, 411 insertions, 0 deletions
diff --git a/toolkit/content/tests/widgets/test_videocontrols.html b/toolkit/content/tests/widgets/test_videocontrols.html
new file mode 100644
index 000000000..191aaef58
--- /dev/null
+++ b/toolkit/content/tests/widgets/test_videocontrols.html
@@ -0,0 +1,411 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Video controls test</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 width="320" height="240" id="video" controls mozNoDynamicControls preload="auto"></video>
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/*
+ * Positions of the UI elements, relative to the upper-left corner of the
+ * <video> box.
+ */
+const videoWidth = 320;
+const videoHeight = 240;
+const videoDuration = 3.8329999446868896;
+
+const playButtonWidth = 28;
+const playButtonHeight = 28;
+const muteButtonWidth = 33;
+const muteButtonHeight = 28;
+const durationWidth = 34;
+const fullscreenButtonWidth = 28;
+const fullscreenButtonHeight = 28;
+const volumeSliderWidth = 32;
+const scrubberWidth = videoWidth - playButtonWidth - durationWidth - muteButtonWidth - volumeSliderWidth - fullscreenButtonWidth;
+const scrubberHeight = 28;
+
+// Play button is on the bottom-left
+const playButtonCenterX = 0 + Math.round(playButtonWidth / 2);
+const playButtonCenterY = videoHeight - Math.round(playButtonHeight / 2);
+// Mute button is on the bottom-right before the full screen button and volume slider
+const muteButtonCenterX = videoWidth - Math.round(muteButtonWidth / 2) - volumeSliderWidth - fullscreenButtonWidth;
+const muteButtonCenterY = videoHeight - Math.round(muteButtonHeight / 2);
+// Fullscreen button is on the bottom-right at the far end
+const fullscreenButtonCenterX = videoWidth - Math.round(fullscreenButtonWidth / 2);
+const fullscreenButtonCenterY = videoHeight - Math.round(fullscreenButtonHeight / 2);
+// Scrubber bar is between the play and mute buttons. We don't need it's
+// X center, just the offset of its box.
+const scrubberOffsetX = 0 + playButtonWidth;
+const scrubberCenterY = videoHeight - Math.round(scrubberHeight / 2);
+
+var testnum = 1;
+var video = document.getElementById("video");
+
+const domUtil = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
+ .getService(SpecialPowers.Ci.inIDOMUtils);
+
+function getButtonByAttribute(aName, aValue) {
+ var kids = domUtil.getChildrenForNode(video, true);
+ var videocontrols = kids[1];
+ return SpecialPowers.wrap(document)
+ .getAnonymousElementByAttribute(videocontrols, aName, aValue);
+}
+
+function isMuteButtonMuted() {
+ var muteButton = getButtonByAttribute('class', 'muteButton');
+ return muteButton.getAttribute('muted') === 'true';
+}
+
+function isVolumeSliderShowingCorrectVolume(expectedVolume) {
+ var volumeButton = getButtonByAttribute('anonid', 'volumeForeground');
+ let expectedPaddingRight = (1 - expectedVolume) * volumeSliderWidth + "px";
+ is(volumeButton.style.paddingRight, expectedPaddingRight,
+ "volume slider should match expected volume");
+}
+
+function forceReframe() {
+ // Setting display then getting the bounding rect to force a frame
+ // reconstruction on the video element.
+ video.style.display = "block";
+ video.getBoundingClientRect();
+ video.style.display = "";
+ video.getBoundingClientRect();
+}
+
+function runTest(event) {
+ ok(true, "----- test #" + testnum + " -----");
+
+ switch (testnum) {
+ /*
+ * Check operation of play/pause/mute/unmute buttons.
+ */
+ case 1:
+ // Check initial state upon load
+ is(event.type, "canplaythrough", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+
+ // Click the play button
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { });
+ });
+ break;
+
+ case 2:
+ is(event.type, "play", "checking event type");
+ is(video.paused, false, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+
+ // Click the pause button
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { });
+ });
+ break;
+
+ case 3:
+ is(event.type, "pause", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { }); // Mute.
+ });
+ break;
+
+ case 4:
+ is(event.type, "volumechange", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, true, "checking video mute state");
+
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { }); // Unmute.
+ });
+ break;
+
+ /*
+ * Bug 470596: Make sure that having CSS border or padding doesn't
+ * break the controls (though it should move them)
+ */
+ case 5:
+ is(event.type, "volumechange", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+
+ video.style.border = "medium solid purple";
+ video.style.borderWidth = "30px 40px 50px 60px";
+ video.style.padding = "10px 20px 30px 40px";
+ // totals: top: 40px, right: 60px, bottom: 80px, left: 100px
+
+ // Click the play button
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, 100 + playButtonCenterX, 40 + playButtonCenterY, { });
+ });
+ break;
+
+ case 6:
+ is(event.type, "play", "checking event type");
+ is(video.paused, false, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+ video.pause();
+ break;
+
+ case 7:
+ is(event.type, "pause", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+
+ // Click the mute button
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, 100 + muteButtonCenterX, 40 + muteButtonCenterY, { });
+ });
+ break;
+
+ case 8:
+ is(event.type, "volumechange", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, true, "checking video mute state");
+ // Clear the style set in test 5.
+ video.style.border = "";
+ video.style.borderWidth = "";
+ video.style.padding = "";
+
+ video.muted = false;
+ break;
+
+ /*
+ * Previous tests have moved playback postion, reset it to 0.
+ */
+ case 9:
+ is(event.type, "volumechange", "checking event type");
+ is(video.paused, true, "checking video play state");
+ is(video.muted, false, "checking video mute state");
+ ok(true, "video position is at " + video.currentTime);
+ video.currentTime = 0.0;
+ break;
+
+ case 10:
+ is(event.type, "seeking", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ break;
+
+ /*
+ * Drag the slider's thumb to the halfway point with the mouse.
+ */
+ case 11:
+ is(event.type, "seeked", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ // Bug 477434 -- sometimes we get 0.098999 here instead of 0!
+ // is(video.currentTime, 0.0, "checking playback position");
+
+ SimpleTest.executeSoon(() => {
+ var beginDragX = scrubberOffsetX;
+ var endDragX = scrubberOffsetX + (scrubberWidth / 2);
+ synthesizeMouse(video, beginDragX, scrubberCenterY, { type: "mousedown", button: 0 });
+ synthesizeMouse(video, endDragX, scrubberCenterY, { type: "mousemove", button: 0 });
+ synthesizeMouse(video, endDragX, scrubberCenterY, { type: "mouseup", button: 0 });
+ });
+ break;
+
+ case 12:
+ is(event.type, "seeking", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ break;
+
+ /*
+ * Click the slider at the 1/4 point with the mouse (jump backwards)
+ */
+ case 13:
+ is(event.type, "seeked", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ var expectedTime = videoDuration / 2;
+ ok(Math.abs(video.currentTime - expectedTime) < 0.1, "checking expected playback position");
+
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, scrubberOffsetX + (scrubberWidth / 4), scrubberCenterY, { });
+ });
+ break;
+
+ case 14:
+ is(event.type, "seeking", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ break;
+
+ case 15:
+ is(event.type, "seeked", "checking event type");
+ ok(true, "video position is at " + video.currentTime);
+ // The scrubber currently just jumps towards the nearest pageIncrement point, not
+ // precisely to the point clicked. So, expectedTime isn't (videoDuration / 4).
+ // We should end up at 1.733, but sometimes we end up at 1.498. I guess
+ // it's timing depending if the <scale> things it's click-and-hold, or a
+ // single click. So, just make sure we end up less that the previous
+ // position.
+ lastPosition = (videoDuration / 2) - 0.1;
+ ok(video.currentTime < lastPosition, "checking expected playback position");
+
+ // Set volume to 0.1 so one down arrow hit will decrease it to 0.
+ video.volume = 0.1;
+ break;
+
+ // See bug 694696.
+ case 16:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.1, "Volume should be set.");
+ ok(!video.muted, "Video is not muted.");
+
+ video.focus();
+ SimpleTest.executeSoon(() => synthesizeKey("VK_DOWN", {}));
+ break;
+
+ case 17:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0, "Volume should be 0.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => {
+ ok(isMuteButtonMuted(), "Mute button says it's muted");
+ synthesizeKey("VK_UP", {});
+ });
+ break;
+
+ case 18:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.1, "Volume is increased.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => {
+ ok(!isMuteButtonMuted(), "Mute button says it's not muted");
+ synthesizeKey("VK_DOWN", {});
+ });
+ break;
+
+ case 19:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0, "Volume should be 0.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => {
+ ok(isMuteButtonMuted(), "Mute button says it's muted");
+ synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
+ });
+ break;
+
+ case 20:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.5, "Volume should be 0.5.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => synthesizeKey("VK_UP", {}));
+ break;
+
+ case 21:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.6, "Volume should be 0.6.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => {
+ synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
+ });
+ break;
+
+ case 22:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.6, "Volume should be 0.6.");
+ ok(video.muted, "Video is muted.");
+
+ SimpleTest.executeSoon(() => {
+ ok(isMuteButtonMuted(), "Mute button says it's muted");
+ synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
+ });
+ break;
+
+ case 23:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.6, "Volume should be 0.6.");
+ ok(!video.muted, "Video is not muted.");
+
+ SimpleTest.executeSoon(() => {
+ ok(!isMuteButtonMuted(), "Mute button says it's not muted");
+ synthesizeMouse(video, fullscreenButtonCenterX, fullscreenButtonCenterY, { });
+ });
+ break;
+
+ case 24:
+ is(event.type, "mozfullscreenchange", "checking event type");
+ is(video.volume, 0.6, "Volume should still be 0.6");
+ SimpleTest.executeSoon(function() {
+ isVolumeSliderShowingCorrectVolume(video.volume);
+ synthesizeKey("VK_ESCAPE", {});
+ });
+ break;
+
+ case 25:
+ is(event.type, "mozfullscreenchange", "checking event type");
+ is(video.volume, 0.6, "Volume should still be 0.6");
+ SimpleTest.executeSoon(function() {
+ isVolumeSliderShowingCorrectVolume(video.volume);
+ forceReframe();
+ video.focus();
+ synthesizeKey("VK_DOWN", {});
+ });
+ break;
+
+ case 26:
+ is(event.type, "volumechange", "checking event type");
+ is(video.volume, 0.5, "Volume should be decreased by 0.1");
+ SimpleTest.executeSoon(function() {
+ isVolumeSliderShowingCorrectVolume(video.volume);
+ SimpleTest.finish();
+ });
+ break;
+
+ default:
+ throw "unexpected test #" + testnum + " w/ event " + event.type;
+ }
+
+ testnum++;
+}
+
+
+
+function canplaythroughevent(event) {
+ video.removeEventListener("canplaythrough", canplaythroughevent, false);
+ // Other events expected by the test.
+ video.addEventListener("play", runTest, false);
+ video.addEventListener("pause", runTest, false);
+ video.addEventListener("volumechange", runTest, false);
+ video.addEventListener("seeking", runTest, false);
+ video.addEventListener("seeked", runTest, false);
+ document.addEventListener("mozfullscreenchange", runTest, false);
+ // Begin the test.
+ runTest(event);
+}
+
+function startMediaLoad() {
+ // Kick off test once video has loaded, in its canplaythrough event handler.
+ video.src = "seek_with_sound.ogg";
+ video.addEventListener("canplaythrough", canplaythroughevent, false);
+}
+
+function loadevent(event) {
+ SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startMediaLoad);
+}
+
+window.addEventListener("load", loadevent, false);
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>