2016-08-04 17:49:32 +02:00
|
|
|
/* eslint-env qunit */
|
2015-03-26 06:43:41 +02:00
|
|
|
import Player from '../../src/js/player.js';
|
2015-05-04 01:12:38 +02:00
|
|
|
import videojs from '../../src/js/video.js';
|
|
|
|
import * as Dom from '../../src/js/utils/dom.js';
|
|
|
|
import * as browser from '../../src/js/utils/browser.js';
|
|
|
|
import log from '../../src/js/utils/log.js';
|
2015-03-26 06:43:41 +02:00
|
|
|
import MediaError from '../../src/js/media-error.js';
|
2015-04-14 22:08:32 +02:00
|
|
|
import Html5 from '../../src/js/tech/html5.js';
|
2015-03-26 06:43:41 +02:00
|
|
|
import TestHelpers from './test-helpers.js';
|
|
|
|
import document from 'global/document';
|
2016-08-04 17:49:32 +02:00
|
|
|
import sinon from 'sinon';
|
2015-12-07 23:27:33 +02:00
|
|
|
import window from 'global/window';
|
2015-11-26 00:11:36 +02:00
|
|
|
import Tech from '../../src/js/tech/tech.js';
|
|
|
|
import TechFaker from './tech/tech-faker.js';
|
2015-03-26 06:43:41 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
QUnit.module('Player', {
|
2016-08-12 19:51:31 +02:00
|
|
|
beforeEach() {
|
2014-12-03 21:31:39 +02:00
|
|
|
this.clock = sinon.useFakeTimers();
|
2016-11-23 20:52:54 +02:00
|
|
|
// reset players storage
|
|
|
|
for (const playerId in Player.players) {
|
|
|
|
if (Player.players[playerId] !== null) {
|
|
|
|
Player.players[playerId].dispose();
|
|
|
|
}
|
|
|
|
delete Player.players[playerId];
|
|
|
|
}
|
2014-09-02 22:39:08 +03:00
|
|
|
},
|
2016-08-12 19:51:31 +02:00
|
|
|
afterEach() {
|
2014-12-03 21:31:39 +02:00
|
|
|
this.clock.restore();
|
2014-09-02 22:39:08 +03:00
|
|
|
}
|
|
|
|
});
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should create player instance that inherits from component and dispose it', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().nodeName === 'DIV');
|
|
|
|
assert.ok(player.on, 'component function exists');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
player.dispose();
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el() === null, 'element disposed');
|
2013-01-11 00:06:12 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('dispose should not throw if styleEl is missing', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2016-01-14 21:01:30 +02:00
|
|
|
|
|
|
|
player.styleEl_.parentNode.removeChild(player.styleEl_);
|
|
|
|
|
|
|
|
player.dispose();
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el() === null, 'element disposed');
|
2016-01-14 21:01:30 +02:00
|
|
|
});
|
|
|
|
|
2015-08-12 22:51:43 +02:00
|
|
|
// technically, all uses of videojs.options should be replaced with
|
|
|
|
// Player.prototype.options_ in this file and a equivalent test using
|
|
|
|
// videojs.options should be made in video.test.js. Keeping this here
|
|
|
|
// until we make that move.
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should accept options from multiple sources and override in correct order', function(assert) {
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
// Set a global option
|
2015-08-12 22:51:43 +02:00
|
|
|
videojs.options.attr = 1;
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag0 = TestHelpers.makeTag();
|
|
|
|
const player0 = new Player(tag0, { techOrder: ['techFaker'] });
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player0.options_.attr, 1, 'global option was set');
|
2013-01-11 00:06:12 +03:00
|
|
|
player0.dispose();
|
|
|
|
|
|
|
|
// Set a tag level option
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag2 = TestHelpers.makeTag();
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// Attributes must be set as strings
|
|
|
|
tag2.setAttribute('attr', 'asdf');
|
|
|
|
|
|
|
|
const player2 = new Player(tag2, { techOrder: ['techFaker'] });
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player2.options_.attr, 'asdf', 'Tag options overrode global options');
|
2015-08-12 22:51:43 +02:00
|
|
|
player2.dispose();
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
// Set a tag level option
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag3 = TestHelpers.makeTag();
|
|
|
|
|
2015-08-12 22:51:43 +02:00
|
|
|
tag3.setAttribute('attr', 'asdf');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player3 = new Player(tag3, { techOrder: ['techFaker'], attr: 'fdsa' });
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player3.options_.attr, 'fdsa', 'Init options overrode tag and global options');
|
2015-08-12 22:51:43 +02:00
|
|
|
player3.dispose();
|
2013-01-11 00:06:12 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should get tag, source, and track settings', function(assert) {
|
2015-05-17 00:59:46 +02:00
|
|
|
// Partially tested in lib->getElAttributes
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
let html = '<video id="example_1" class="video-js" autoplay preload="none">';
|
|
|
|
|
|
|
|
html += '<source src="http://google.com" type="video/mp4">';
|
|
|
|
html += '<source src="http://google.com" type="video/webm">';
|
|
|
|
html += '<track kind="captions" attrtest>';
|
|
|
|
html += '</video>';
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.options_.autoplay, true, 'autoplay is set to true');
|
|
|
|
assert.equal(player.options_.preload, 'none', 'preload is set to none');
|
|
|
|
assert.equal(player.options_.id, 'example_1', 'id is set to example_1');
|
|
|
|
assert.equal(player.options_.sources.length, 2, 'we have two sources');
|
|
|
|
assert.equal(player.options_.sources[0].src, 'http://google.com', 'first source is google.com');
|
|
|
|
assert.equal(player.options_.sources[0].type, 'video/mp4', 'first time is video/mp4');
|
|
|
|
assert.equal(player.options_.sources[1].type, 'video/webm', 'second type is video/webm');
|
|
|
|
assert.equal(player.options_.tracks.length, 1, 'we have one text track');
|
|
|
|
assert.equal(player.options_.tracks[0].kind, 'captions', 'the text track is a captions file');
|
|
|
|
assert.equal(player.options_.tracks[0].attrtest, '', 'we have an empty attribute called attrtest');
|
2016-04-19 23:09:53 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.notEqual(player.el().className.indexOf('video-js'), -1, 'transferred class from tag to player div');
|
|
|
|
assert.equal(player.el().id, 'example_1', 'transferred id from tag to player div');
|
2016-04-19 23:09:53 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(Player.players[player.id()], player, 'player referenceable from global list');
|
|
|
|
assert.notEqual(tag.id, player.id, 'tag ID no longer is the same as player ID');
|
|
|
|
assert.notEqual(tag.className, player.el().className, 'tag classname updated');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.notEqual(tag.player, player, 'tag player ref killed');
|
|
|
|
assert.ok(!Player.players.example_1, 'global player ref killed');
|
|
|
|
assert.equal(player.el(), null, 'player el killed');
|
2012-12-11 03:40:12 +03:00
|
|
|
});
|
|
|
|
|
2016-11-03 21:50:55 +02:00
|
|
|
QUnit.test('should get current source from source tag', function(assert) {
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
|
|
|
|
const html = [
|
|
|
|
'<video id="example_1" class="video-js" preload="none">',
|
|
|
|
'<source src="http://google.com" type="video/mp4">',
|
|
|
|
'<source src="http://hugo.com" type="video/webm">',
|
|
|
|
'</video>'
|
|
|
|
].join('');
|
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
|
|
|
|
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
|
|
|
assert.ok(player.currentSource().src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSource().type === 'video/mp4');
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-11-03 21:50:55 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('should get current sources from source tag', function(assert) {
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
|
|
|
|
const html = [
|
|
|
|
'<video id="example_1" class="video-js" preload="none">',
|
|
|
|
'<source src="http://google.com" type="video/mp4">',
|
|
|
|
'<source src="http://hugo.com" type="video/webm">',
|
|
|
|
'</video>'
|
|
|
|
].join('');
|
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
|
|
|
|
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
|
|
|
assert.ok(player.currentSources()[0].src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSources()[0].type === 'video/mp4');
|
|
|
|
assert.ok(player.currentSources()[1].src === 'http://hugo.com');
|
|
|
|
assert.ok(player.currentSources()[1].type === 'video/webm');
|
|
|
|
|
|
|
|
// when redefining src expect sources to update accordingly
|
|
|
|
player.src('http://google.com');
|
|
|
|
|
|
|
|
assert.ok(player.currentSources()[0].src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSources()[0].type === undefined);
|
|
|
|
assert.ok(player.currentSources()[1] === undefined);
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-11-03 21:50:55 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('should get current source from src set', function(assert) {
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
|
|
|
|
const html = '<video id="example_1" class="video-js" preload="none"></video>';
|
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
|
|
|
|
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
|
|
|
player.loadTech_('Html5');
|
|
|
|
|
|
|
|
// check for matching undefined src
|
|
|
|
assert.deepEqual(player.currentSource(), {});
|
|
|
|
|
|
|
|
player.src('http://google.com');
|
|
|
|
|
|
|
|
assert.ok(player.currentSource().src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSource().type === undefined);
|
|
|
|
|
|
|
|
player.src({
|
|
|
|
src: 'http://google.com'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.ok(player.currentSource().src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSource().type === undefined);
|
|
|
|
|
|
|
|
player.src({
|
|
|
|
src: 'http://google.com',
|
|
|
|
type: 'video/mp4'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.ok(player.currentSource().src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSource().type === 'video/mp4');
|
2016-12-02 21:17:36 +02:00
|
|
|
player.dispose();
|
2016-11-03 21:50:55 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('should get current sources from src set', function(assert) {
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
|
|
|
|
const html = '<video id="example_1" class="video-js" preload="none"></video>';
|
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
|
|
|
|
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
|
|
|
player.loadTech_('Html5');
|
|
|
|
|
|
|
|
// check for matching undefined src
|
|
|
|
assert.ok(player.currentSources(), []);
|
|
|
|
|
|
|
|
player.src([{
|
|
|
|
src: 'http://google.com'
|
|
|
|
}, {
|
|
|
|
src: 'http://hugo.com'
|
|
|
|
}]);
|
|
|
|
|
|
|
|
assert.ok(player.currentSources()[0].src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSources()[0].type === undefined);
|
|
|
|
assert.ok(player.currentSources()[1].src === 'http://hugo.com');
|
|
|
|
assert.ok(player.currentSources()[1].type === undefined);
|
|
|
|
|
|
|
|
player.src([{
|
|
|
|
src: 'http://google.com',
|
|
|
|
type: 'video/mp4'
|
|
|
|
}, {
|
|
|
|
src: 'http://hugo.com',
|
|
|
|
type: 'video/webm'
|
|
|
|
}]);
|
|
|
|
|
|
|
|
assert.ok(player.currentSources()[0].src === 'http://google.com');
|
|
|
|
assert.ok(player.currentSources()[0].type === 'video/mp4');
|
|
|
|
assert.ok(player.currentSources()[1].src === 'http://hugo.com');
|
|
|
|
assert.ok(player.currentSources()[1].type === 'video/webm');
|
|
|
|
|
|
|
|
// when redefining src expect sources to update accordingly
|
|
|
|
player.src('http://hugo.com');
|
|
|
|
|
|
|
|
assert.ok(player.currentSources()[0].src === 'http://hugo.com');
|
|
|
|
assert.ok(player.currentSources()[0].type === undefined);
|
|
|
|
assert.ok(player.currentSources()[1] === undefined);
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-11-03 21:50:55 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should asynchronously fire error events during source selection', function(assert) {
|
|
|
|
assert.expect(2);
|
2014-09-02 22:39:08 +03:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
sinon.stub(log, 'error');
|
2014-09-02 22:39:08 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
techOrder: ['foo'],
|
|
|
|
sources: [
|
|
|
|
{ src: 'http://vjs.zencdn.net/v/oceans.mp4', type: 'video/mp4' }
|
2014-09-02 22:39:08 +03:00
|
|
|
]
|
|
|
|
});
|
2016-08-04 17:49:32 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.options_.techOrder[0] === 'foo', 'Foo listed as the only tech');
|
2014-09-02 22:39:08 +03:00
|
|
|
|
|
|
|
player.on('error', function(e) {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.error().code === 4, 'Source could not be played error thrown');
|
2014-09-02 22:39:08 +03:00
|
|
|
});
|
|
|
|
|
2014-12-03 21:31:39 +02:00
|
|
|
this.clock.tick(1);
|
2014-09-02 22:39:08 +03:00
|
|
|
|
|
|
|
player.dispose();
|
2015-05-04 01:12:38 +02:00
|
|
|
log.error.restore();
|
2014-09-02 22:39:08 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should set the width, height, and aspect ratio via a css class', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const getStyleText = function(styleEl) {
|
2015-05-14 07:45:01 +02:00
|
|
|
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
|
|
|
|
};
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2015-07-23 21:45:41 +02:00
|
|
|
// NOTE: was using npm/css to parse the actual CSS ast
|
|
|
|
// but the css module doesn't support ie8
|
2016-08-04 17:49:32 +02:00
|
|
|
const confirmSetting = function(prop, val) {
|
2015-07-23 21:45:41 +02:00
|
|
|
let styleText = getStyleText(player.styleEl_);
|
2016-08-04 17:49:32 +02:00
|
|
|
const re = new RegExp(prop + ':\\s?' + val);
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2015-07-23 21:45:41 +02:00
|
|
|
// Lowercase string for IE8
|
|
|
|
styleText = styleText.toLowerCase();
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2015-07-23 21:45:41 +02:00
|
|
|
return !!re.test(styleText);
|
|
|
|
};
|
2013-04-09 02:23:41 +03:00
|
|
|
|
2015-07-23 21:45:41 +02:00
|
|
|
// Initial state
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(!getStyleText(player.styleEl_), 'style element should be empty when the player is given no dimensions');
|
2015-05-14 07:45:01 +02:00
|
|
|
|
|
|
|
// Set only the width
|
|
|
|
player.width(100);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(confirmSetting('width', '100px'), 'style width should equal the supplied width in pixels');
|
|
|
|
assert.ok(confirmSetting('height', '56.25px'), 'style height should match the default aspect ratio of the width');
|
2015-05-14 07:45:01 +02:00
|
|
|
|
|
|
|
// Set the height
|
|
|
|
player.height(200);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(confirmSetting('height', '200px'), 'style height should match the supplied height in pixels');
|
2015-05-14 07:45:01 +02:00
|
|
|
|
|
|
|
// Reset the width and height to defaults
|
|
|
|
player.width('');
|
|
|
|
player.height('');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(confirmSetting('width', '300px'), 'supplying an empty string should reset the width');
|
|
|
|
assert.ok(confirmSetting('height', '168.75px'), 'supplying an empty string should reset the height');
|
2015-05-14 07:45:01 +02:00
|
|
|
|
|
|
|
// Switch to fluid mode
|
|
|
|
player.fluid(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.hasClass('vjs-fluid'), 'the vjs-fluid class should be added to the player');
|
|
|
|
assert.ok(confirmSetting('padding-top', '56.25%'), 'fluid aspect ratio should match the default aspect ratio');
|
2015-05-14 07:45:01 +02:00
|
|
|
|
|
|
|
// Change the aspect ratio
|
|
|
|
player.aspectRatio('4:1');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(confirmSetting('padding-top', '25%'), 'aspect ratio percent should match the newly set aspect ratio');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2013-03-09 11:39:28 +03:00
|
|
|
});
|
|
|
|
|
2016-11-03 21:37:30 +02:00
|
|
|
QUnit.test('should default to 16:9 when fluid', function(assert) {
|
|
|
|
const player = TestHelpers.makePlayer({fluid: true});
|
2016-11-04 00:40:14 +02:00
|
|
|
const ratio = player.currentHeight() / player.currentWidth();
|
2016-11-03 21:37:30 +02:00
|
|
|
|
2016-11-04 00:40:14 +02:00
|
|
|
// IE8 rounds 0.5625 up to 0.563
|
|
|
|
assert.ok(((ratio >= 0.562) && (ratio <= 0.563)), 'fluid player without dimensions defaults to 16:9');
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-11-03 21:37:30 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('should set fluid to true if element has vjs-fluid class', function(assert) {
|
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
|
|
|
|
tag.className += ' vjs-fluid';
|
|
|
|
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
|
|
|
assert.ok(player.fluid(), 'fluid is true with vjs-fluid class');
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-11-03 21:37:30 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should use an class name that begins with an alpha character', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const alphaPlayer = TestHelpers.makePlayer({ id: 'alpha1' });
|
|
|
|
const numericPlayer = TestHelpers.makePlayer({ id: '1numeric' });
|
2015-11-21 00:38:05 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const getStyleText = function(styleEl) {
|
2015-11-21 00:38:05 +02:00
|
|
|
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
|
|
|
|
};
|
|
|
|
|
|
|
|
alphaPlayer.width(100);
|
|
|
|
numericPlayer.width(100);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(/\s*\.alpha1-dimensions\s*\{/.test(getStyleText(alphaPlayer.styleEl_)), 'appends -dimensions to an alpha player ID');
|
|
|
|
assert.ok(/\s*\.dimensions-1numeric\s*\{/.test(getStyleText(numericPlayer.styleEl_)), 'prepends dimensions- to a numeric player ID');
|
2016-08-25 16:58:42 +02:00
|
|
|
alphaPlayer.dispose();
|
|
|
|
numericPlayer.dispose();
|
2015-11-21 00:38:05 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should wrap the original tag in the player div', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
const container = document.createElement('div');
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
container.appendChild(tag);
|
|
|
|
fixture.appendChild(container);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = new Player(tag, { techOrder: ['techFaker'] });
|
|
|
|
const el = player.el();
|
2013-01-11 00:06:12 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(el.parentNode === container, 'player placed at same level as tag');
|
2013-01-11 00:06:12 +03:00
|
|
|
// Tag may be placed inside the player element or it may be removed from the DOM
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(tag.parentNode !== container, 'tag removed from original place');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should set and update the poster value', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const poster = '#';
|
|
|
|
const updatedPoster = 'http://example.com/updated-poster.jpg';
|
2013-08-25 02:34:26 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
2013-08-25 02:34:26 +03:00
|
|
|
|
2013-11-27 03:53:23 +03:00
|
|
|
tag.setAttribute('poster', poster);
|
2013-08-25 02:34:26 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.poster(), poster, 'the poster property should equal the tag attribute');
|
2013-08-25 02:34:26 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
let pcEmitted = false;
|
|
|
|
|
|
|
|
player.on('posterchange', function() {
|
2013-11-27 03:53:23 +03:00
|
|
|
pcEmitted = true;
|
|
|
|
});
|
2013-08-25 02:34:26 +03:00
|
|
|
|
|
|
|
player.poster(updatedPoster);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(pcEmitted, 'posterchange event was emitted');
|
|
|
|
assert.equal(player.poster(), updatedPoster, 'the updated poster is returned');
|
2013-08-25 02:34:26 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2015-02-09 19:11:00 +02:00
|
|
|
// hasStarted() is equivalent to the "show poster flag" in the
|
|
|
|
// standard, for the purpose of displaying the poster image
|
|
|
|
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should hide the poster when play is called', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
2015-02-09 19:11:00 +02:00
|
|
|
poster: 'https://example.com/poster.jpg'
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.hasStarted(), false, 'the show poster flag is true before play');
|
2016-06-28 05:07:00 +02:00
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.hasStarted(), true, 'the show poster flag is false after play');
|
2015-02-09 19:11:00 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.hasStarted(), false, 'the resource selection algorithm sets the show poster flag to true');
|
2015-02-09 19:11:00 +02:00
|
|
|
|
2016-06-28 05:07:00 +02:00
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.hasStarted(), true, 'the show poster flag is false after play');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-02-09 19:11:00 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should load a media controller', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
2013-01-11 00:06:12 +03:00
|
|
|
preload: 'none',
|
|
|
|
sources: [
|
2013-02-09 01:29:04 +03:00
|
|
|
{ src: 'http://google.com', type: 'video/mp4' },
|
|
|
|
{ src: 'http://google.com', type: 'video/webm' }
|
2013-01-11 00:06:12 +03:00
|
|
|
]
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().children[0].className.indexOf('vjs-tech') !== -1, 'media controller loaded');
|
2013-01-11 00:06:12 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
2013-01-18 04:33:53 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should be able to initialize player twice on the same tag using string reference', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
let videoTag = TestHelpers.makeTag();
|
|
|
|
const id = videoTag.id;
|
|
|
|
|
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
2013-03-06 00:23:01 +03:00
|
|
|
|
|
|
|
fixture.appendChild(videoTag);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
let player = videojs(videoTag.id, { techOrder: ['techFaker'] });
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player, 'player is created');
|
2013-03-06 00:23:01 +03:00
|
|
|
player.dispose();
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(!document.getElementById(id), 'element is removed');
|
2015-03-26 06:43:41 +02:00
|
|
|
videoTag = TestHelpers.makeTag();
|
2013-03-06 00:23:01 +03:00
|
|
|
fixture.appendChild(videoTag);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// here we receive cached version instead of real
|
2015-09-28 20:23:25 +02:00
|
|
|
player = videojs(videoTag.id, { techOrder: ['techFaker'] });
|
2016-08-04 17:49:32 +02:00
|
|
|
// here it triggers error, because player was destroyed already after first dispose
|
2013-03-06 00:23:01 +03:00
|
|
|
player.dispose();
|
|
|
|
});
|
2013-05-03 03:15:37 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should set controls and trigger events', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({ controls: false });
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.controls() === false, 'controls set through options');
|
2016-08-04 17:49:32 +02:00
|
|
|
const hasDisabledClass = player.el().className.indexOf('vjs-controls-disabled');
|
2013-05-03 03:15:37 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(hasDisabledClass !== -1, 'Disabled class added to player');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2013-05-03 03:15:37 +03:00
|
|
|
player.controls(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.controls() === true, 'controls updated');
|
2016-08-04 17:49:32 +02:00
|
|
|
const hasEnabledClass = player.el().className.indexOf('vjs-controls-enabled');
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(hasEnabledClass !== -1, 'Disabled class added to player');
|
2013-05-03 03:15:37 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('controlsenabled', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'enabled fired once');
|
2013-08-10 00:29:22 +03:00
|
|
|
});
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('controlsdisabled', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'disabled fired once');
|
2013-05-03 03:15:37 +03:00
|
|
|
});
|
|
|
|
player.controls(false);
|
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should toggle user the user state between active and inactive', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.expect(9);
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.userActive(), 'User should be active at player init');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('userinactive', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'userinactive event triggered');
|
2013-08-10 00:29:22 +03:00
|
|
|
});
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('useractive', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'useractive event triggered');
|
2013-08-10 00:29:22 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
player.userActive(false);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.userActive() === false, 'Player state changed to inactive');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-user-active') === -1, 'Active class removed');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-user-inactive') !== -1, 'Inactive class added');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
player.userActive(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.userActive() === true, 'Player state changed to active');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-user-inactive') === -1, 'Inactive class removed');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-user-active') !== -1, 'Active class added');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should add a touch-enabled classname when touch is supported', function(assert) {
|
|
|
|
assert.expect(1);
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
// Fake touch support. Real touch support isn't needed for this test.
|
2016-08-04 17:49:32 +02:00
|
|
|
const origTouch = browser.TOUCH_ENABLED;
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
browser.TOUCH_ENABLED = true;
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
browser.TOUCH_ENABLED = origTouch;
|
2013-08-10 00:29:22 +03:00
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should allow for tracking when native controls are used', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2013-08-10 00:29:22 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.expect(6);
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
// Make sure native controls is false before starting test
|
|
|
|
player.usingNativeControls(false);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('usingnativecontrols', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'usingnativecontrols event triggered');
|
2013-08-10 00:29:22 +03:00
|
|
|
});
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('usingcustomcontrols', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'usingcustomcontrols event triggered');
|
2013-08-10 00:29:22 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
player.usingNativeControls(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.usingNativeControls() === true, 'Using native controls is true');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-using-native-controls') !== -1, 'Native controls class added');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
player.usingNativeControls(false);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.usingNativeControls() === false, 'Using native controls is false');
|
|
|
|
assert.ok(player.el().className.indexOf('vjs-using-native-controls') === -1, 'Native controls class removed');
|
2013-08-10 00:29:22 +03:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('make sure that controls listeners do not get added too many times', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
|
|
|
let listeners = 0;
|
2015-08-25 22:17:35 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.addTechControlsListeners_ = function() {
|
2015-08-25 22:17:35 +02:00
|
|
|
listeners++;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Make sure native controls is false before starting test
|
|
|
|
player.usingNativeControls(false);
|
|
|
|
|
|
|
|
player.usingNativeControls(true);
|
|
|
|
|
|
|
|
player.controls(true);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(listeners, 0, 'addTechControlsListeners_ should not have gotten called yet');
|
2015-08-25 22:17:35 +02:00
|
|
|
|
|
|
|
player.usingNativeControls(false);
|
|
|
|
player.controls(false);
|
|
|
|
|
|
|
|
player.controls(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(listeners, 1, 'addTechControlsListeners_ should have gotten called once');
|
2015-08-25 22:17:35 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should select the proper tech based on the the sourceOrder option', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
const html =
|
2015-11-26 00:11:36 +02:00
|
|
|
'<video id="example_1">' +
|
|
|
|
'<source src="fake.foo1" type="video/unsupported-format">' +
|
|
|
|
'<source src="fake.foo2" type="video/foo-format">' +
|
|
|
|
'</video>';
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// Extend TechFaker to create a tech that plays the only mime-type that TechFaker
|
|
|
|
// will not play
|
|
|
|
class PlaysUnsupported extends TechFaker {
|
|
|
|
constructor(options, handleReady) {
|
|
|
|
super(options, handleReady);
|
|
|
|
}
|
|
|
|
// Support ONLY "video/unsupported-format"
|
|
|
|
static isSupported() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
static canPlayType(type) {
|
|
|
|
return (type === 'video/unsupported-format' ? 'maybe' : '');
|
|
|
|
}
|
|
|
|
static canPlaySource(srcObj) {
|
|
|
|
return srcObj.type === 'video/unsupported-format';
|
2015-11-26 00:11:36 +02:00
|
|
|
}
|
2016-08-04 17:49:32 +02:00
|
|
|
}
|
|
|
|
Tech.registerTech('PlaysUnsupported', PlaysUnsupported);
|
2015-11-26 00:11:36 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
fixture.innerHTML += html;
|
|
|
|
let tag = document.getElementById('example_1');
|
2015-11-26 00:11:36 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
let player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported'], sourceOrder: true });
|
2015-11-26 00:11:36 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.techName_, 'PlaysUnsupported', 'selected the PlaysUnsupported tech when sourceOrder is truthy');
|
2016-08-04 17:49:32 +02:00
|
|
|
player.dispose();
|
2015-11-26 00:11:36 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
fixture.innerHTML += html;
|
|
|
|
tag = document.getElementById('example_1');
|
|
|
|
|
|
|
|
player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported']});
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.techName_, 'TechFaker', 'selected the TechFaker tech when sourceOrder is falsey');
|
2016-08-04 17:49:32 +02:00
|
|
|
player.dispose();
|
2015-11-26 00:11:36 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should register players with generated ids', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
|
|
|
|
const video = document.createElement('video');
|
2013-12-03 02:29:41 +03:00
|
|
|
|
|
|
|
video.className = 'vjs-default-skin video-js';
|
|
|
|
fixture.appendChild(video);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = new Player(video, { techOrder: ['techFaker'] });
|
|
|
|
const id = player.el().id;
|
2013-12-03 02:29:41 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.el().id, player.id(), 'the player and element ids are equal');
|
|
|
|
assert.ok(Player.players[id], 'the generated id is registered');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2013-12-03 02:29:41 +03:00
|
|
|
});
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should not add multiple first play events despite subsequent loads', function(assert) {
|
|
|
|
assert.expect(1);
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
player.on('firstplay', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'First play should fire once.');
|
2014-04-03 20:41:02 +03:00
|
|
|
});
|
|
|
|
|
2015-05-06 20:01:52 +02:00
|
|
|
// Checking to make sure onLoadStart removes first play listener before adding a new one.
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
player.tech_.trigger('play');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-04-03 20:41:02 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should fire firstplay after resetting the player', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2014-06-11 02:55:08 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
let fpFired = false;
|
|
|
|
|
|
|
|
player.on('firstplay', function() {
|
2014-06-11 02:55:08 +03:00
|
|
|
fpFired = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
// init firstplay listeners
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(fpFired, 'First firstplay fired');
|
2014-06-11 02:55:08 +03:00
|
|
|
|
|
|
|
// reset the player
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
2014-06-11 02:55:08 +03:00
|
|
|
fpFired = false;
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(fpFired, 'Second firstplay fired');
|
2014-06-11 02:55:08 +03:00
|
|
|
|
|
|
|
// the play event can fire before the loadstart event.
|
|
|
|
// in that case we still want the firstplay even to fire.
|
2016-08-04 17:49:32 +02:00
|
|
|
player.tech_.paused = function() {
|
|
|
|
return false;
|
|
|
|
};
|
2014-06-11 02:55:08 +03:00
|
|
|
fpFired = false;
|
|
|
|
// reset the player
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
// player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(fpFired, 'Third firstplay fired');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-06-11 02:55:08 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should remove vjs-has-started class', function(assert) {
|
|
|
|
assert.expect(3);
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added');
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-has-started') === -1, 'vjs-has-started class removed');
|
2014-04-03 20:41:02 +03:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('play');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added again');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-04-03 20:41:02 +03:00
|
|
|
});
|
2014-05-13 03:08:48 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should add and remove vjs-ended class', function(assert) {
|
|
|
|
assert.expect(4);
|
2015-02-13 01:15:44 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
2015-02-13 01:15:44 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
|
|
|
player.tech_.trigger('play');
|
|
|
|
player.tech_.trigger('ended');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class added');
|
2015-02-13 01:15:44 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('play');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
|
2015-02-13 01:15:44 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('ended');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class re-added');
|
2015-02-13 01:15:44 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('loadstart');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-02-13 01:15:44 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('player should handle different error types', function(assert) {
|
|
|
|
assert.expect(8);
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({});
|
|
|
|
const testMsg = 'test message';
|
2014-05-13 03:08:48 +03:00
|
|
|
|
|
|
|
// prevent error log messages in the console
|
2015-05-04 01:12:38 +02:00
|
|
|
sinon.stub(log, 'error');
|
2014-05-13 03:08:48 +03:00
|
|
|
|
|
|
|
// error code supplied
|
2016-08-04 17:49:32 +02:00
|
|
|
function errCode() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.error().code, 1, 'error code is correct');
|
2014-05-13 03:08:48 +03:00
|
|
|
}
|
|
|
|
player.on('error', errCode);
|
|
|
|
player.error(1);
|
|
|
|
player.off('error', errCode);
|
|
|
|
|
|
|
|
// error instance supplied
|
2016-08-04 17:49:32 +02:00
|
|
|
function errInst() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.error().code, 2, 'MediaError code is correct');
|
|
|
|
assert.equal(player.error().message, testMsg, 'MediaError message is correct');
|
2014-05-13 03:08:48 +03:00
|
|
|
}
|
|
|
|
player.on('error', errInst);
|
2015-03-26 06:43:41 +02:00
|
|
|
player.error(new MediaError({ code: 2, message: testMsg }));
|
2014-05-13 03:08:48 +03:00
|
|
|
player.off('error', errInst);
|
|
|
|
|
|
|
|
// error message supplied
|
2016-08-04 17:49:32 +02:00
|
|
|
function errMsg() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.error().code, 0, 'error message code is correct');
|
|
|
|
assert.equal(player.error().message, testMsg, 'error message is correct');
|
2014-05-13 03:08:48 +03:00
|
|
|
}
|
|
|
|
player.on('error', errMsg);
|
|
|
|
player.error(testMsg);
|
|
|
|
player.off('error', errMsg);
|
|
|
|
|
|
|
|
// error config supplied
|
2016-08-04 17:49:32 +02:00
|
|
|
function errConfig() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.error().code, 3, 'error config code is correct');
|
|
|
|
assert.equal(player.error().message, testMsg, 'error config message is correct');
|
2014-05-13 03:08:48 +03:00
|
|
|
}
|
|
|
|
player.on('error', errConfig);
|
|
|
|
player.error({ code: 3, message: testMsg });
|
|
|
|
player.off('error', errConfig);
|
|
|
|
|
|
|
|
// check for vjs-error classname
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf('vjs-error') >= 0, 'player does not have vjs-error classname');
|
2014-05-13 03:08:48 +03:00
|
|
|
|
|
|
|
// restore error logging
|
2015-05-04 01:12:38 +02:00
|
|
|
log.error.restore();
|
2016-08-25 16:58:42 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2014-05-13 03:08:48 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Data attributes on the video element should persist in the new wrapper element', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const dataId = 123;
|
2014-07-01 22:10:45 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
2014-07-01 22:10:45 +03:00
|
|
|
|
|
|
|
tag.setAttribute('data-id', dataId);
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
2014-07-01 22:10:45 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2014-07-01 22:10:45 +03:00
|
|
|
});
|
2014-08-05 01:12:17 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should restore attributes from the original video tag when creating a new element', function(assert) {
|
2014-08-05 01:04:39 +03:00
|
|
|
// simulate attributes stored from the original tag
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = Dom.createEl('video');
|
|
|
|
|
2015-05-06 20:01:52 +02:00
|
|
|
tag.setAttribute('preload', 'auto');
|
|
|
|
tag.setAttribute('autoplay', '');
|
|
|
|
tag.setAttribute('webkit-playsinline', '');
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const html5Mock = { options_: {tag} };
|
2014-08-05 01:12:17 +03:00
|
|
|
|
2014-08-05 01:04:39 +03:00
|
|
|
// set options that should override tag attributes
|
2015-05-06 20:01:52 +02:00
|
|
|
html5Mock.options_.preload = 'none';
|
2014-08-05 01:12:17 +03:00
|
|
|
|
2014-08-05 01:04:39 +03:00
|
|
|
// create the element
|
2016-08-04 17:49:32 +02:00
|
|
|
const el = Html5.prototype.createEl.call(html5Mock);
|
2014-08-05 01:12:17 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(el.getAttribute('preload'), 'none', 'attribute was successful overridden by an option');
|
|
|
|
assert.equal(el.getAttribute('autoplay'), '', 'autoplay attribute was set properly');
|
|
|
|
assert.equal(el.getAttribute('webkit-playsinline'), '', 'webkit-playsinline attribute was set properly');
|
2014-08-05 01:12:17 +03:00
|
|
|
});
|
2014-08-25 12:28:52 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should honor default inactivity timeout', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const clock = sinon.useFakeTimers();
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// default timeout is 2000ms
|
|
|
|
const player = TestHelpers.makePlayer({});
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is active on creation');
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.tick(1800);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is still active');
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.tick(500);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), false, 'User is inactive after timeout expired');
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.restore();
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-08-25 12:35:06 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should honor configured inactivity timeout', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const clock = sinon.useFakeTimers();
|
2014-08-25 12:28:52 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// default timeout is 2000ms, set to shorter 200ms
|
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
inactivityTimeout: 200
|
|
|
|
});
|
2014-08-25 12:28:52 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is active on creation');
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.tick(150);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is still active');
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.tick(350);
|
|
|
|
// make sure user is now inactive after 500ms
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), false, 'User is inactive after timeout expired');
|
2014-08-25 17:42:58 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.restore();
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-08-25 12:28:52 +03:00
|
|
|
});
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should honor disabled inactivity timeout', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const clock = sinon.useFakeTimers();
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
// default timeout is 2000ms, disable by setting to zero
|
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
inactivityTimeout: 0
|
|
|
|
});
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is active on creation');
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.tick(5000);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.userActive(), true, 'User is still active');
|
2014-08-25 12:35:06 +03:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
clock.restore();
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-08-25 12:35:06 +03:00
|
|
|
});
|
2014-09-04 18:51:05 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should clear pending errors on disposal', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const clock = sinon.useFakeTimers();
|
|
|
|
|
|
|
|
const player = TestHelpers.makePlayer();
|
2014-09-04 18:51:05 +03:00
|
|
|
|
|
|
|
player.src({
|
|
|
|
src: 'http://example.com/movie.unsupported-format',
|
|
|
|
type: 'video/unsupported-format'
|
|
|
|
});
|
|
|
|
player.dispose();
|
|
|
|
try {
|
|
|
|
clock.tick(5000);
|
|
|
|
} catch (e) {
|
2016-08-12 19:51:31 +02:00
|
|
|
return assert.ok(!e, 'threw an error: ' + e.message);
|
2014-09-04 18:51:05 +03:00
|
|
|
}
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(true, 'did not throw an error after disposal');
|
2014-09-04 18:51:05 +03:00
|
|
|
});
|
2014-09-16 20:55:55 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('pause is called when player ended event is fired and player is not paused', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const video = document.createElement('video');
|
|
|
|
const player = TestHelpers.makePlayer({}, video);
|
|
|
|
let pauses = 0;
|
|
|
|
|
2014-09-16 20:55:55 +03:00
|
|
|
player.paused = function() {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
player.pause = function() {
|
|
|
|
pauses++;
|
|
|
|
};
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('ended');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(pauses, 1, 'pause was called');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-09-16 20:55:55 +03:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('pause is not called if the player is paused and ended is fired', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const video = document.createElement('video');
|
|
|
|
const player = TestHelpers.makePlayer({}, video);
|
|
|
|
let pauses = 0;
|
|
|
|
|
2014-09-16 20:55:55 +03:00
|
|
|
player.paused = function() {
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
player.pause = function() {
|
|
|
|
pauses++;
|
|
|
|
};
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.trigger('ended');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(pauses, 0, 'pause was not called when ended fired');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-09-16 20:55:55 +03:00
|
|
|
});
|
2014-10-01 04:34:51 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should add an audio class if an audio el is used', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const audio = document.createElement('audio');
|
|
|
|
const player = TestHelpers.makePlayer({}, audio);
|
|
|
|
const audioClass = 'vjs-audio';
|
2014-10-01 04:34:51 +03:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().className.indexOf(audioClass) !== -1, 'added ' + audioClass + ' css class');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2014-10-01 04:34:51 +03:00
|
|
|
});
|
2015-04-28 22:33:20 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should add a video player region if a video el is used', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const video = document.createElement('video');
|
|
|
|
const player = TestHelpers.makePlayer({}, video);
|
2016-04-05 19:47:58 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().getAttribute('role') === 'region', 'region role is present');
|
|
|
|
assert.ok(player.el().getAttribute('aria-label') === 'video player', 'video player label present');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-04-05 19:47:58 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should add an audio player region if an audio el is used', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const audio = document.createElement('audio');
|
|
|
|
const player = TestHelpers.makePlayer({}, audio);
|
2016-04-05 19:47:58 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.el().getAttribute('role') === 'region', 'region role is present');
|
|
|
|
assert.ok(player.el().getAttribute('aria-label') === 'audio player', 'audio player label present');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-04-05 19:47:58 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should not be scrubbing while not seeking', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.scrubbing(), false, 'player is not scrubbing');
|
|
|
|
assert.ok(player.el().className.indexOf('scrubbing') === -1, 'scrubbing class is not present');
|
2015-04-28 22:33:20 +02:00
|
|
|
player.scrubbing(false);
|
2016-08-25 16:58:42 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.scrubbing(), false, 'player is not scrubbing');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-04-28 22:33:20 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should be scrubbing while seeking', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
|
2015-04-28 22:33:20 +02:00
|
|
|
player.scrubbing(true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.scrubbing(), true, 'player is scrubbing');
|
|
|
|
assert.ok(player.el().className.indexOf('scrubbing') !== -1, 'scrubbing class is present');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-04-28 22:33:20 +02:00
|
|
|
});
|
2015-04-29 23:05:22 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should throw on startup no techs are specified', function(assert) {
|
2015-08-12 22:51:43 +02:00
|
|
|
const techOrder = videojs.options.techOrder;
|
2015-04-29 23:05:22 +02:00
|
|
|
|
2015-08-12 22:51:43 +02:00
|
|
|
videojs.options.techOrder = null;
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.throws(function() {
|
2015-04-29 23:05:22 +02:00
|
|
|
videojs(TestHelpers.makeTag());
|
|
|
|
}, 'a falsey techOrder should throw');
|
|
|
|
|
2015-08-12 22:51:43 +02:00
|
|
|
videojs.options.techOrder = techOrder;
|
2015-04-29 23:05:22 +02:00
|
|
|
});
|
2015-05-01 23:16:19 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should have a sensible toJSON that is equivalent to player.options', function(assert) {
|
2015-05-01 23:16:19 +02:00
|
|
|
const playerOptions = {
|
|
|
|
html5: {
|
|
|
|
nativeTextTracks: false
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const player = TestHelpers.makePlayer(playerOptions);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.deepEqual(player.toJSON(), player.options_, 'simple player options toJSON produces output equivalent to player.options_');
|
2015-05-01 23:16:19 +02:00
|
|
|
|
|
|
|
const playerOptions2 = {
|
|
|
|
tracks: [{
|
|
|
|
label: 'English',
|
|
|
|
srclang: 'en',
|
|
|
|
src: '../docs/examples/shared/example-captions.vtt',
|
|
|
|
kind: 'captions'
|
|
|
|
}]
|
|
|
|
};
|
|
|
|
|
|
|
|
const player2 = TestHelpers.makePlayer(playerOptions2);
|
|
|
|
|
|
|
|
playerOptions2.tracks[0].player = player2;
|
|
|
|
|
2015-06-05 02:33:34 +02:00
|
|
|
const popts = player2.options_;
|
2016-08-04 17:49:32 +02:00
|
|
|
|
2015-05-01 23:16:19 +02:00
|
|
|
popts.tracks[0].player = undefined;
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.deepEqual(player2.toJSON(), popts, 'no circular references');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
player2.dispose();
|
2015-05-01 23:16:19 +02:00
|
|
|
});
|
2015-05-20 00:33:52 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should ignore case in language codes and try primary code', function(assert) {
|
|
|
|
assert.expect(3);
|
2015-05-20 00:33:52 +02:00
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
languages: {
|
2015-05-20 00:33:52 +02:00
|
|
|
'en-gb': {
|
2016-08-04 17:49:32 +02:00
|
|
|
Good: 'Brilliant'
|
2015-05-20 00:33:52 +02:00
|
|
|
},
|
|
|
|
'EN': {
|
2016-08-04 17:49:32 +02:00
|
|
|
Good: 'Awesome',
|
|
|
|
Error: 'Problem'
|
2015-05-20 00:33:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
player.language('en-gb');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.strictEqual(player.localize('Good'), 'Brilliant', 'Used subcode specific localisation');
|
|
|
|
assert.strictEqual(player.localize('Error'), 'Problem', 'Used primary code localisation');
|
2015-05-20 00:33:52 +02:00
|
|
|
player.language('en-GB');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.strictEqual(player.localize('Good'), 'Brilliant', 'Ignored case');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-05-20 00:33:52 +02:00
|
|
|
});
|
2015-10-27 19:46:05 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('inherits language from parent element', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
const oldLang = fixture.getAttribute('lang');
|
2016-07-18 20:53:31 +02:00
|
|
|
|
|
|
|
fixture.setAttribute('lang', 'x-test');
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2016-07-18 20:53:31 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.language(), 'x-test', 'player inherits parent element language');
|
2016-07-18 20:53:31 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
if (oldLang) {
|
|
|
|
fixture.setAttribute('lang', oldLang);
|
|
|
|
} else {
|
|
|
|
fixture.removeAttribute('lang');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should return correct values for canPlayType', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2015-10-27 19:46:05 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.canPlayType('video/mp4'), 'maybe', 'player can play mp4 files');
|
|
|
|
assert.equal(player.canPlayType('video/unsupported-format'), '', 'player can not play unsupported files');
|
2015-10-27 19:46:05 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
2015-10-28 19:28:15 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('createModal()', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const modal = player.createModal('foo');
|
|
|
|
const spy = sinon.spy();
|
2015-10-28 19:28:15 +02:00
|
|
|
|
|
|
|
modal.on('dispose', spy);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.expect(5);
|
|
|
|
assert.strictEqual(modal.el().parentNode, player.el(), 'the modal is injected into the player');
|
|
|
|
assert.strictEqual(modal.content(), 'foo', 'content is set properly');
|
|
|
|
assert.ok(modal.opened(), 'modal is opened by default');
|
2015-10-28 19:28:15 +02:00
|
|
|
modal.close();
|
2016-08-25 16:58:42 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(spy.called, 'modal was disposed when closed');
|
|
|
|
assert.strictEqual(player.children().indexOf(modal), -1, 'modal was removed from player\'s children');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-10-28 19:28:15 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('createModal() options object', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const modal = player.createModal('foo', {content: 'bar', label: 'boo'});
|
2015-10-28 19:28:15 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.expect(2);
|
|
|
|
assert.strictEqual(modal.content(), 'foo', 'content argument takes precedence');
|
|
|
|
assert.strictEqual(modal.options_.label, 'boo', 'modal options are set properly');
|
2015-10-28 19:28:15 +02:00
|
|
|
modal.close();
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-10-28 19:28:15 +02:00
|
|
|
});
|
2015-11-24 22:37:34 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('you can clear error in the error event', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2015-11-24 22:37:34 +02:00
|
|
|
|
|
|
|
sinon.stub(log, 'error');
|
|
|
|
|
|
|
|
player.error({code: 4});
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(player.error(), 'we have an error');
|
2015-11-24 22:37:34 +02:00
|
|
|
player.error(null);
|
|
|
|
|
|
|
|
player.one('error', function() {
|
|
|
|
player.error(null);
|
|
|
|
});
|
|
|
|
player.error({code: 4});
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(!player.error(), 'we no longer have an error');
|
2015-11-24 22:37:34 +02:00
|
|
|
|
|
|
|
log.error.restore();
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-11-24 22:37:34 +02:00
|
|
|
});
|
2015-12-07 23:27:33 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Player#tech will return tech given the appropriate input', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const tech_ = {};
|
|
|
|
const returnedTech = Player.prototype.tech.call({tech_}, {IWillNotUseThisInPlugins: true});
|
2015-12-07 23:27:33 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(returnedTech, tech_, 'We got back the tech we wanted');
|
2015-12-07 23:27:33 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Player#tech alerts and throws without the appropriate input', function(assert) {
|
2015-12-07 23:27:33 +02:00
|
|
|
let alertCalled;
|
2016-08-04 17:49:32 +02:00
|
|
|
const oldAlert = window.alert;
|
|
|
|
|
|
|
|
window.alert = () => {
|
|
|
|
alertCalled = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
const tech_ = {};
|
2015-12-07 23:27:33 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.throws(function() {
|
2015-12-07 23:27:33 +02:00
|
|
|
Player.prototype.tech.call({tech_});
|
|
|
|
}, new RegExp('https://github.com/videojs/video.js/issues/2617'),
|
|
|
|
'we threw an error');
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(alertCalled, 'we called an alert');
|
2015-12-07 23:27:33 +02:00
|
|
|
window.alert = oldAlert;
|
|
|
|
});
|
2015-12-08 00:45:50 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('player#reset loads the Html5 tech and then techCalls reset', function(assert) {
|
2015-12-08 00:45:50 +02:00
|
|
|
let loadedTech;
|
|
|
|
let loadedSource;
|
|
|
|
let techCallMethod;
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const testPlayer = {
|
2015-12-08 00:45:50 +02:00
|
|
|
options_: {
|
2016-08-04 17:49:32 +02:00
|
|
|
techOrder: ['html5', 'flash']
|
2015-12-08 00:45:50 +02:00
|
|
|
},
|
|
|
|
loadTech_(tech, source) {
|
|
|
|
loadedTech = tech;
|
|
|
|
loadedSource = source;
|
|
|
|
},
|
|
|
|
techCall_(method) {
|
|
|
|
techCallMethod = method;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Player.prototype.reset.call(testPlayer);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(loadedTech, 'Html5', 'we loaded the html5 tech');
|
|
|
|
assert.equal(loadedSource, null, 'with a null source');
|
|
|
|
assert.equal(techCallMethod, 'reset', 'we then reset the tech');
|
2015-12-08 00:45:50 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('player#reset loads the first item in the techOrder and then techCalls reset', function(assert) {
|
2015-12-08 00:45:50 +02:00
|
|
|
let loadedTech;
|
|
|
|
let loadedSource;
|
|
|
|
let techCallMethod;
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const testPlayer = {
|
2015-12-08 00:45:50 +02:00
|
|
|
options_: {
|
2016-08-04 17:49:32 +02:00
|
|
|
techOrder: ['flash', 'html5']
|
2015-12-08 00:45:50 +02:00
|
|
|
},
|
|
|
|
loadTech_(tech, source) {
|
|
|
|
loadedTech = tech;
|
|
|
|
loadedSource = source;
|
|
|
|
},
|
|
|
|
techCall_(method) {
|
|
|
|
techCallMethod = method;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Player.prototype.reset.call(testPlayer);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(loadedTech, 'Flash', 'we loaded the Flash tech');
|
|
|
|
assert.equal(loadedSource, null, 'with a null source');
|
|
|
|
assert.equal(techCallMethod, 'reset', 'we then reset the tech');
|
2015-12-08 00:45:50 +02:00
|
|
|
});
|
2016-03-07 21:48:15 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Remove waiting class on timeupdate after tech waiting', function(assert) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
|
2016-03-07 21:48:15 +02:00
|
|
|
player.tech_.trigger('waiting');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(/vjs-waiting/.test(player.el().className), 'vjs-waiting is added to the player el on tech waiting');
|
2016-03-07 21:48:15 +02:00
|
|
|
player.trigger('timeupdate');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(!(/vjs-waiting/).test(player.el().className), 'vjs-waiting is removed from the player el on timeupdate');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-03-07 21:48:15 +02:00
|
|
|
});
|
2016-03-25 20:06:39 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Make sure that player\'s style el respects VIDEOJS_NO_DYNAMIC_STYLE option', function(assert) {
|
2016-03-25 20:06:39 +02:00
|
|
|
// clear the HEAD before running this test
|
|
|
|
let styles = document.querySelectorAll('style');
|
|
|
|
let i = styles.length;
|
2016-08-04 17:49:32 +02:00
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
while (i--) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const style = styles[i];
|
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
style.parentNode.removeChild(style);
|
|
|
|
}
|
|
|
|
|
|
|
|
let tag = TestHelpers.makeTag();
|
2016-08-04 17:49:32 +02:00
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
tag.id = 'vjs-no-base-theme-tag';
|
|
|
|
tag.width = 600;
|
|
|
|
tag.height = 300;
|
|
|
|
|
|
|
|
window.VIDEOJS_NO_DYNAMIC_STYLE = true;
|
2016-08-04 17:49:32 +02:00
|
|
|
TestHelpers.makePlayer({}, tag);
|
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
styles = document.querySelectorAll('style');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(styles.length, 0, 'we should not get any style elements included in the DOM');
|
2016-03-25 20:06:39 +02:00
|
|
|
|
|
|
|
window.VIDEOJS_NO_DYNAMIC_STYLE = false;
|
2016-03-28 18:08:00 +02:00
|
|
|
tag = TestHelpers.makeTag();
|
2016-08-04 17:49:32 +02:00
|
|
|
TestHelpers.makePlayer({}, tag);
|
2016-03-25 20:06:39 +02:00
|
|
|
styles = document.querySelectorAll('style');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(styles.length, 1, 'we should have one style element in the DOM');
|
|
|
|
assert.equal(styles[0].className, 'vjs-styles-dimensions', 'the class name is the one we expected');
|
2016-03-25 20:06:39 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('When VIDEOJS_NO_DYNAMIC_STYLE is set, apply sizing directly to the tech el', function(assert) {
|
2016-03-25 20:06:39 +02:00
|
|
|
// clear the HEAD before running this test
|
2016-08-04 17:49:32 +02:00
|
|
|
const styles = document.querySelectorAll('style');
|
2016-03-25 20:06:39 +02:00
|
|
|
let i = styles.length;
|
2016-08-04 17:49:32 +02:00
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
while (i--) {
|
2016-08-04 17:49:32 +02:00
|
|
|
const style = styles[i];
|
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
style.parentNode.removeChild(style);
|
|
|
|
}
|
|
|
|
|
2016-08-04 17:49:32 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
|
2016-03-25 20:06:39 +02:00
|
|
|
tag.id = 'vjs-no-base-theme-tag';
|
|
|
|
tag.width = 600;
|
|
|
|
tag.height = 300;
|
|
|
|
|
|
|
|
window.VIDEOJS_NO_DYNAMIC_STYLE = true;
|
2016-08-04 17:49:32 +02:00
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
2016-03-25 20:06:39 +02:00
|
|
|
|
|
|
|
player.width(300);
|
|
|
|
player.height(600);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.tech_.el().width, 300, 'the width is equal to 300');
|
|
|
|
assert.equal(player.tech_.el().height, 600, 'the height is equal 600');
|
2016-03-25 20:06:39 +02:00
|
|
|
|
|
|
|
player.width(600);
|
|
|
|
player.height(300);
|
2016-08-25 16:58:42 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.tech_.el().width, 600, 'the width is equal to 600');
|
|
|
|
assert.equal(player.tech_.el().height, 300, 'the height is equal 300');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-03-25 20:06:39 +02:00
|
|
|
});
|
2016-11-23 20:52:54 +02:00
|
|
|
|
|
|
|
QUnit.test('should allow to register custom player when any player has not been created', function(assert) {
|
|
|
|
class CustomPlayer extends Player {}
|
|
|
|
videojs.registerComponent('Player', CustomPlayer);
|
|
|
|
|
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
const player = videojs(tag);
|
|
|
|
|
|
|
|
assert.equal(player instanceof CustomPlayer, true, 'player is custom');
|
|
|
|
player.dispose();
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
// reset the Player to the original value;
|
|
|
|
videojs.registerComponent('Player', Player);
|
2016-11-23 20:52:54 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('should not allow to register custom player when any player has been created', function(assert) {
|
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
const player = videojs(tag);
|
|
|
|
|
|
|
|
class CustomPlayer extends Player {}
|
2016-12-02 21:17:36 +02:00
|
|
|
|
|
|
|
assert.throws(function() {
|
2016-11-23 20:52:54 +02:00
|
|
|
videojs.registerComponent('Player', CustomPlayer);
|
2016-12-02 21:17:36 +02:00
|
|
|
}, 'Can not register Player component after player has been created');
|
|
|
|
|
|
|
|
player.dispose();
|
2016-11-23 20:52:54 +02:00
|
|
|
|
2016-12-02 21:17:36 +02:00
|
|
|
// reset the Player to the original value;
|
|
|
|
videojs.registerComponent('Player', Player);
|
2016-11-23 20:52:54 +02:00
|
|
|
});
|