module('Player'); // Compiler doesn't like using 'this' in setup/teardown. // module("Player", { // /** // * @this {*} // */ // setup: function(){ // window.player1 = true; // using window works // }, // /** // * @this {*} // */ // teardown: function(){ // // if (this.player && this.player.el() !== null) { // // this.player.dispose(); // // this.player = null; // // } // } // }); // Object.size = function(obj) { // var size = 0, key; // for (key in obj) { // console.log('key', key) // if (obj.hasOwnProperty(key)) size++; // } // return size; // }; test('should create player instance that inherits from component and dispose it', function(){ var player = PlayerTest.makePlayer(); ok(player.el().nodeName === 'DIV'); ok(player.on, 'component function exists'); player.dispose(); ok(player.el() === null, 'element disposed'); }); test('should accept options from multiple sources and override in correct order', function(){ // For closure compiler to work, all reference to the prop have to be the same type // As in options['attr'] or options.attr. Compiler will minimize each separately. // Since we're using setAttribute which requires a string, we have to use the string // version of the key for all version. // Set a global option vjs.options['attr'] = 1; var tag0 = PlayerTest.makeTag(); var player0 = new vjs.Player(tag0); ok(player0.options_['attr'] === 1, 'global option was set'); player0.dispose(); // Set a tag level option var tag1 = PlayerTest.makeTag(); tag1.setAttribute('attr', 'asdf'); // Attributes must be set as strings var player1 = new vjs.Player(tag1); ok(player1.options_['attr'] === 'asdf', 'Tag options overrode global options'); player1.dispose(); // Set a tag level option var tag2 = PlayerTest.makeTag(); tag2.setAttribute('attr', 'asdf'); var player2 = new vjs.Player(tag2, { 'attr': 'fdsa' }); ok(player2.options_['attr'] === 'fdsa', 'Init options overrode tag and global options'); player2.dispose(); }); test('should get tag, source, and track settings', function(){ // Partially tested in lib->getAttributeValues var fixture = document.getElementById('qunit-fixture'); var html = ''; fixture.innerHTML += html; var tag = document.getElementById('example_1'); var player = new vjs.Player(tag); ok(player.options_['autoplay'] === true); ok(player.options_['preload'] === 'metadata'); // No extern. Use string. ok(player.options_['id'] === 'example_1'); ok(player.options_['sources'].length === 2); ok(player.options_['sources'][0].src === 'http://google.com'); ok(player.options_['sources'][0].type === 'video/mp4'); ok(player.options_['sources'][1].type === 'video/webm'); ok(player.options_['tracks'].length === 1); ok(player.options_['tracks'][0]['kind'] === 'captions'); // No extern ok(player.options_['tracks'][0]['default'] === true); ok(player.el().className.indexOf('video-js') !== -1, 'transferred class from tag to player div'); ok(player.el().id === 'example_1', 'transferred id from tag to player div'); ok(vjs.players[player.id()] === player, 'player referenceable from global list'); ok(tag.id !== player.id, 'tag ID no longer is the same as player ID'); ok(tag.className !== player.el().className, 'tag classname updated'); player.dispose(); ok(tag['player'] !== player, 'tag player ref killed'); ok(!vjs.players['example_1'], 'global player ref killed'); ok(player.el() === null, 'player el killed'); }); test('should set the width and height of the player', function(){ var player = PlayerTest.makePlayer({ width: 123, height: '100%' }); ok(player.width() === 123); ok(player.el().style.width === '123px'); var fixture = document.getElementById('qunit-fixture'); var container = document.createElement('div'); fixture.appendChild(container); // Player container needs to have height in order to have height // Don't want to mess with the fixture itself container.appendChild(player.el()); container.style.height = '1000px'; ok(player.height() === 1000); player.dispose(); }); test('should not force width and height', function() { var player = PlayerTest.makePlayer({ width: 'auto', height: 'auto' }); ok(player.el().style.width === '', 'Width is not forced'); ok(player.el().style.height === '', 'Height is not forced'); player.dispose(); }); test('should wrap the original tag in the player div', function(){ var tag = PlayerTest.makeTag(); var container = document.createElement('div'); var fixture = document.getElementById('qunit-fixture'); container.appendChild(tag); fixture.appendChild(container); var player = new vjs.Player(tag); var el = player.el(); ok(el.parentNode === container, 'player placed at same level as tag'); // Tag may be placed inside the player element or it may be removed from the DOM ok(tag.parentNode !== container, 'tag removed from original place'); player.dispose(); }); test('should set and update the poster value', function(){ var tag, poster, updatedPoster, player; poster = 'http://example.com/poster.jpg'; updatedPoster = 'http://example.com/updated-poster.jpg'; tag = PlayerTest.makeTag(); tag.setAttribute('poster', poster); player = PlayerTest.makePlayer({}, tag); equal(player.poster(), poster, 'the poster property should equal the tag attribute'); var pcEmitted = false; player.on('posterchange', function(){ pcEmitted = true; }); player.poster(updatedPoster); ok(pcEmitted, 'posterchange event was emitted'); equal(player.poster(), updatedPoster, 'the updated poster is returned'); player.dispose(); }); test('should load a media controller', function(){ var player = PlayerTest.makePlayer({ preload: 'none', sources: [ { src: 'http://google.com', type: 'video/mp4' }, { src: 'http://google.com', type: 'video/webm' } ] }); ok(player.el().children[0].className.indexOf('vjs-tech') !== -1, 'media controller loaded'); player.dispose(); }); test('should be able to initialize player twice on the same tag using string reference', function() { var videoTag = PlayerTest.makeTag(); var id = videoTag.id; var fixture = document.getElementById('qunit-fixture'); fixture.appendChild(videoTag); var player = vjs(videoTag.id); ok(player, 'player is created'); player.dispose(); ok(!document.getElementById(id), 'element is removed'); videoTag = PlayerTest.makeTag(); fixture.appendChild(videoTag); //here we receive cached version instead of real player = vjs(videoTag.id); //here it triggers error, because player was destroyed already after first dispose player.dispose(); }); test('should set controls and trigger events', function() { expect(6); var player = PlayerTest.makePlayer({ 'controls': false }); ok(player.controls() === false, 'controls set through options'); var hasDisabledClass = player.el().className.indexOf('vjs-controls-disabled'); ok(hasDisabledClass !== -1, 'Disabled class added to player'); player.controls(true); ok(player.controls() === true, 'controls updated'); var hasEnabledClass = player.el().className.indexOf('vjs-controls-enabled'); ok(hasEnabledClass !== -1, 'Disabled class added to player'); player.on('controlsenabled', function(){ ok(true, 'enabled fired once'); }); player.on('controlsdisabled', function(){ ok(true, 'disabled fired once'); }); player.controls(false); player.controls(true); // Check for unnecessary events player.controls(true); player.dispose(); }); // Can't figure out how to test fullscreen events with tests // Browsers aren't triggering the events at least // asyncTest('should trigger the fullscreenchange event', function() { // expect(3); // var player = PlayerTest.makePlayer(); // player.on('fullscreenchange', function(){ // ok(true, 'fullscreenchange event fired'); // ok(this.isFullScreen() === true, 'isFullScreen is true'); // ok(this.el().className.indexOf('vjs-fullscreen') !== -1, 'vjs-fullscreen class added'); // player.dispose(); // start(); // }); // player.requestFullScreen(); // }); test('should toggle user the user state between active and inactive', function(){ var player = PlayerTest.makePlayer({}); expect(9); ok(player.userActive(), 'User should be active at player init'); player.on('userinactive', function(){ ok(true, 'userinactive event triggered'); }); player.on('useractive', function(){ ok(true, 'useractive event triggered'); }); player.userActive(false); ok(player.userActive() === false, 'Player state changed to inactive'); ok(player.el().className.indexOf('vjs-user-active') === -1, 'Active class removed'); ok(player.el().className.indexOf('vjs-user-inactive') !== -1, 'Inactive class added'); player.userActive(true); ok(player.userActive() === true, 'Player state changed to active'); ok(player.el().className.indexOf('vjs-user-inactive') === -1, 'Inactive class removed'); ok(player.el().className.indexOf('vjs-user-active') !== -1, 'Active class added'); player.dispose(); }); test('should add a touch-enabled classname when touch is supported', function(){ var player; expect(1); // Fake touch support. Real touch support isn't needed for this test. var origTouch = vjs.TOUCH_ENABLED; vjs.TOUCH_ENABLED = true; player = PlayerTest.makePlayer({}); ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added'); vjs.TOUCH_ENABLED = origTouch; player.dispose(); }); test('should allow for tracking when native controls are used', function(){ var player = PlayerTest.makePlayer({}); expect(6); // Make sure native controls is false before starting test player.usingNativeControls(false); player.on('usingnativecontrols', function(){ ok(true, 'usingnativecontrols event triggered'); }); player.on('usingcustomcontrols', function(){ ok(true, 'usingcustomcontrols event triggered'); }); player.usingNativeControls(true); ok(player.usingNativeControls() === true, 'Using native controls is true'); ok(player.el().className.indexOf('vjs-using-native-controls') !== -1, 'Native controls class added'); player.usingNativeControls(false); ok(player.usingNativeControls() === false, 'Using native controls is false'); ok(player.el().className.indexOf('vjs-using-native-controls') === -1, 'Native controls class removed'); player.dispose(); }); test('should use custom message when encountering an unsupported video type', function() { videojs.options['notSupportedMessage'] = 'Video no go link'; var fixture = document.getElementById('qunit-fixture'); var html = ''; fixture.innerHTML += html; var tag = document.getElementById('example_1'); var player = new vjs.Player(tag); var incompatibilityMessage = player.el().getElementsByTagName('p')[0]; // ie8 capitalizes tag names equal(incompatibilityMessage.innerHTML.toLowerCase(), 'video no go link'); player.dispose(); }); test('should return the player when setting src', function() { var player, ret; player = PlayerTest.makePlayer({}), ret = player.src('foo'); equal(player, ret, 'the player is returned'); }); test('should register players with generated ids', function(){ var fixture, video, player, id; fixture = document.getElementById('qunit-fixture'); video = document.createElement('video'); video.className = 'vjs-default-skin video-js'; fixture.appendChild(video); player = new vjs.Player(video); id = player.el().id; equal(player.el().id, player.id(), 'the player and element ids are equal'); ok(vjs.players[id], 'the generated id is registered'); });