Commit 9e706d90 authored by Yuta Kasai's avatar Yuta Kasai Committed by Commit Bot

Service Worker: Add tentative wpt test for FetchEvent WorkerTiming in frame

This patch adds tentative wpt test. Currently FetchEvent WorkerTiming is a
tentative feature. In chromium, this feature hasn't implemented completely yet,
so some tests will be failed.


Explainer : https://github.com/wanderview/fetchevent-worker-timing/blob/master/explainer.md

Bug: 900700
Change-Id: I7a43989d8833ddd65c93106de67c4ebe6bd9ed52
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1915644
Commit-Queue: Yuta Kasai <yutakasai@google.com>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720134}
parent 1cc443b4
This is a testharness.js-based test.
PASS Set up an active service worker
FAIL workerTiming for navigation in a frame with network fallback assert_equals: workerTiming is completed when PerformanceResourceTiming is observed expected 3 but got 0
FAIL workerTiming for navigation in a frame for a response from a fetch handler assert_equals: workerTiming is completed when PerformanceResourceTiming is observed expected 3 but got 0
FAIL workerTiming for subresources in a frame with network fallback assert_equals: workerTiming is completed when PerformanceResourceTiming is observed expected 3 but got 1
FAIL workerTiming for subresources in a frame for a response from a fetchhandler assert_equals: workerTiming is completed when PerformanceResourceTiming is observed expected 3 but got 1
PASS Unregister service worker
Harness: the test ran to completion.
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
// This is tentative because currently this feature only has an explainer and
// no formal spec.
// https://github.com/wanderview/fetchevent-worker-timing/blob/master/explainer.md
async function wait_for_performance_entries(url, performance, entry_type) {
const entries = await performance.getEntriesByName(url);
if (entries.length > 0) {
return entries;
}
return new Promise((resolve) => {
new PerformanceObserver((list, observer) => {
const entries = list.getEntriesByName(url);
if (entries.length > 0) {
observer.disconnect();
resolve(entries);
}
}).observe({ entryTypes: [entry_type] });
});
}
function load_image(target_document, url) {
return new Promise((resolve, reject) => {
const image = target_document.createElement('img');
image.onload = () => { resolve(image); }
image.onerror = () => { reject(`Failed to load: ${url}`); };
image.src = url;
});
}
promise_test(async (t) => {
const registration = await service_worker_unregister_and_register(
t, 'resources/fetch-event-worker-timing.js', 'resources/');
promise_test(async (t) => registration.unregister(),
'Unregister service worker');
await wait_for_state(t, registration.installing, 'activated');
}, 'Set up an active service worker');
promise_test(async (t) => {
const frame = await with_iframe('resources/empty.html?fallback');
t.add_cleanup(() => frame.remove());
const performance = frame.contentWindow.performance;
const entries = await wait_for_performance_entries(
frame.src, performance, 'navigation');
assert_equals(entries.length, 1, 'PerformanceNavigationTiming is observed');
const worker_timings = await entries[0].workerTiming;
const expected_worker_timings = [
{
name: "network-fallback mark 1",
entryType: "mark",
detail: { foo: 'foo' }
},
{
name: "network-fallback mark 2",
entryType: "mark",
detail: { bar: 'bar' }
},
{
name: "network-fallback measure",
entryType: "measure",
detail: { baz: 'baz' }
}
];
assert_equals(worker_timings.length, expected_worker_timings.length,
'workerTiming is completed when PerformanceResourceTiming is observed');
for (let i = 0; i < workerTimings.length; i++) {
assert_equals(worker_timings[i].name,
expected_worker_timings[i].name, 'entry name');
assert_equals(worker_timings[i].entryType,
expected_worker_timings[i].entryType, 'entry type');
assert_object_equals(worker_timings[i].detail,
expected_worker_timings[i].detail, 'entry detail');
}
}, 'workerTiming for navigation in a frame with network fallback');
promise_test(async (t) => {
const frame= await with_iframe('resources/empty.html?fetch-event');
t.add_cleanup(() => frame.remove());
const performance = frame.contentWindow.performance;
const entries = await wait_for_performance_entries(
frame.src, performance, 'navigation');
assert_equals(entries.length, 1, 'PerformanceNavigationTiming is observed');
const worker_timings = await entries[0].workerTiming;
const expected_worker_timings = [
{
name: "fetch-event mark 1",
entryType: "mark",
detail: { foo: 'foo' }
},
{
name: "fetch-event mark 2",
entryType: "mark",
detail: { bar: 'bar' }
},
{
name: "fetch-event measure",
entryType: "measure",
detail: { baz: 'baz' }
}
];
assert_equals(worker_timings.length, expected_worker_timings.length,
'workerTiming is completed when PerformanceResourceTiming is observed');
for (let i = 0; i < workerTimings.length; i++) {
assert_equals(worker_timings[i].name,
expected_worker_timings[i].name, 'entry name');
assert_equals(worker_timings[i].entryType,
expected_worker_timings[i].entryType, 'entry type');
assert_object_equals(worker_timings[i].detail,
expected_worker_timings[i].detail, 'entry detail');
}
}, 'workerTiming for navigation in a frame for a response from a fetch ' +
'handler');
promise_test(async (t) => {
const frame = await with_iframe('resources/empty.html');
t.add_cleanup(() => frame.remove());
const performance = frame.contentWindow.performance;
const image_path = base_path() + 'resources/square.png?fallback';
const image_url = get_host_info()['HTTPS_ORIGIN'] + image_path;
let entries = await performance.getEntriesByName(image_url);
assert_equals(entries.length, 0, 'No PerformanceResourceTiming');
const image = await load_image(frame.contentDocument,
'square.png?fetch-event');
entries = await wait_for_performance_entries(
image.src, performance, 'resource');
assert_equals(entries.length, 1, 'PerformanceResourceTiming is observed');
const worker_timings = await entries[0].workerTiming;
const expected_worker_timings = [
{
name: "network-fallback mark 1",
entryType: "mark",
detail: { foo: 'foo' }
},
{
name: "network-fallback mark 2",
entryType: "mark",
detail: { bar: 'bar' }
},
{
name: "network-fallback measure",
entryType: "measure",
detail: { baz: 'baz' }
}
];
assert_equals(worker_timings.length, expected_worker_timings.length,
'workerTiming is completed when PerformanceResourceTiming is observed');
for (let i = 0; i < workerTimings.length; i++) {
assert_equals(worker_timings[i].name,
expected_worker_timings[i].name, 'entry name');
assert_equals(worker_timings[i].entryType,
expected_worker_timings[i].entryType, 'entry type');
assert_object_equals(worker_timings[i].detail,
expected_worker_timings[i].detail, 'entry detail');
}
}, 'workerTiming for subresources in a frame with network fallback');
promise_test(async (t) => {
const frame = await with_iframe('resources/empty.html');
t.add_cleanup(() => frame.remove());
const performance = frame.contentWindow.performance;
const image_path = base_path() + 'resources/square.png?fetch-event';
const image_url = get_host_info()['HTTPS_ORIGIN'] + image_path;
let entries = await performance.getEntriesByName(image_url);
assert_equals(entries.length, 0, 'No PerformanceResourceTiming');
const image = await load_image(frame.contentDocument,
'square.png?fetch-event');
entries = await wait_for_performance_entries(
image.src, performance, 'resource');
assert_equals(entries.length, 1, 'PerformanceResourceTiming is observed');
const worker_timings = await entries[0].workerTiming;
const expected_worker_timings = [
{
name: "fetch-event mark 1",
entryType: "mark",
detail: { foo: 'foo' }
},
{
name: "fetch-event mark 2",
entryType: "mark",
detail: { bar: 'bar' }
},
{
name: "fetch-event measure",
entryType: "measure",
detail: { baz: 'baz' }
}
];
assert_equals(worker_timings.length, expected_worker_timings.length,
'workerTiming is completed when PerformanceResourceTiming is observed');
for (let i = 0; i < workerTimings.length; i++) {
assert_equals(worker_timings[i].name,
expected_worker_timings[i].name, 'entry name');
assert_equals(worker_timings[i].entryType,
expected_worker_timings[i].entryType, 'entry type');
assert_object_equals(worker_timings[i].detail,
expected_worker_timings[i].detail, 'entry detail');
}
}, 'workerTiming for subresources in a frame for a response from a fetch' +
'handler');
</script>
importScripts("/resources/testharness.js");
self.addEventListener('fetch', event => {
if (event.request.url.indexOf('fallback') >= 0) {
event.addPerformanceEntry(
performance.mark("network-fallback mark 1",
{ detail: { foo: 'foo' } }));
event.addPerformanceEntry(
performance.mark("network-fallback mark 2",
{ detail: { bar: 'bar' } }));
event.addPerformanceEntry(performance.measure("network-fallback measure",
{
start: "network-fallback mark 1", end: "network-fallback mark 2",
detail: { baz: 'baz' }
}));
return;
} else if (event.request.url.indexOf('fetch-event') >= 0) {
event.respondWith((async () => {
event.addPerformanceEntry(performance.mark("fetch-event mark 1",
{ detail: { foo: 'foo' } }));
const response = await fetch(event.request);
event.waitUntil(new Promise((resolve) => {
// Add performance entries after settling a promise for respondWith().
step_timeout(() => {
event.addPerformanceEntry(performance.mark("fetch-event mark 2",
{ detail: { bar: 'bar' } }));
event.addPerformanceEntry(performance.measure("fetch-event measure",
{
start: "fetch-event mark 1", end: "fetch-event mark 2",
detail: { baz: 'baz' }
}));
resolve();
}, 100);
}));
return response;
})());
}
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment