mirror of
https://github.com/videojs/video.js.git
synced 2025-02-02 11:34:50 +02:00
test: check dom-data to verify we aren't leaking memory and event handlers (#5862)
This commit is contained in:
parent
d07f97dc94
commit
6e173b017f
@ -14,7 +14,7 @@ import * as Guid from './guid.js';
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
const elData = {};
|
||||
export const elData = {};
|
||||
|
||||
/*
|
||||
* Unique attribute name to store an element's guid in
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* eslint-env qunit */
|
||||
import document from 'global/document';
|
||||
import * as DomData from '../../../src/js/utils/dom-data';
|
||||
import videojs from '../../../src/js/video.js';
|
||||
|
||||
QUnit.module('dom-data');
|
||||
|
||||
@ -21,3 +22,45 @@ QUnit.test('should get and remove data from an element', function(assert) {
|
||||
|
||||
assert.notOk(DomData.hasData(el), 'cached item emptied');
|
||||
});
|
||||
|
||||
let memoryTestRun = false;
|
||||
|
||||
QUnit.done(function(details) {
|
||||
// don't run the extra dom data test on failures, there will likely be
|
||||
// memory leaks
|
||||
if (details.failed || memoryTestRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: fix memory leaks on the following
|
||||
if (videojs.browser.IS_SAFARI || videojs.browser.IS_EDGE || videojs.browser.IE_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
memoryTestRun = true;
|
||||
|
||||
QUnit.module('dom-data memory');
|
||||
|
||||
/**
|
||||
* If this test fails you will want to add a debug statement
|
||||
* in DomData.getData with the `id`. For instance if DomData.elData
|
||||
* had 2 objects in it {5: {...}, 2003: {...} you would add:
|
||||
*
|
||||
* ```js
|
||||
* if (id === 5) {
|
||||
* debugger;
|
||||
* }
|
||||
* ```
|
||||
* to the tests to see what test. Then re-run the tests to see
|
||||
* what leaking and where.
|
||||
*
|
||||
* > Note that the id can be off by 1-2 in either direction
|
||||
* for larger guids, so you may have to account for that.
|
||||
*/
|
||||
QUnit.test('Memory is not leaking', function(assert) {
|
||||
if (Object.keys(DomData.elData).length > 0) {
|
||||
videojs.domData = DomData;
|
||||
}
|
||||
assert.equal(Object.keys(DomData.elData).length, 0, 'no leaks, check videojs.domData.elData if failure');
|
||||
});
|
||||
});
|
||||
|
@ -7,6 +7,9 @@ import log from '../../src/js/utils/log.js';
|
||||
QUnit.module('video.js:hooks ', {
|
||||
beforeEach() {
|
||||
videojs.hooks_ = {};
|
||||
},
|
||||
afterEach() {
|
||||
videojs.hooks_ = {};
|
||||
}
|
||||
});
|
||||
|
||||
|
128
test/unit/videojs-integration.test.js
Normal file
128
test/unit/videojs-integration.test.js
Normal file
@ -0,0 +1,128 @@
|
||||
/* eslint-env qunit */
|
||||
import videojs from '../../src/js/video.js';
|
||||
import window from 'global/window';
|
||||
import document from 'global/document';
|
||||
import * as DomData from '../../src/js/utils/dom-data';
|
||||
import * as Fn from '../../src/js/utils/fn';
|
||||
|
||||
/**
|
||||
* This test is very important for dom-data memory checking
|
||||
* as it runs through a basic player lifecycle for real.
|
||||
*/
|
||||
QUnit.test('create a real player and dispose', function(assert) {
|
||||
assert.timeout(30000);
|
||||
const done = assert.async();
|
||||
const fixture = document.getElementById('qunit-fixture');
|
||||
const old = {};
|
||||
|
||||
// TODO: remove this code when we have a videojs debug build
|
||||
// see https://github.com/videojs/video.js/issues/5858
|
||||
old.bind = Fn.bind;
|
||||
|
||||
Fn.bind = function(context, fn, uid) {
|
||||
const retval = old.bind(context, fn, uid);
|
||||
|
||||
retval.og_ = fn.og_ || fn;
|
||||
retval.cx_ = fn.cx_ || context;
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
old.throttle = Fn.throttle;
|
||||
Fn.throttle = function(fn, wait) {
|
||||
const retval = old.throttle(fn, wait);
|
||||
|
||||
retval.og_ = fn.og_ || fn;
|
||||
retval.cx_ = fn.cx_;
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
old.debounce = Fn.debounce;
|
||||
|
||||
Fn.debounce = function(func, wait, immediate, context = window) {
|
||||
const retval = old.debounce(func, wait, immediate, context);
|
||||
|
||||
retval.og_ = func.og_ || func;
|
||||
retval.cx_ = func.cx_;
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
// TODO: use a local source rather than a remote one
|
||||
fixture.innerHTML = `
|
||||
<video-js
|
||||
id="vid1"
|
||||
controls
|
||||
preload="auto"
|
||||
width="640"
|
||||
height="264"
|
||||
poster="http://vjs.zencdn.net/v/oceans.png">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.ogv" type="video/ogg">
|
||||
<track kind="captions" src="../docs/examples/shared/example-captions.vtt" srclang="en" label="English">
|
||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||
</video-js>
|
||||
`.trim();
|
||||
|
||||
const player = videojs('vid1', {techOrder: ['html5']});
|
||||
|
||||
player.muted(true);
|
||||
|
||||
const checkDomData = function() {
|
||||
Object.keys(DomData.elData).forEach(function(elId) {
|
||||
const data = DomData.elData[elId] || {};
|
||||
|
||||
Object.keys(data.handlers || {}).forEach(function(eventName) {
|
||||
const listeners = data.handlers[eventName];
|
||||
const uniqueList = [];
|
||||
|
||||
(listeners || []).forEach(function(listener) {
|
||||
let add = true;
|
||||
|
||||
for (let i = 0; i < uniqueList.length; i++) {
|
||||
const obj = uniqueList[i];
|
||||
|
||||
if (listener.og_ && listener.cx_ && obj.fn === listener.og_ && obj.cx === listener.cx_) {
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (listener.og_ && !listener.cx_ && obj.fn === listener.og_) {
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!listener.og_ && !listener.cx_ && obj.fn === listener) {
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const obj = {fn: listener.og_ || listener, cx: listener.cx_};
|
||||
|
||||
if (add) {
|
||||
uniqueList.push(obj);
|
||||
assert.ok(true, `${elId}/${eventName}/${obj.fn.name} is unique`);
|
||||
} else {
|
||||
assert.ok(false, `${elId}/${eventName}/${obj.fn.name} is not unique`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
player.addTextTrack('captions', 'foo', 'en');
|
||||
player.ready(function() {
|
||||
assert.ok(player.tech_, 'tech exists');
|
||||
assert.equal(player.textTracks().length, 1, 'should have one text track');
|
||||
|
||||
checkDomData();
|
||||
player.dispose();
|
||||
|
||||
Object.keys(old).forEach(function(k) {
|
||||
Fn[k] = old[k];
|
||||
});
|
||||
done();
|
||||
}, true);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user