Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
            - /fetch/fetchpriority/fetchpriority-urgency-destination.https.h2.html - WPT Dashboard Interop Dashboard
 
<!DOCTYPE html>
<title>Fetch destination tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script src="support/priority-dependent-content.js"></script>
<script>
  let frame;
  // Set up the service worker and the frame.
  promise_test(t => {
      const kScope = 'support/resources/empty.https.h2.html';
      const kScript = 'support/fetch-destination-worker.js';
      return service_worker_unregister_and_register(t, kScript, kScope)
          .then(registration => {
              add_completion_callback(() => {
                  registration.unregister();
              });
              return wait_for_state(t, registration.installing, 'activated');
          })
          .then(() => {
              return with_iframe(kScope);
          })
          .then(f => {
              frame = f;
              add_completion_callback(() => { f.remove(); });
          });
  }, 'Initialize global state');
  // Actual tests
  function fetchPriorityParam(fetchpriority) {
      return fetchpriority ? `fetchpriority=${fetchpriority}` : "";
  }
  // TODO: should also test what's happening when a fetchpriority
  // attribute is set on the img, script or link nodes below.
  // TODO: Add tests for more destination. See /fetch/api/request/destination
  // HTMLImageElement - image destination
  promise_test(async t => {
      async function getUrgencyForImage(fetchpriority) {
          let rect = await new Promise((resolve, reject) => {
              let node = frame.contentWindow.document.createElement("img");
              frame.contentWindow.document.body.appendChild(node);
              node.onload = () => {
                  resolve(node.getBoundingClientRect());
              };
              node.onerror = reject;
              node.src = `priority-dependent-content.py?as-type=image&resource-id=image_${fetchpriority}&destination=image&${fetchPriorityParam(fetchpriority)}`;
          }).catch((e) => {
              assert_unreached("Fetch errored.");
          });
          return convertRectToUrgency(rect);
      }
      // See network.fetchpriority.adjustments.images and
      // nsHttpHandler::UrgencyFromCoSFlags.
      let normalUrgency = 4;
      assert_equals(await getUrgencyForImage("low"), normalUrgency + 2);
      assert_equals(await getUrgencyForImage("high"), normalUrgency - 1);
      assert_equals(await getUrgencyForImage("auto"), normalUrgency + 1);
      assert_equals(await getUrgencyForImage(), normalUrgency + 1);
  }, 'Adjustment of urgency parameter when fetching with an "image" Request.destination');
  // HTMLScriptElement - script destination
  promise_test(async t => {
      async function getUrgencyForScript(fetchpriority) {
          return await new Promise((resolve, reject) => {
              const resource_id = `script_${fetchpriority}`;
              let node = frame.contentWindow.document.createElement("script");
              node.onload = () => {
                  resolve(frame.contentWindow.scriptUrgency[resource_id]);
              };
              node.onerror = reject;
              node.src = `priority-dependent-content.py?as-type=script&resource-id=${resource_id}&destination=script&${fetchPriorityParam(fetchpriority)}`;
              frame.contentWindow.document.body.appendChild(node);
          }).catch((e) => {
              assert_unreached("Fetch errored.");
          });
      }
      // See network.fetchpriority.adjustments.link-preload-script and
      // nsHttpHandler::UrgencyFromCoSFlags.
      let normalUrgency = 4;
      assert_equals(await getUrgencyForScript("low"), normalUrgency + 2);
      assert_equals(await getUrgencyForScript("high"), normalUrgency);
      assert_equals(await getUrgencyForScript("auto"), normalUrgency);
      assert_equals(await getUrgencyForScript(), normalUrgency);
  }, 'Adjustment of urgency parameter when fetching with a "script" Request.destination');
  // HTMLLinkElement with rel=stylesheet - style destination
  promise_test(async t => {
      async function getUrgencyForStyle(fetchpriority) {
          let rect = await new Promise((resolve, reject) => {
              const resource_id = `style_${fetchpriority}`;
              let node = frame.contentWindow.document.createElement("link");
              let div = frame.contentWindow.document.createElement("div");
              div.id = `urgency_square_${resource_id}`;
              node.rel = "stylesheet";
              node.onload = () => {
                  resolve(div.getBoundingClientRect());
              };
              node.onerror = reject;
              node.href = `priority-dependent-content.py?as-type=style&resource-id=${resource_id}&destination=style&${fetchPriorityParam(fetchpriority)}`;
              frame.contentWindow.document.body.appendChild(node);
              frame.contentWindow.document.body.appendChild(div);
          }).catch(() => {
              assert_unreached("Fetch errored.");
          });
          return convertRectToUrgency(rect);
      }
      // See network.fetchpriority.adjustments.link-preload-style and
      // nsHttpHandler::UrgencyFromCoSFlags.
      let normalUrgency = 4;
      assert_equals(await getUrgencyForStyle("low"), normalUrgency + 1);
      assert_equals(await getUrgencyForStyle("high"), normalUrgency);
      assert_equals(await getUrgencyForStyle("auto"), normalUrgency);
      assert_equals(await getUrgencyForStyle(), normalUrgency);
  }, 'Adjustment of urgency parameter when fetching with a "style" Request.destination');
  // HTMLAudioElement/HTMLVideoElement - audio/video destination
  ["audio", "video"].forEach(media => {
    promise_test(async t => {
        async function getUrgencyForMedia(fetchpriority) {
            let duration = await new Promise((resolve, reject) => {
                let node = frame.contentWindow.document.createElement(media);
                node.onloadeddata = () => { resolve(node.duration); };
                node.onerror = reject;
                node.src = `priority-dependent-content.py?as-type=${media}&resource-id=${media}_${fetchpriority}&destination=${media}&${fetchPriorityParam(fetchpriority)}`;
                frame.contentWindow.document.body.appendChild(node);
            }).catch((e) => {
                assert_unreached("Fetch errored.");
            });
            return convertDurationToUrgency(duration);
        }
        // See network.fetchpriority.adjustments.media and
        // nsHttpHandler::UrgencyFromCoSFlags.
        let normalUrgency = 4;
        assert_equals(await getUrgencyForMedia("low"), normalUrgency + 1);
        assert_equals(await getUrgencyForMedia("high"), normalUrgency);
        assert_equals(await getUrgencyForMedia("auto"), normalUrgency);
        assert_equals(await getUrgencyForMedia(), normalUrgency);
    }, `Adjustment of urgency parameter when fetching with a "${media}" Request.destination`);
  });
  // HTMLLinkElement with rel=preload and as=font - font destination
  promise_test(async t => {
      async function getUrgencyForFont(fetchpriority) {
          let fontFamily = `custom_font_priority_${fetchpriority ? fetchpriority : "default"}`;
          let span = frame.contentWindow.document.createElement("span");
          span.style = `font-family: ${fontFamily}; font-size: 10px`
          span.textContent = 'M';
          frame.contentWindow.document.body.appendChild(span);
          let link = frame.contentWindow.document.createElement("link");
          link.rel = "preload";
          link.as = "font";
          link.crossOrigin = "";
          let size = await new Promise((resolve, reject) => {
              link.onload = async () => {
                  let response = await fetch(link.href, {cache: "force-cache"});
                  let font_face = new FontFace(fontFamily,
                                               await response.arrayBuffer());
                  frame.contentWindow.document.fonts.add(font_face);
                  resolve(span.getBoundingClientRect().width);
              };
              link.onerror = reject;
              link.href = `priority-dependent-content.py?as-type=font&resource-id=font_${fetchpriority}_${token()}&destination=font&${fetchPriorityParam(fetchpriority)}&use-cache=true`;
              frame.contentWindow.document.body.appendChild(link);
          }).catch(() => {
              assert_unreached("Fetch errored.");
          });
          return convertSizeToUrgency(size);
      }
      // See network.fetchpriority.adjustments.link_preload_font and
      // nsHttpHandler::UrgencyFromCoSFlags.
      let normalUrgency = 3;
      assert_equals(await getUrgencyForFont("low"), normalUrgency + 2);
      assert_equals(await getUrgencyForFont("high"), normalUrgency - 1);
      assert_equals(await getUrgencyForFont("auto"), normalUrgency);
      assert_equals(await getUrgencyForFont(), normalUrgency);
  }, 'Adjustment of urgency parameter when fetching with a "font" Request.destination');
</script>