summaryrefslogtreecommitdiff
path: root/javascript/videojs/test/unit/autoplay.test.js
diff options
context:
space:
mode:
Diffstat (limited to 'javascript/videojs/test/unit/autoplay.test.js')
-rw-r--r--javascript/videojs/test/unit/autoplay.test.js481
1 files changed, 481 insertions, 0 deletions
diff --git a/javascript/videojs/test/unit/autoplay.test.js b/javascript/videojs/test/unit/autoplay.test.js
new file mode 100644
index 0000000..2a3b56f
--- /dev/null
+++ b/javascript/videojs/test/unit/autoplay.test.js
@@ -0,0 +1,481 @@
+/* eslint-env qunit */
+import Player from '../../src/js/player.js';
+import videojs from '../../src/js/video.js';
+import {merge} from '../../src/js/utils/obj';
+import TestHelpers from './test-helpers.js';
+import document from 'global/document';
+import window from 'global/window';
+import sinon from 'sinon';
+
+QUnit.module('autoplay', {
+ beforeEach() {
+ this.clock = sinon.useFakeTimers();
+ // reset players storage
+ for (const playerId in Player.players) {
+ if (Player.players[playerId] !== null) {
+ Player.players[playerId].dispose();
+ }
+ delete Player.players[playerId];
+ }
+
+ const videoTag = TestHelpers.makeTag();
+ const fixture = document.getElementById('qunit-fixture');
+
+ this.counts = {
+ play: 0,
+ muted: 0,
+ success: 0,
+ failure: 0
+ };
+
+ fixture.appendChild(videoTag);
+
+ // These mock promises immediately execute,
+ // effectively synchronising promise chains for testing
+
+ // This will only act on catch calls
+ this.rejectPromise = {
+ then(fn) {
+ return this;
+ },
+ catch(fn) {
+ try {
+ fn();
+ } catch (err) {
+ return this;
+ }
+ return this;
+ }
+ };
+
+ // This will only act on then calls
+ this.resolvePromise = {
+ then(fn) {
+ fn();
+ return this;
+ },
+ catch(fn) {
+ return this;
+ }
+ };
+
+ this.createPlayer = (options = {}, attributes = {}, playRetval = null) => {
+ Object.keys(attributes).forEach((a) => {
+ videoTag.setAttribute(a, attributes[a]);
+ });
+
+ this.player = videojs(videoTag.id, merge({techOrder: ['techFaker']}, options));
+ const oldMuted = this.player.muted;
+
+ this.player.play = () => {
+ this.counts.play++;
+
+ if (playRetval || this.playRetval) {
+ return playRetval || this.playRetval;
+ }
+ };
+
+ this.mutedValue = this.player.muted();
+
+ this.player.muted = (v) => {
+
+ if (typeof v !== 'undefined') {
+ this.counts.muted++;
+ this.mutedValue = v;
+ }
+
+ return oldMuted.call(this.player, v);
+ };
+
+ this.player.on('autoplay-success', () => this.counts.success++);
+ this.player.on('autoplay-failure', () => this.counts.failure++);
+
+ // we have to trigger ready so that we
+ // are waiting for loadstart
+ this.player.tech_.triggerReady();
+ return this.player;
+ };
+ },
+ afterEach() {
+ this.clock.restore();
+ this.player.dispose();
+ }
+});
+
+QUnit.test('option = false no play/muted', function(assert) {
+ this.createPlayer({autoplay: false});
+
+ assert.equal(this.player.autoplay(), false, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = true no play/muted', function(assert) {
+ this.createPlayer({autoplay: true});
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), true, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "random" no play/muted', function(assert) {
+ this.createPlayer({autoplay: 'random'});
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), true, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = null, should be set to false no play/muted', function(assert) {
+ this.createPlayer({autoplay: null});
+
+ assert.equal(this.player.autoplay(), false, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "play" play, no muted', function(assert) {
+ this.createPlayer({autoplay: 'play'}, {}, this.resolvePromise);
+
+ assert.equal(this.player.autoplay(), 'play', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 2, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = true w/ normalizeAutoplay = true play, no muted', function(assert) {
+ this.createPlayer({
+ autoplay: true,
+ normalizeAutoplay: true
+ }, {}, this.resolvePromise);
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 2, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "any" play, no muted', function(assert) {
+ this.createPlayer({autoplay: 'any'}, {}, this.resolvePromise);
+
+ assert.equal(this.player.autoplay(), 'any', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 2, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "muted" play and muted', function(assert) {
+ this.createPlayer({autoplay: 'muted'}, {}, this.resolvePromise);
+
+ assert.equal(this.player.autoplay(), 'muted', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 1, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.counts.success, 2, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "play" play, no muted, rejection ignored', function(assert) {
+ this.createPlayer({autoplay: 'play'}, {}, this.rejectPromise);
+
+ assert.equal(this.player.autoplay(), 'play', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 1, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 2, 'failure count');
+});
+
+QUnit.test('option = "any" play, no muted, rejection leads to muted then play', function(assert) {
+ this.createPlayer({autoplay: 'any'}, {}, this.rejectPromise);
+
+ assert.equal(this.player.autoplay(), 'any', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ // The workflow described here:
+ // Call play() -> on rejection, attempt to set mute to true ->
+ // call play() again -> on rejection, set original mute value ->
+ // catch failure at the end of promise chain
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 1, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 4, 'play count');
+ assert.equal(this.counts.muted, 4, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 2, 'failure count');
+});
+
+QUnit.test('option = "muted" play and muted, rejection ignored', function(assert) {
+ this.createPlayer({autoplay: 'muted'}, {}, this.rejectPromise);
+
+ assert.equal(this.player.autoplay(), 'muted', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ // muted called twice here, as muted is value is restored on failure.
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 1, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 4, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 2, 'failure count');
+});
+
+QUnit.test('option = "muted", attr = true, play and muted', function(assert) {
+ this.createPlayer({autoplay: 'muted'}, {autoplay: true});
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), true, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "play", attr = true, play only', function(assert) {
+ this.createPlayer({autoplay: 'play'}, {autoplay: true});
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), true, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "any", attr = true, play only', function(assert) {
+ this.createPlayer({autoplay: 'any'}, {autoplay: true});
+
+ assert.equal(this.player.autoplay(), true, 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), true, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.tech_.trigger('loadstart');
+ assert.equal(this.counts.play, 0, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "any", play terminated restores muted', function(assert) {
+ this.createPlayer({autoplay: 'any'});
+
+ this.playRetval = {
+ then(fn) {
+ fn();
+ return this;
+ },
+ catch: (fn) => {
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 0, 'muted count');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.playRetval = {
+ then(_fn) {
+ window.setTimeout(_fn, 1);
+ return this;
+ },
+ catch(_fn) {
+ return this;
+ }
+ };
+ const retval = fn();
+
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 1, 'muted count');
+ assert.equal(this.mutedValue, true, 'is muted');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ return retval;
+ }
+ };
+
+ assert.equal(this.player.autoplay(), 'any', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+ assert.equal(this.mutedValue, false, 'is not muted');
+
+ this.player.tech_.trigger('loadstart');
+
+ this.player.runPlayTerminatedQueue_();
+
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.mutedValue, false, 'is not muted');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.runPlayTerminatedQueue_();
+
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.mutedValue, false, 'is not muted');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ // verify autoplay success
+ this.clock.tick(1);
+ assert.equal(this.counts.play, 2, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});
+
+QUnit.test('option = "muted", play terminated restores muted', function(assert) {
+ this.createPlayer({autoplay: 'muted'}, {}, {
+ then(fn) {
+ window.setTimeout(() => {
+ fn();
+ }, 1);
+ return this;
+ },
+ catch(fn) {
+ return this;
+ }
+ });
+
+ assert.equal(this.player.autoplay(), 'muted', 'player.autoplay getter');
+ assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
+
+ this.player.tech_.trigger('loadstart');
+
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 1, 'muted count');
+ assert.equal(this.mutedValue, true, 'is muted');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ this.player.runPlayTerminatedQueue_();
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.mutedValue, false, 'no longer muted');
+ assert.equal(this.counts.success, 0, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+
+ // verify autoplay success
+ this.clock.tick(1);
+ assert.equal(this.counts.play, 1, 'play count');
+ assert.equal(this.counts.muted, 2, 'muted count');
+ assert.equal(this.counts.success, 1, 'success count');
+ assert.equal(this.counts.failure, 0, 'failure count');
+});