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>