tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_texttrackcue.html (10940B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Test for Bug 833386 - HTMLTrackElement</title>
      5  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      6  <script type="text/javascript" src="manifest.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
      8 </head>
      9 <body>
     10 <video id="v" src="seek.webm" preload="metadata">
     11  <track src="basic.vtt" kind="subtitles" id="default" default>
     12 </video>
     13 <script type="text/javascript">
     14 /**
     15 * This test is used to test the VTTCue's different behaviors and check whether
     16 * cues would be activatived correctly during video playback.
     17 */
     18 var video = document.getElementById("v");
     19 var trackElement = document.getElementById("default");
     20 
     21 async function runTest() {
     22  await waitUntiTrackLoaded();
     23  checkCueDefinition();
     24  checkFirstCueParsedContent();
     25  checkCueStartTimeAndEndtime();
     26  checkCueSizeAndPosition();
     27  checkCueSnapToLines();
     28  checkCueAlignmentAndWritingDirection();
     29  checkCueLine();
     30  checkCreatingNewCue();
     31  checkRemoveNonExistCue();
     32  checkActiveCues();
     33  checkCueRegion();
     34  await checkCActiveCuesDuringVideoPlaying();
     35  SimpleTest.finish();
     36 }
     37 
     38 SimpleTest.waitForExplicitFinish();
     39 
     40 runTest();
     41 
     42 /**
     43 * The following are test helper functions.
     44 */
     45 async function waitUntiTrackLoaded() {
     46  if (trackElement.readyState != 2) {
     47    info(`wait until the track finishes loading`);
     48    await once(trackElement, "load");
     49  }
     50  is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
     51  is(trackElement.track.cues.length, 6, "Cue list length should be 6.");
     52 }
     53 
     54 function checkCueDefinition() {
     55  // Check that the typedef of TextTrackCue works in Gecko.
     56  isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined.");
     57  isnot(window.VTTCue, undefined, "VTTCue should be defined.");
     58 }
     59 
     60 function checkFirstCueParsedContent() {
     61  // Check if first cue was parsed correctly.
     62  const cue = trackElement.track.cues[0];
     63  ok(cue instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue.");
     64  ok(cue instanceof VTTCue, "Cue should be an instanceof VTTCue.");
     65  is(cue.id, "1", "Cue's ID should be 1.");
     66  is(cue.startTime, 0.5, "Cue's start time should be 0.5.");
     67  is(cue.endTime, 0.7, "Cue's end time should be 0.7.");
     68  is(cue.pauseOnExit, false, "Cue's pause on exit flag should be false.");
     69  is(cue.text, "This", "Cue's text should be set correctly.");
     70  is(cue.track, trackElement.track, "Cue's track should be defined.");
     71  cue.track = null;
     72  isnot(cue.track, null, "Cue's track should not be able to be set.");
     73 }
     74 
     75 function checkCueStartTimeAndEndtime() {
     76  const cueList = trackElement.track.cues;
     77  // Check that all cue times were not rounded
     78  is(cueList[1].startTime, 1.2, "Second cue's start time should be 1.2.");
     79  is(cueList[1].endTime, 2.4, "Second cue's end time should be 2.4.");
     80  is(cueList[2].startTime, 2, "Third cue's start time should be 2.");
     81  is(cueList[2].endTime, 3.5, "Third cue's end time should be 3.5.");
     82  is(cueList[3].startTime, 2.71, "Fourth cue's start time should be 2.71.");
     83  is(cueList[3].endTime, 2.91, "Fourth cue's end time should be 2.91.");
     84  is(cueList[4].startTime, 3.217, "Fifth cue's start time should be 3.217.");
     85  is(cueList[4].endTime, 3.989, "Fifth cue's end time should be 3.989.");
     86  is(cueList[5].startTime, 3.217, "Sixth cue's start time should be 3.217.");
     87  is(cueList[5].endTime, 3.989, "Sixth cue's end time should be 3.989.");
     88 
     89  // Check that Cue setters are working correctly.
     90  const cue = trackElement.track.cues[0];
     91  cue.id = "Cue 01";
     92  is(cue.id, "Cue 01", "Cue's ID should be 'Cue 01'.");
     93  cue.startTime = 0.51;
     94  is(cue.startTime, 0.51, "Cue's start time should be 0.51.");
     95  cue.endTime = 0.71;
     96  is(cue.endTime, 0.71, "Cue's end time should be 0.71.");
     97  cue.pauseOnExit = true;
     98  is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true.");
     99  video.addEventListener("pause", function() {
    100    video.play();
    101  }, {once: true});
    102 }
    103 
    104 function checkCueSizeAndPosition() {
    105  function checkPercentageValue(prop, initialVal) {
    106    ok(prop in cue, prop + " should be a property on VTTCue.");
    107    cue[prop] = initialVal;
    108    is(cue[prop], initialVal, `Cue's ${prop} should initially be ${initialVal}`);
    109    [ 101, -1 ].forEach(function(val) {
    110      let exceptionHappened = false;
    111      try {
    112        cue[prop] = val;
    113      } catch(e) {
    114        exceptionHappened = true;
    115        is(e.name, "IndexSizeError", "Should have thrown IndexSizeError.");
    116      }
    117      ok(exceptionHappened, "Exception should have happened.");
    118    });
    119  }
    120 
    121  const cue = trackElement.track.cues[0];
    122  checkPercentageValue("size", 100.0);
    123  cue.size = 50.5;
    124  is(cue.size, 50.5, "Cue's size should be 50.5.")
    125 
    126  // Check cue.position
    127  checkPercentageValue("position", "auto");
    128  cue.position = 50.5;
    129  is(cue.position, 50.5, "Cue's position value should now be 50.5.");
    130 }
    131 
    132 function checkCueSnapToLines() {
    133  const cue = trackElement.track.cues[0];
    134  ok(cue.snapToLines, "Cue's snapToLines should be set by set.");
    135  cue.snapToLines = false;
    136  ok(!cue.snapToLines, "Cue's snapToLines should not be set.");
    137 }
    138 
    139 function checkCueAlignmentAndWritingDirection() {
    140  function checkEnumValue(prop, initialVal, acceptedValues) {
    141    ok(prop in cue, `${prop} should be a property on VTTCue.`);
    142    is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`);
    143    cue[prop] = "bogus";
    144    is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`);
    145    acceptedValues.forEach(function(val) {
    146      cue[prop] = val;
    147      is(cue[prop], val, `Cue's ${prop} should be ${val}`);
    148      if (typeof val === "string") {
    149        cue[prop] = val.toUpperCase();
    150        is(cue[prop], val, `Cue's ${prop} should be ${val}`);
    151      }
    152    });
    153  }
    154 
    155  const cue = trackElement.track.cues[0];
    156  checkEnumValue("align", "center", [ "start", "left", "center", "right", "end" ]);
    157  checkEnumValue("lineAlign", "start", [ "start", "center", "end" ]);
    158  checkEnumValue("vertical", "", [ "", "lr", "rl" ]);
    159 
    160  cue.lineAlign = "center";
    161  is(cue.lineAlign, "center", "Cue's line align should be center.");
    162  cue.lineAlign = "START";
    163  is(cue.lineAlign, "center", "Cue's line align should be center.");
    164  cue.lineAlign = "end";
    165  is(cue.lineAlign, "end", "Cue's line align should be end.");
    166 
    167  // Check that cue position align works properly
    168  is(cue.positionAlign, "auto", "Cue's default position alignment should be auto.");
    169 
    170  cue.positionAlign = "line-left";
    171  is(cue.positionAlign, "line-left", "Cue's position align should be line-left.");
    172  cue.positionAlign = "auto";
    173  is(cue.positionAlign, "auto", "Cue's position align should be auto.");
    174  cue.positionAlign = "line-right";
    175  is(cue.positionAlign, "line-right", "Cue's position align should be line-right.");
    176 }
    177 
    178 function checkCueLine() {
    179  const cue = trackElement.track.cues[0];
    180  // Check cue.line
    181  is(cue.line, "auto", "Cue's line value should initially be auto.");
    182  cue.line = 0.5;
    183  is(cue.line, 0.5, "Cue's line value should now be 0.5.");
    184  cue.line = "auto";
    185  is(cue.line, "auto", "Cue's line value should now be auto.");
    186 }
    187 
    188 function checkCreatingNewCue() {
    189  const cueList = trackElement.track.cues;
    190 
    191  // Check that we can create and add new VTTCues
    192  let vttCue = new VTTCue(3.999, 4, "foo");
    193  is(vttCue.track, null, "Cue's track should be null.");
    194  trackElement.track.addCue(vttCue);
    195  is(vttCue.track, trackElement.track, "Cue's track should be defined.");
    196  is(cueList.length, 7, "Cue list length should now be 7.");
    197 
    198  // Check that new VTTCue was added correctly
    199  let cue = cueList[6];
    200  is(cue.startTime, 3.999, "Cue's start time should be 3.999.");
    201  is(cue.endTime, 4, "Cue's end time should be 4.");
    202  is(cue.text, "foo", "Cue's text should be foo.");
    203 
    204  // Adding the same cue again should not increase the cue count.
    205  trackElement.track.addCue(vttCue);
    206  is(cueList.length, 7, "Cue list length should be 7.");
    207 
    208  // Check that we are able to remove cues.
    209  trackElement.track.removeCue(cue);
    210  is(cueList.length, 6, "Cue list length should be 6.");
    211 }
    212 
    213 function checkRemoveNonExistCue() {
    214  is(trackElement.track.cues.length, 6, "Cue list length should be 6.");
    215  let exceptionHappened = false;
    216  try {
    217    // We should not be able to remove a cue that is not in the list.
    218    trackElement.track.removeCue(new VTTCue(1, 2, "foo"));
    219  } catch (e) {
    220    // "NotFoundError" should be thrown when trying to remove a cue that is
    221    // not in the list.
    222    is(e.name, "NotFoundError", "Should have thrown NotFoundError.");
    223    exceptionHappened = true;
    224  }
    225  // If this is false then we did not throw an error and probably removed a cue
    226  // when we shouln't have.
    227  ok(exceptionHappened, "Exception should have happened.");
    228  is(trackElement.track.cues.length, 6, "Cue list length should still be 6.");
    229 }
    230 
    231 function checkActiveCues() {
    232  video.currentTime = 2;
    233  isnot(trackElement.track.activeCues, null);
    234 
    235  trackElement.track.mode = "disabled";
    236  is(trackElement.track.activeCues, null, "No active cue when track is disabled.");
    237  trackElement.track.mode = "showing";
    238 }
    239 
    240 function checkCueRegion() {
    241  let regionInfo = [
    242    { lines: 2, width: 30 },
    243    { lines: 4, width: 20 },
    244    { lines: 2, width: 30 }
    245  ];
    246 
    247  for (let i = 0; i < regionInfo.length; i++) {
    248    let cue = trackElement.track.cues[i];
    249    isnot(cue.region, null, `Cue at ${i} should have a region.`);
    250    for (let key in regionInfo[i]) {
    251      is(cue.region[key], regionInfo[i][key],
    252         `Region should have a ${key} property with a value of ${regionInfo[i][key]}`);
    253    }
    254  }
    255 }
    256 
    257 async function checkCActiveCuesDuringVideoPlaying() {
    258  // Test TextTrack::ActiveCues.
    259  let cueInfo = [
    260    { startTime: 0.51, endTime: 0.71, ids: ["Cue 01"] },
    261    { startTime: 0.72, endTime: 1.19, ids: [] },
    262    { startTime: 1.2, endTime: 1.9, ids: [2] },
    263    { startTime: 2, endTime: 2.4, ids: [2, 2.5] },
    264    { startTime: 2.41, endTime: 2.70, ids: [2.5] },
    265    { startTime: 2.71, endTime: 2.91, ids: [2.5, 3] },
    266    { startTime: 2.92, endTime: 3.216, ids: [2.5] },
    267    { startTime: 3.217, endTime: 3.5, ids: [2.5, 4, 5] },
    268    { startTime: 3.51, endTime: 3.989, ids: [4, 5] },
    269    { startTime: 3.99, endTime: 4, ids: [] }
    270  ];
    271 
    272  video.addEventListener("timeupdate", function() {
    273    let activeCues = trackElement.track.activeCues,
    274        playbackTime = video.currentTime;
    275 
    276    for (let i = 0; i < cueInfo.length; i++) {
    277      let cue = cueInfo[i];
    278      if (playbackTime >= cue.startTime && playbackTime < cue.endTime) {
    279        is(activeCues.length, cue.ids.length, `There should be ${cue.ids.length} currently active cue(s).`);
    280        for (let j = 0; j < cue.ids.length; j++) {
    281          isnot(activeCues.getCueById(cue.ids[j]), undefined,
    282                `The cue with ID ${cue.ids[j]} should be active.`);
    283        }
    284        break;
    285      }
    286    }
    287  });
    288 
    289  info(`start video from 0s.`);
    290  video.currentTime = 0;
    291  video.play();
    292  await once(video, "playing");
    293  info(`video starts playing.`);
    294  await once(video, "ended");
    295 }
    296 
    297 </script>
    298 </body>
    299 </html>