diff options
Diffstat (limited to 'toolkit/content/tests/widgets/test_videocontrols.html')
-rw-r--r-- | toolkit/content/tests/widgets/test_videocontrols.html | 411 |
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 0000000000..191aaef580 --- /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> |