Back to Repositories

Validating Video Track Implementation in video.js

This test suite validates the Video.js video tracks functionality, focusing on HTML5 tech implementation and native video track support. It ensures proper track event handling and tech switching behavior in the Video.js player.

Test Coverage Overview

The test suite provides comprehensive coverage of video track functionality in Video.js.

Key areas tested include:
  • Tech delegation for video track methods
  • Native video track event handling (add/remove)
  • HTML5 tech support detection
  • Track persistence during tech switching
Integration points focus on HTML5 tech implementation and player-tech interactions.

Implementation Analysis

The testing approach uses QUnit framework with sinon for time manipulation and mocking. Tests employ isolation patterns by replacing HTML5.TEST_VID and prototype methods for controlled testing environments.

Framework-specific features utilized include:
  • QUnit module hooks for setup/teardown
  • Sinon fake timers
  • TestHelpers utility for player instantiation

Technical Details

Testing tools and configuration:
  • QUnit as the primary testing framework
  • Sinon.js for mocking and time manipulation
  • Custom TestHelpers module for player setup
  • ES modules for importing dependencies
  • ESLint configuration for maintaining code quality

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through isolation of components and thorough edge case coverage.

Notable practices include:
  • Proper test cleanup and resource disposal
  • Isolation of native browser APIs
  • Consistent state management between tests
  • Clear test case organization and naming

videojs/videoJs

test/unit/tracks/video-tracks.test.js

            
/* eslint-env qunit */
import Html5 from '../../../src/js/tech/html5.js';
import TestHelpers from '../test-helpers.js';
import sinon from 'sinon';

QUnit.module('Video Tracks', {
  beforeEach(assert) {
    this.clock = sinon.useFakeTimers();
  },
  afterEach(assert) {
    this.clock.restore();
  }
});

QUnit.test('Player track methods call the tech', function(assert) {
  let calls = 0;
  const player = TestHelpers.makePlayer();

  player.tech_.videoTracks = function() {
    calls++;
  };

  player.videoTracks();

  assert.equal(calls, 1, 'videoTrack defers to the tech');
  player.dispose();
});

QUnit.test('listen to remove and add track events in native video tracks', function(assert) {
  const oldTestVid = Html5.TEST_VID;
  const oldVideoTracks = Html5.prototype.videoTracks;
  const events = {};

  Html5.prototype.videoTracks = function() {
    return {
      removeEventListener() {},
      addEventListener(type, handler) {
        events[type] = true;
      }
    };
  };

  Html5.TEST_VID = {
    videoTracks: []
  };

  const player = {
    // Function.prototype is a built-in no-op function.
    controls() {},
    ready() {},
    options() {
      return {};
    },
    addChild() {},
    id() {},
    el() {
      return {
        insertBefore() {},
        appendChild() {}
      };
    }
  };

  player.player_ = player;
  player.options_ = {};

  const html = new Html5({});

  assert.ok(events.removetrack, 'removetrack listener was added');
  assert.ok(events.addtrack, 'addtrack listener was added');

  Html5.TEST_VID = oldTestVid;
  Html5.prototype.videoTracks = oldVideoTracks;

  html.dispose();
});

QUnit.test('html5 tech supports native video tracks if the video supports it', function(assert) {
  const oldTestVid = Html5.TEST_VID;

  Html5.TEST_VID = {
    videoTracks: []
  };

  assert.ok(Html5.supportsNativeVideoTracks(), 'native video tracks are supported');

  Html5.TEST_VID = oldTestVid;
});

QUnit.test('html5 tech does not support native video tracks if the video does not supports it', function(assert) {
  const oldTestVid = Html5.TEST_VID;

  Html5.TEST_VID = {};

  assert.ok(!Html5.supportsNativeVideoTracks(), 'native video tracks are not supported');

  Html5.TEST_VID = oldTestVid;
});

QUnit.test('when switching techs, we should not get a new video track', function(assert) {
  const player = TestHelpers.makePlayer();

  player.loadTech_('TechFaker');
  const firstTracks = player.videoTracks();

  player.loadTech_('TechFaker');
  const secondTracks = player.videoTracks();

  assert.ok(firstTracks === secondTracks, 'the tracks are equal');

  player.dispose();
});