| Index: LayoutTests/media/video-autoplay-experiment.html
|
| diff --git a/LayoutTests/media/video-autoplay-experiment.html b/LayoutTests/media/video-autoplay-experiment.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0c7624e07fdb7bfcbb601fd1fb23a18a09b6af6b
|
| --- /dev/null
|
| +++ b/LayoutTests/media/video-autoplay-experiment.html
|
| @@ -0,0 +1,246 @@
|
| +<video autoplay controls></video>
|
| +<script src=media-file.js></script>
|
| +<script src=video-test.js></script>
|
| +<body>
|
| +<pre>
|
| + Check if the autoplay gesture override experiment works. There are a lot
|
| + of config options, so this test just runs all of them.
|
| +
|
| + The "results" table contains one row per config tested.
|
| + == Test Inputs ==
|
| + # - config number, in case you'd like to run just one.
|
| + Flags - autoplay experiment setting being tested.
|
| + E - "enabled" in command line.
|
| + V - "-ifviewport"
|
| + M - "-ifmuted"
|
| + p - "-playmuted"
|
| + For example, EVM means "enabled-ifviewport-ifmuted".
|
| + This test does not check -ifmobile since that check always
|
| + fails outside of android.
|
| + Play w/- how is play requested?
|
| + none - play is not requested.
|
| + attr - autoplay attribute is set on the element.
|
| + play() - play() called after media is ready to play.
|
| + Mute - how is media muted?
|
| + none - media is not muted.
|
| + attr - muted attribute is set on the element.
|
| + js - muted property is set after media is ready to play.
|
| + View - is media in viewport?
|
| + onscreen - element starts out onscreen.
|
| + scroll - element starts offscreen, scrolled into view once
|
| + it is ready to play.
|
| + offscreen - element starts out offscreen and stays offscreen.
|
| +
|
| + == Test Outputs ==
|
| + Early? - did playback start before element was scrolled onscreen? For
|
| + tests in which View!=scroll, this is reported as "-".
|
| + Played? - did playback start by the conclusion of the test?
|
| + Muted? - was the media muted? If the media didn't play, then this is
|
| + reported as "-".
|
| +
|
| +</pre>
|
| +<table id="results">
|
| +<tr>
|
| +<td>#</td>
|
| +<td>Flags</td>
|
| +<td>Play w/</td>
|
| +<td>Mute</td>
|
| +<td>View</td>
|
| +<td>Early?</td>
|
| +<td>Played?</td>
|
| +<td>Muted?</td>
|
| +</tr>
|
| +</table>
|
| +</body>
|
| +
|
| +<script>
|
| +
|
| +// Starting configuration number. This should be zero normally.
|
| +var configNumber = 0;
|
| +
|
| +var mediaFile = findMediaFile("video", "content/test");
|
| +var onscreenParent = document.createElement("div");
|
| +// The onscreen parent's height is also used to make sure that the off-screen
|
| +// parent is, in fact, off-screen.
|
| +onscreenParent.style.height="1000px";
|
| +document.body.insertBefore(onscreenParent, document.body.firstChild);
|
| +// Also create another root that's off the bottom of the window.
|
| +var offscreenParent = document.createElement("div");
|
| +document.body.appendChild(offscreenParent);
|
| +
|
| +function didPlaybackStart(video)
|
| +{
|
| + // We say that the video started if it's not paused or if it played and
|
| + // already ended.
|
| + return !video.paused || video.ended;
|
| +}
|
| +
|
| +function addResultsRow(spec)
|
| +{
|
| + // Add a row to the results table.
|
| + var row = document.getElementById("results").insertRow(-1);
|
| + var td = row.insertCell(0);
|
| +
|
| + // Add experiment number
|
| + row.insertCell(-1).innerText = (""+spec["experimentNumber"]);
|
| +
|
| + // Process experiment type specially.
|
| + var type = spec["experimentType"];
|
| + var smallType = "";
|
| + smallType += (type.indexOf("enabled")>-1)?"E":"";
|
| + smallType += (type.indexOf("-ifviewport")>-1)?"V":"";
|
| + smallType += (type.indexOf("-ifmuted")>-1)?"M":"";
|
| + smallType += (type.indexOf("-playmuted")>-1)?"p":"";
|
| + row.insertCell(-1).innerText = smallType;
|
| +
|
| + // Add remaining fields.
|
| + var fields = [ "autoplayType", "mutedType", "visType", "playedEarly",
|
| + "played", "muted"];
|
| + for(idx in fields)
|
| + row.insertCell(-1).innerText = spec[fields[idx]].substring(0,7);
|
| +}
|
| +
|
| +function configureVideoViaScript(video, spec)
|
| +{
|
| + if (spec.mutedType == "js")
|
| + video.muted = true;
|
| + if(spec.autoplayType == "play()")
|
| + video.play();
|
| +}
|
| +
|
| +function queueNextExperiment()
|
| +{
|
| + // Start the next config, but let the event queue drain.
|
| + setTimeout(runNextConfig, 0);
|
| +}
|
| +
|
| +function checkVideoStatus(video, spec)
|
| +{
|
| + // Update the spec with the results.
|
| + var didStart = didPlaybackStart(video);
|
| + video.spec.played = didStart ? "played" : "no";
|
| + video.spec.muted = didStart ? (video.muted ? "muted" : "unmuted") : "-";
|
| +
|
| + addResultsRow(video.spec);
|
| + video.parentElement.removeChild(video);
|
| +
|
| + // Scroll back to the top, in case this was a scrolling test.
|
| + onscreenParent.scrollIntoView();
|
| +
|
| + queueNextExperiment();
|
| +}
|
| +
|
| +function runOneConfig(spec)
|
| +{
|
| + internals.settings.setAutoplayExperimentMode(spec.experimentType);
|
| +
|
| + // Create, configure, and attach a media element.
|
| + var video = document.createElement("video");
|
| +
|
| + // Pick whether the element will be visible when canPlayThrough.
|
| + if (spec.visType == "onscreen")
|
| + onscreenParent.appendChild(video);
|
| + else
|
| + offscreenParent.appendChild(video);
|
| +
|
| + // Set any attributes before canPlayThrough.
|
| + if (spec.mutedType == "attr")
|
| + video.setAttribute("muted", "true");
|
| + if (spec.autoplayType == "attr")
|
| + video.setAttribute("autoplay", "true");
|
| +
|
| + spec.playedEarly = "-";
|
| +
|
| + // Record the spec in the video element, so that we can display the
|
| + // results later.
|
| + video.spec = spec;
|
| +
|
| + // Wait for canplaythrough before continuing, so that the media
|
| + // might actually be playing.
|
| + video.addEventListener("canplaythrough", function()
|
| + {
|
| + // Now that we can play, if we're supposed to play / mute via js do so.
|
| + configureVideoViaScript(video, spec);
|
| +
|
| + // If we're supposed to scroll the item onscreen after it is ready to
|
| + // play, then do so now.
|
| + if(spec.visType == "scroll") {
|
| + // Record the play state here, too, before we scroll.
|
| + spec.playedEarly = didPlaybackStart(video) ? "yes" : "no";
|
| +
|
| + // We are supposed to scroll the player into view.
|
| + video.scrollIntoView(true);
|
| + // We cause two visibility checks. The first notices the scroll,
|
| + // while the second notices that scrolling has stopped.
|
| + // It would be nicer to trigger location polling here, but that
|
| + // can take ~second to notice that scrolling is stopped.
|
| + window.internals.triggerAutoplayViewportCheck(video);
|
| + window.internals.triggerAutoplayViewportCheck(video);
|
| + // Once those are return, the state should be correct.
|
| + checkVideoStatus(video, spec);
|
| + } else {
|
| + // Record the results immediately.
|
| + checkVideoStatus(video, spec);
|
| + }
|
| + });
|
| +
|
| + // Set the source, which will eventually lead to canPlayThrough.
|
| + video.src=mediaFile;
|
| +}
|
| +
|
| +var experimentTypes = [
|
| + "none",
|
| + "enabled",
|
| + "enabled-ifviewport",
|
| + "enabled-ifviewport-ifmuted",
|
| + "enabled-ifviewport-playmuted"
|
| +];
|
| +var autoplayTypes = ["none", "attr", "play()"];
|
| +var mutedTypes = ["none", "attr", "js"];
|
| +var visTypes = ["onscreen", "scroll", "offscreen"];
|
| +
|
| +function runNextConfig()
|
| +{
|
| + // Convert configNumber into a spec, and run it.
|
| + var exp = configNumber;
|
| +
|
| + // Convert this experiment number into settings.
|
| + var spec = {};
|
| + spec.experimentType = experimentTypes[exp % experimentTypes.length];
|
| + exp = Math.floor(exp / experimentTypes.length);
|
| + spec.autoplayType = autoplayTypes[exp % autoplayTypes.length];
|
| + exp = Math.floor(exp / autoplayTypes.length);
|
| + spec.mutedType = mutedTypes[exp % mutedTypes.length];
|
| + exp = Math.floor(exp / mutedTypes.length);
|
| + spec.visType = visTypes[exp % visTypes.length];
|
| + exp = Math.floor(exp / visTypes.length);
|
| + spec.experimentNumber = configNumber;
|
| +
|
| + // exp>0 here indicates that we've wrapped around.
|
| + if (exp > 0) {
|
| + endTest();
|
| + }
|
| +
|
| + configNumber++;
|
| +
|
| + // To keep the test fast, skip a few combinations.
|
| + var skip = false;
|
| + if (spec.autoplayType == "none" && spec.visType != 'onscreen')
|
| + skip = true;
|
| + else if (spec.experimentType.indexOf("-ifmuted") > -1 && spec.visType != "onscreen")
|
| + skip = true;
|
| + else if (spec.visType == "offscreen" && spec.autoplayType != "attr")
|
| + skip = true;
|
| + else if (spec.experimentType.indexOf("-ifmuted") == -1 && spec.mutedType != "none")
|
| + skip = true;
|
| +
|
| + if (skip)
|
| + queueNextExperiment();
|
| + else
|
| + runOneConfig(spec);
|
| +}
|
| +
|
| +window.internals.settings.setMediaPlaybackRequiresUserGesture(true);
|
| +runNextConfig();
|
| +
|
| +</script>
|
|
|