Bug 1562021 - part5 : add test 'test_texttrack_mode_change_during_loading.html'. r=jya
authorAlastor Wu <alwu@mozilla.com>
Wed, 03 Jul 2019 23:28:31 +0000
changeset 481470 084252265e0c4bbf1b2211801b55278090f90d64
parent 481469 1ff85088fbf482a4a518e74150b7bc6036552374
child 481471 d8612428d805feed01c8bc8cff3981352889c1d2
push id89225
push useralwu@mozilla.com
push dateFri, 05 Jul 2019 18:06:03 +0000
treeherderautoland@084252265e0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1562021
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1562021 - part5 : add test 'test_texttrack_mode_change_during_loading.html'. r=jya In order to simulate the specific running order, we have to add a test event 'mozStartedLoadingTextTrack', which would be controlled under a pref. This test is used to ensure that we won't get `error` event when we change track's mode during loading. Differential Revision: https://phabricator.services.mozilla.com/D36410
dom/html/HTMLTrackElement.cpp
dom/html/HTMLTrackElement.h
dom/media/WebVTTListener.cpp
dom/media/test/mochitest.ini
dom/media/test/test_texttrack_mode_change_during_loading.html
modules/libpref/init/StaticPrefList.h
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -493,10 +493,17 @@ nsresult HTMLTrackElement::AfterSetAttr(
     if (ReadyState() == TextTrackReadyState::Loading && aValue != aOldValue) {
       SetReadyState(TextTrackReadyState::FailedToLoad);
     }
   }
   return nsGenericHTMLElement::AfterSetAttr(
       aNameSpaceID, aName, aValue, aOldValue, aMaybeScriptedPrincipal, aNotify);
 }
 
+void HTMLTrackElement::DispatchTestEvent(const nsAString& aName) {
+  if (!StaticPrefs::media_webvtt_testing_events()) {
+    return;
+  }
+  DispatchTrustedEvent(aName);
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/html/HTMLTrackElement.h
+++ b/dom/html/HTMLTrackElement.h
@@ -89,16 +89,17 @@ class HTMLTrackElement final : public ns
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
                                 const nsAttrValue* aValue,
                                 const nsAttrValue* aOldValue,
                                 nsIPrincipal* aMaybeScriptedPrincipal,
                                 bool aNotify) override;
 
   void DispatchTrackRunnable(const nsString& aEventName);
   void DispatchTrustedEvent(const nsAString& aName);
+  void DispatchTestEvent(const nsAString& aName);
 
   void CancelChannelAndListener();
 
   // Only load resource for the non-disabled track with media parent.
   void MaybeDispatchLoadResource();
 
  protected:
   virtual ~HTMLTrackElement();
--- a/dom/media/WebVTTListener.cpp
+++ b/dom/media/WebVTTListener.cpp
@@ -89,16 +89,17 @@ WebVTTListener::AsyncOnChannelRedirect(n
 
 NS_IMETHODIMP
 WebVTTListener::OnStartRequest(nsIRequest* aRequest) {
   if (IsCanceled()) {
     return NS_OK;
   }
 
   LOG("OnStartRequest");
+  mElement->DispatchTestEvent(NS_LITERAL_STRING("mozStartedLoadingTextTrack"));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebVTTListener::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
   if (IsCanceled()) {
     return NS_OK;
   }
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -1221,16 +1221,19 @@ tags = webvtt
 [test_texttrack_cors_preload_none.html]
 support-files =
   ../../canvas/test/crossorigin/video.sjs
 tags = webvtt
 [test_testtrack_cors_no_response.html]
 support-files =
   ../../canvas/test/crossorigin/video.sjs
 tags = webvtt
+[test_texttrack_mode_change_during_loading.html]
+skip-if = toolkit == 'android' # android(bug 1562021)
+tags = webvtt
 [test_texttrackcue.html]
 skip-if = android_version == '17' || android_version == '22' # android(bug 1368010, bug 1372457)
 tags = webvtt
 [test_texttrackcue_moz.html]
 skip-if = android_version == '22' # bug 1294111, android(bug 1368010)
 tags = webvtt
 [test_texttrackevents_video.html]
 skip-if = android_version == '17' || android_version == '22' # android(bug 1368010, bug 1372457)
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_texttrack_mode_change_during_loading.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>WebVTT : changing track's mode during loading</title>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="manifest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+/**
+ * This test is to ensure that we won't get `error` event when we change track's
+ * mode during loading. In this test, track element starts loading after setting
+ * the src and we would start another load later just after the channel which is
+ * used to fetch data starts. The second load is triggered by mode changes, and
+ * it should stop the prevous load and won't generate any error.
+ */
+async function startTest() {
+  const video = createVideo();
+  const trackElement = createAndAppendtrackElemententToVideo(video);
+
+  await changeTrackModeDuringLoading(trackElement);
+  await waitUntilTrackLoaded(trackElement);
+
+  removeNodeAndSource(video);
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [["media.webvtt.testing.events", true]]},
+                            startTest);
+
+/**
+ * The following are test helper functions.
+ */
+function createVideo() {
+  info(`create video`);
+  let video = document.createElement("video");
+  video.src = "gizmo.mp4";
+  document.body.appendChild(video);
+  return video;
+}
+
+function createAndAppendtrackElemententToVideo(video) {
+  let trackElement = document.createElement("track");
+  trackElement.default = true;
+  video.append(trackElement);
+  return trackElement;
+}
+
+async function changeTrackModeDuringLoading(trackElement) {
+  info(`set src to start loading`);
+  trackElement.src = "basic.vtt";
+
+  info(`wait until starting loading resource.`);
+  await once(trackElement, "mozStartedLoadingTextTrack");
+
+  info(`changeing track's mode during loading should not cause loading failed.`);
+  trackElement.onerror = () => {
+    ok(false, `Should not get error event!`);
+  }
+  trackElement.track.mode = "hidden";
+}
+
+async function waitUntilTrackLoaded(trackElement) {
+  if (trackElement.readyState != 2) {
+    info(`wait until the track finishes loading`);
+    await once(trackElement, "load");
+  }
+  is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
+  is(trackElement.track.cues.length, 6, "Cue list length should be 6.");
+}
+</script>
+</body>
+</html>
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -5968,16 +5968,24 @@ VARCACHE_PREF(
 // TextTrack WebVTT Region extension support.
 VARCACHE_PREF(
   Live,
   "media.webvtt.regions.enabled",
   media_webvtt_regions_enabled,
   bool, true
 )
 
+// This pref controls whether dispatch testing-only events.
+VARCACHE_PREF(
+  Live,
+  "media.webvtt.testing.events",
+  media_webvtt_testing_events,
+  bool, true
+)
+
 VARCACHE_PREF(
   Live,
   "media.webspeech.synth.force_global_queue",
    media_webspeech_synth_force_global_queue,
   bool, false
 )
 
 VARCACHE_PREF(