Back to Repositories

Testing Video Track Selection Management in Video.js

This test suite validates the functionality of VideoTrackList implementation in Video.js, focusing on track selection behavior and event handling. The tests ensure proper management of video tracks and their selection states within the player.

Test Coverage Overview

The test suite provides comprehensive coverage of VideoTrackList functionality, focusing on track selection mechanics and event propagation.

  • Tests track selection exclusivity
  • Validates change event triggering
  • Verifies track addition and removal behavior
  • Covers selection state management across multiple tracks

Implementation Analysis

The testing approach uses QUnit framework to systematically verify VideoTrackList behavior.

Tests utilize EventTarget and VideoTrack implementations to simulate real-world track management scenarios. The implementation follows a modular pattern with isolated test cases for specific functionality aspects.

Technical Details

Testing Infrastructure:

  • QUnit as the primary testing framework
  • ES6 module imports for VideoTrackList and VideoTrack classes
  • EventTarget for event handling simulation
  • ESLint configuration for code quality

Best Practices Demonstrated

The test suite exemplifies strong testing practices through isolated test cases and comprehensive assertions.

  • Clear test case organization and naming
  • Proper cleanup after each test
  • Thorough event handling verification
  • Edge case coverage for track selection states

videojs/videoJs

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

            
/* eslint-env qunit */
import VideoTrackList from '../../../src/js/tracks/video-track-list.js';
import VideoTrack from '../../../src/js/tracks/video-track.js';
import EventTarget from '../../../src/js/event-target.js';

QUnit.module('Video Track List');

QUnit.test('trigger "change" when "selectedchange" is fired on a track', function(assert) {
  const track = new EventTarget();

  track.loaded_ = true;
  const videoTrackList = new VideoTrackList([track]);
  let changes = 0;
  const changeHandler = function() {
    changes++;
  };

  videoTrackList.on('change', changeHandler);
  track.trigger('selectedchange');
  assert.equal(changes, 1, 'one change events for trigger');

  videoTrackList.off('change', changeHandler);
  videoTrackList.onchange = changeHandler;

  track.trigger('selectedchange');
  assert.equal(changes, 2, 'one change events for another trigger');

  videoTrackList.removeTrack(track);
  videoTrackList.off('change');
});

QUnit.test('only one track is ever selected', function(assert) {
  const track = new VideoTrack({selected: true});
  const track2 = new VideoTrack({selected: true});
  const track3 = new VideoTrack({selected: true});
  const track4 = new VideoTrack();
  const list = new VideoTrackList([track, track2]);

  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, true, 'track2 is selected');

  track.selected = true;
  assert.equal(track.selected, true, 'track is selected');
  assert.equal(track2.selected, false, 'track2 is unselected');

  list.addTrack(track3);
  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, false, 'track2 is unselected');
  assert.equal(track3.selected, true, 'track3 is selected');

  track2.selected = true;
  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, true, 'track2 is selected');
  assert.equal(track3.selected, false, 'track3 is unselected');

  list.addTrack(track4);
  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, true, 'track2 is selected');
  assert.equal(track3.selected, false, 'track3 is unselected');
  assert.equal(track4.selected, false, 'track4 is unselected');

  list.removeTrack(track);
  list.removeTrack(track2);
  list.removeTrack(track3);
  list.removeTrack(track4);
});

QUnit.test('all tracks can be unselected', function(assert) {
  const track = new VideoTrack();
  const track2 = new VideoTrack();
  const list = new VideoTrackList([track, track2]);

  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, false, 'track2 is unselected');

  track.selected = true;
  assert.equal(track.selected, true, 'track is selected');
  assert.equal(track2.selected, false, 'track2 is unselected');

  track.selected = false;
  assert.equal(track.selected, false, 'track is unselected');
  assert.equal(track2.selected, false, 'track2 is unselected');

  list.removeTrack(track);
  list.removeTrack(track2);
});

QUnit.test('trigger a change event per selected change', function(assert) {
  const track = new VideoTrack({selected: true});
  const track2 = new VideoTrack({selected: true});
  const track3 = new VideoTrack({selected: true});
  const track4 = new VideoTrack();
  const list = new VideoTrackList([track, track2]);
  let change = 0;

  list.on('change', () => change++);
  track.selected = true;
  assert.equal(change, 1, 'one change triggered');

  list.addTrack(track3);
  assert.equal(change, 2, 'another change triggered by adding an selected track');

  track.selected = true;
  assert.equal(change, 3, 'another change trigger by changing selected');

  track.selected = false;
  assert.equal(change, 4, 'another change trigger by changing selected');

  list.addTrack(track4);
  assert.equal(change, 4, 'no change triggered by adding a unselected track');

  list.removeTrack(track);
  list.removeTrack(track2);
  list.removeTrack(track3);
  list.removeTrack(track4);
  list.off('change');
});