Modernize WPT: resource-timing and navigation-timing.https.html
As a part of the effort to understand the current behavior of the
resource timing, I changed the tests to use async/await for readability
with adding a few comments.
Bug: 1128786
Change-Id: I45daee67e52a13c98ad3f2010131d858a58781d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2413927
Commit-Queue: Makoto Shimazu <shimazu@chromium.org>
Auto-Submit: Makoto Shimazu <shimazu@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807845}
diff --git a/service-workers/service-worker/navigation-timing.https.html b/service-workers/service-worker/navigation-timing.https.html
index 13b9ee4..6b51a5c 100644
--- a/service-workers/service-worker/navigation-timing.https.html
+++ b/service-workers/service-worker/navigation-timing.https.html
@@ -32,81 +32,45 @@
const worker_url = 'resources/navigation-timing-worker.js';
-promise_test(t => {
+promise_test(async (t) => {
const scope = 'resources/empty.html';
- let frame;
+ const registration = await service_worker_unregister_and_register(t, worker_url, scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+ const frame = await with_iframe(scope);
+ t.add_cleanup(() => frame.remove());
- return service_worker_unregister_and_register(t, worker_url, scope)
- .then(r => {
- return wait_for_state(t, r.installing, 'activated');
- })
- .then(() => with_iframe(scope))
- .then(f => {
- frame = f;
- return navigate_in_frame(frame, 'resources/empty.html');
- })
- .then(timing => {
- assert_greater_than(timing.workerStart, 0);
- verify(timing);
- })
- .catch(unreached_rejection(t))
- .then(() => {
- if (frame)
- frame.remove();
- return service_worker_unregister(t, scope);
- });
+ const timing = await navigate_in_frame(frame, scope);
+ assert_greater_than(timing.workerStart, 0);
+ verify(timing);
}, 'Service worker controlled navigation timing');
-promise_test(t => {
+promise_test(async (t) => {
const scope = 'resources/empty.html?network-fallback';
- let frame;
+ const registration = await service_worker_unregister_and_register(t, worker_url, scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+ const frame = await with_iframe(scope);
+ t.add_cleanup(() => frame.remove());
- return service_worker_unregister_and_register(t, worker_url, scope)
- .then(r => {
- return wait_for_state(t, r.installing, 'activated');
- })
- .then(() => with_iframe(scope))
- .then(f => {
- frame = f;
- return navigate_in_frame(frame, 'resources/empty.html?network-fallback');
- })
- .then(timing => {
- verify(timing);
- })
- .catch(unreached_rejection(t))
- .then(() => {
- if (frame)
- frame.remove();
- return service_worker_unregister(t, scope);
- });
+ const timing = await navigate_in_frame(frame, scope);
+ verify(timing);
}, 'Service worker controlled navigation timing network fallback');
-promise_test(t => {
+promise_test(async (t) => {
const scope = 'resources/redirect.py?Redirect=empty.html';
- let frame;
+ const registration = await service_worker_unregister_and_register(t, worker_url, scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+ const frame = await with_iframe(scope);
+ t.add_cleanup(() => frame.remove());
- return service_worker_unregister_and_register(t, worker_url, scope)
- .then(r => {
- return wait_for_state(t, r.installing, 'activated');
- })
- .then(() => with_iframe(scope))
- .then(f => {
- frame = f;
- return navigate_in_frame(frame, 'resources/redirect.py?Redirect=empty.html');
- })
- .then(timing => {
- verify(timing);
- // Additional checks for redirected navigation.
- assert_true(timing.redirectStart <= timing.redirectEnd,
- 'Expected redirectStart <= redirectEnd');
- assert_true(timing.redirectEnd <= timing.fetchStart,
- 'Expected redirectEnd <= fetchStart');
- })
- .catch(unreached_rejection(t))
- .then(() => {
- if (frame)
- frame.remove();
- return service_worker_unregister(t, scope);
- });
+ const timing = await navigate_in_frame(frame, scope);
+ verify(timing);
+ // Additional checks for redirected navigation.
+ assert_true(timing.redirectStart <= timing.redirectEnd,
+ 'Expected redirectStart <= redirectEnd');
+ assert_true(timing.redirectEnd <= timing.fetchStart,
+ 'Expected redirectEnd <= fetchStart');
}, 'Service worker controlled navigation timing redirect');
</script>
diff --git a/service-workers/service-worker/resource-timing.sub.https.html b/service-workers/service-worker/resource-timing.sub.https.html
index 2a36608..f2f81bc 100644
--- a/service-workers/service-worker/resource-timing.sub.https.html
+++ b/service-workers/service-worker/resource-timing.sub.https.html
@@ -4,138 +4,147 @@
<script src="resources/test-helpers.sub.js"></script>
<script>
function resourceUrl(path) {
- return "https://{{host}}:{{ports[https][0]}}" + base_path() + path;
+ return "https://{{host}}:{{ports[https][0]}}" + base_path() + path;
}
function crossOriginUrl(path) {
- return "https://{{hosts[alt][]}}:{{ports[https][0]}}" + base_path() + path;
+ return "https://{{hosts[alt][]}}:{{ports[https][0]}}" + base_path() + path;
}
+// Verify existance of a PerformanceEntry and the order between the timings.
+//
+// |options| has these properties:
+// performance: Performance interface to verify existance of the entry.
+// resource: the path to the resource.
+// mode: 'cross-origin' to load the resource from third-party origin.
+// description: the description passed to each assertion.
+// should_no_performance_entry: no entry is expected to be recorded when it's
+// true.
function verify(options) {
- const url = options.mode === 'cross-origin' ? crossOriginUrl(options.resource)
- : resourceUrl(options.resource);
- const entryList = options.performance.getEntriesByName(url, 'resource');
- if (options.should_no_performance_entry) {
- // The performance timeline may not have an entry for a resource
- // which failed to load.
- assert_equals(entryList.length, 0, options.description);
- return;
- }
- assert_equals(entryList.length, 1, options.description);
- const entry = entryList[0];
- assert_equals(entry.entryType, 'resource', options.description);
- assert_greater_than(entry.workerStart, 0, options.description);
- assert_greater_than_equal(entry.workerStart, entry.startTime, options.description);
- assert_less_than_equal(entry.workerStart, entry.fetchStart, options.description);
- if (options.mode === 'cross-origin') {
- assert_equals(entry.responseStart, 0, options.description);
- assert_greater_than_equal(entry.responseEnd, entry.fetchStart, options.description);
- } else {
- assert_greater_than_equal(entry.responseStart, entry.fetchStart, options.description);
- assert_greater_than_equal(entry.responseEnd, entry.responseStart, options.description);
- }
- assert_greater_than(entry.responseEnd, entry.fetchStart, options.description);
- assert_greater_than(entry.duration, 0, options.description);
- if (options.resource.indexOf('redirect.py') != -1) {
- assert_less_than_equal(entry.workerStart, entry.redirectStart,
- options.description);
- } else {
- assert_equals(entry.redirectStart, 0, options.description);
- }
+ const url = options.mode === 'cross-origin' ? crossOriginUrl(options.resource)
+ : resourceUrl(options.resource);
+ const entryList = options.performance.getEntriesByName(url, 'resource');
+ if (options.should_no_performance_entry) {
+ // The performance timeline may not have an entry for a resource
+ // which failed to load.
+ assert_equals(entryList.length, 0, options.description);
+ return;
+ }
+
+ assert_equals(entryList.length, 1, options.description);
+ const entry = entryList[0];
+ assert_equals(entry.entryType, 'resource', options.description);
+
+ // workerStart is recorded between startTime and fetchStart.
+ assert_greater_than(entry.workerStart, 0, options.description);
+ assert_greater_than_equal(entry.workerStart, entry.startTime, options.description);
+ assert_less_than_equal(entry.workerStart, entry.fetchStart, options.description);
+
+ if (options.mode === 'cross-origin') {
+ assert_equals(entry.responseStart, 0, options.description);
+ assert_greater_than_equal(entry.responseEnd, entry.fetchStart, options.description);
+ } else {
+ assert_greater_than_equal(entry.responseStart, entry.fetchStart, options.description);
+ assert_greater_than_equal(entry.responseEnd, entry.responseStart, options.description);
+ }
+
+ // responseEnd follows fetchStart.
+ assert_greater_than(entry.responseEnd, entry.fetchStart, options.description);
+ // duration always has some value.
+ assert_greater_than(entry.duration, 0, options.description);
+
+ if (options.resource.indexOf('redirect.py') != -1) {
+ assert_less_than_equal(entry.workerStart, entry.redirectStart,
+ options.description);
+ } else {
+ assert_equals(entry.redirectStart, 0, options.description);
+ }
}
-promise_test(function(t) {
- const worker_url = 'resources/resource-timing-worker.js';
- const scope = 'resources/resource-timing-iframe.sub.html';
- let registration;
+promise_test(async (t) => {
+ const worker_url = 'resources/resource-timing-worker.js';
+ const scope = 'resources/resource-timing-iframe.sub.html';
- return service_worker_unregister_and_register(t, worker_url, scope)
- .then(function(r) {
- registration = r;
- return wait_for_state(t, r.installing, 'activated');
- })
- .then(function() {
- return with_iframe(scope);
- })
- .then(function(frame) {
- const performance = frame.contentWindow.performance;
- verify({
- performance: performance,
- resource: 'resources/dummy.js',
- mode: 'same-origin',
- description: 'Generated response',
- });
- verify({
- performance: performance,
- resource: 'resources/empty.js',
- mode: 'same-origin',
- description: 'Network fallback',
- });
- verify({
- performance: performance,
- resource: 'resources/redirect.py?Redirect=empty.js',
- mode: 'same-origin',
- description: 'Redirect',
- });
- verify({
- performance: performance,
- resource: 'resources/square.png',
- mode: 'same-origin',
- description: 'Network fallback image',
- });
- // Test that worker start is available on cross-origin no-cors
- // subresources.
- verify({
- performance: performance,
- resource: 'resources/square.png',
- mode: 'cross-origin',
- description: 'Network fallback cross-origin image',
- });
+ const registration = await service_worker_unregister_and_register(t, worker_url, scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+ const frame = await with_iframe(scope);
+ t.add_cleanup(() => frame.remove());
- // Tests for resouces which failed to load.
- verify({
- performance: performance,
- resource: 'resources/missing.jpg',
- mode: 'same-origin',
- description: 'Network fallback load failure',
- });
- verify({
- performance: performance,
- resource: 'resources/missing.jpg',
- mode: 'cross-origin',
- description: 'Network fallback cross-origin load failure',
- });
- // Tests for respondWith(fetch()).
- verify({
- performance: performance,
- resource: 'resources/missing.jpg?SWRespondsWithFetch',
- mode: 'same-origin',
- description: 'Resource in iframe, nonexistent but responded with fetch to another.',
- });
- verify({
- performance: performance,
- resource: 'resources/dummy.txt?SWFetched',
- mode: 'same-origin',
- description: 'Resource fetched as response from missing.jpg?SWRespondsWithFetch.',
- should_no_performance_entry: true,
- });
- // Test for a normal resource that is unaffected by the Service Worker.
- verify({
- performance: performance,
- resource: 'resources/empty-worker.js',
- mode: 'same-origin',
- description: 'Resource untouched by the Service Worker.',
- });
+ const performance = frame.contentWindow.performance;
+ verify({
+ performance: performance,
+ resource: 'resources/dummy.js',
+ mode: 'same-origin',
+ description: 'Generated response',
+ });
+ verify({
+ performance: performance,
+ resource: 'resources/empty.js',
+ mode: 'same-origin',
+ description: 'Network fallback',
+ });
+ verify({
+ performance: performance,
+ resource: 'resources/redirect.py?Redirect=empty.js',
+ mode: 'same-origin',
+ description: 'Redirect',
+ });
+ verify({
+ performance: performance,
+ resource: 'resources/square.png',
+ mode: 'same-origin',
+ description: 'Network fallback image',
+ });
+ // Test that worker start is available on cross-origin no-cors
+ // subresources.
+ verify({
+ performance: performance,
+ resource: 'resources/square.png',
+ mode: 'cross-origin',
+ description: 'Network fallback cross-origin image',
+ });
- frame.remove();
- return registration.unregister();
- });
+ // Tests for resouces which failed to load.
+ verify({
+ performance: performance,
+ resource: 'resources/missing.jpg',
+ mode: 'same-origin',
+ description: 'Network fallback load failure',
+ });
+ verify({
+ performance: performance,
+ resource: 'resources/missing.jpg',
+ mode: 'cross-origin',
+ description: 'Network fallback cross-origin load failure',
+ });
+ // Tests for respondWith(fetch()).
+ verify({
+ performance: performance,
+ resource: 'resources/missing.jpg?SWRespondsWithFetch',
+ mode: 'same-origin',
+ description: 'Resource in iframe, nonexistent but responded with fetch to another.',
+ });
+ verify({
+ performance: performance,
+ resource: 'resources/dummy.txt?SWFetched',
+ mode: 'same-origin',
+ description: 'Resource fetched as response from missing.jpg?SWRespondsWithFetch.',
+ should_no_performance_entry: true,
+ });
+ // Test for a normal resource that is unaffected by the Service Worker.
+ verify({
+ performance: performance,
+ resource: 'resources/empty-worker.js',
+ mode: 'same-origin',
+ description: 'Resource untouched by the Service Worker.',
+ });
}, 'Controlled resource loads');
test(() => {
- const url = resourceUrl('resources/test-helpers.sub.js');
- const entry = window.performance.getEntriesByName(url, 'resource')[0];
- assert_equals(entry.workerStart, 0, 'Non-controlled');
+ const url = resourceUrl('resources/test-helpers.sub.js');
+ const entry = window.performance.getEntriesByName(url, 'resource')[0];
+ assert_equals(entry.workerStart, 0, 'Non-controlled');
}, 'Non-controlled resource loads');
</script>