diff options
Diffstat (limited to 'javascript/videojs/test/unit/autoplay.test.js')
| -rw-r--r-- | javascript/videojs/test/unit/autoplay.test.js | 481 |
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'); +}); |
