function playingTest(name, data) {
        it(name, () => {
          video.buffered = createFakeBuffered(data.buffered);
          video.currentTime = data.start;
          video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;

          onEvent.and.callFake((event) => {});

          playhead = new shaka.media.MediaSourcePlayhead(
              video,
              manifest,
              config,
              /* startTime= */ data.start,
              Util.spyFunc(onSeek),
              Util.spyFunc(onEvent));

          playhead.ready();

          jasmine.clock().tick(500);
          for (let time = data.start; time < data.waitingAt; time++) {
            // We don't want to run tick() for 1 second because it will trigger
            // the stall-detection, which will move the playhead; on the other
            // hand, we don't want to be 0.5 seconds from the gap because on
            // Edge/Tizen, gap jumping will treat that as in the gap.
            // See shaka.media.TimeRangesUtils.getGapIndex.

            video.currentTime = time;
            jasmine.clock().tick(400);
            // Make sure Playhead didn't adjust the time yet.
            expect(video.currentTime).toBe(time);

            video.currentTime = time + 0.4;
            jasmine.clock().tick(600);
            // Make sure Playhead didn't adjust the time yet.
            expect(video.currentTime).toBe(time + 0.4);
          }

          expect(onEvent).not.toHaveBeenCalled();

          video.currentTime = data.waitingAt;
          video.readyState = HTMLMediaElement.HAVE_CURRENT_DATA;
          video.on['waiting']();
          jasmine.clock().tick(500);

          expect(onEvent).toHaveBeenCalledTimes(data.expectEvent ? 1 : 0);
          expect(video.currentTime).toBe(data.expectedEndTime);
        });
      }
@param {string} name
@param {PlayingTestInfo} data