[ResourceTiming]: Migrate redirects(.sub).html WPT
This change updates the redirects.sub.html WPT to follow the new style
and structure we've been introducing in the linked bug.
Bug: 1171767
Change-Id: I28bb746d01872b7ba4585750d86fc4d5a8d9af9b
GithubIssue: https://github.com/w3c/resource-timing/issues/254
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2774478
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Commit-Queue: Tom McKee <tommckee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#864435}
diff --git a/resource-timing/entry-attributes.html b/resource-timing/entry-attributes.html
index e667c63..1115b7f 100644
--- a/resource-timing/entry-attributes.html
+++ b/resource-timing/entry-attributes.html
@@ -9,26 +9,6 @@
<script src="resources/resource-loaders.js"></script>
<script src="resources/entry-invariants.js"></script>
<script>
-
-// Given a resource-loader and a PerformanceResourceTiming validator, loads a
-// resource and validates the resulting entry.
-const attribute_test = (load_resource, validate, test_label) => {
- promise_test(
- async () => {
- // Clear out everything that isn't the one ResourceTiming entry under test.
- performance.clearResourceTimings();
-
- await load_resource();
-
- const entry_list = performance.getEntriesByType("resource");
- if (entry_list.length != 1) {
- throw new Error(`There should be one entry for one resource (found ${entry_list.length})`);
- }
-
- validate(entry_list[0]);
- }, test_label);
-}
-
attribute_test(
() => load.image("resources/fake_responses.py#hash=1"),
entry => {
diff --git a/resource-timing/redirects.html b/resource-timing/redirects.html
new file mode 100644
index 0000000..f0fe409
--- /dev/null
+++ b/resource-timing/redirects.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<title>Resource Timing: resources fetched through same-origin redirects</title>
+<link rel="author" title="Google" href="http://www.google.com/" />
+<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/resource-loaders.js"></script>
+<script src="resources/entry-invariants.js"></script>
+<script>
+const {HTTPS_NOTSAMESITE_ORIGIN} = get_host_info();
+const redirect_url = `/common/redirect.py`;
+const url_prefix = `${redirect_url}?location=/resource-timing/resources/`;
+const https_url_prefix = `${redirect_url}?location=${HTTPS_NOTSAMESITE_ORIGIN}/resource-timing/resources/`;
+
+attribute_test(
+ () => load.stylesheet(url_prefix + "resource_timing_test0.css"),
+ invariants.assert_same_origin_redirected_resource,
+ "Verify attributes of a redirected stylesheet's PerformanceResourceTiming");
+
+attribute_test(
+ () => load.image(url_prefix + "blue.png"),
+ invariants.assert_same_origin_redirected_resource,
+ "Verify attributes of a redirected image's PerformanceResourceTiming");
+
+attribute_test(
+ () => load.iframe(url_prefix + "blank_page_green.html"),
+ invariants.assert_same_origin_redirected_resource,
+ "Verify attributes of a redirected iframe's PerformanceResourceTiming");
+
+attribute_test(
+ () => load.script(url_prefix + "empty_script.js"),
+ invariants.assert_same_origin_redirected_resource,
+ "Verify attributes of a redirected script's PerformanceResourceTiming");
+
+attribute_test(
+ () => load.xhr_sync(url_prefix + "blank_page_green.htm?id=xhr"),
+ invariants.assert_same_origin_redirected_resource,
+ "Verify attributes of a redirected synchronous XMLHttpRequest's " +
+ "PerformanceResourceTiming");
+
+attribute_test(
+ () => load.xhr_sync(https_url_prefix + "blank_page_green.htm?id=xhr"),
+ invariants.assert_cross_origin_redirected_resource,
+ "Verify attributes of a synchronous XMLHttpRequest's " +
+ "PerformanceResourceTiming where the initial HTTP request is redirected " +
+ "to a cross-origin HTTPS resource."
+);
+
+</script>
+</head>
+<body>
+<h1>Description</h1>
+<p>This test validates that, when a fetching resources that encounter
+same-origin redirects, attributes of the PerformanceResourceTiming entry
+conform to the specification.</p>
+</body>
+</html>
diff --git a/resource-timing/redirects.sub.html b/resource-timing/redirects.sub.html
deleted file mode 100644
index d3d4f75..0000000
--- a/resource-timing/redirects.sub.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8" />
-<title>Resource Timing redirect names</title>
-<link rel="author" title="Google" href="http://www.google.com/" />
-<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="resources/webperftestharness.js"></script>
-<script src="resources/webperftestharnessextension.js"></script>
-<script>
-let iframe;
-const redirect_url = 'common/redirect.py';
-const url_prefix = redirect_url + '?location=/resource-timing/resources/';
-const https_url_prefix = redirect_url + '?location=https://{{hosts[alt][]}}:{{ports[https][0]}}/resource-timing/resources/';
-function setup_iframe() {
- const iframe_content =
- '<link rel="stylesheet" href="/' + url_prefix + 'resource_timing_test0.css"></link>' +
- '<img src="/' + url_prefix + 'blue.png"></img>' +
- '<iframe src="/' + url_prefix + 'blank_page_green.htm"></iframe>' +
- '<script src="/' + url_prefix + 'empty_script.js"></scr' + 'ipt>' +
- '<scr' + 'ipt>' +
- 'const xhr = new XMLHttpRequest;' +
- 'xhr.open("GET", "/' + url_prefix + 'blank_page_green.htm?id=xhr", false);' +
- 'xhr.send();' +
- 'const xhr2 = new XMLHttpRequest;' +
- 'xhr2.open("GET", "/' + https_url_prefix + 'blank_page_green.htm?id=xhr", false);' +
- 'xhr2.send();' +
- '</scr' + 'ipt>';
- iframe = document.getElementById('frameContext');
- iframe.contentWindow.document.write(iframe_content);
-}
-function onload_test() {
- const context = new PerformanceContext(iframe.contentWindow.performance);
- const entries = context.getEntriesByType('resource');
-
- const index = window.location.pathname.lastIndexOf('resource-timing');
- const pathname = window.location.pathname.substring(0, index) + url_prefix;
- const https_pathname = window.location.pathname.substring(0, index) + https_url_prefix;
- let expected_entries = {};
- expected_entries[pathname + 'resource_timing_test0.css'] = 'link';
- expected_entries[pathname + 'blue.png'] = 'img';
- expected_entries[pathname + 'blank_page_green.htm'] = 'iframe';
- expected_entries[pathname + 'empty_script.js'] = 'script';
- expected_entries[pathname + 'blank_page_green.htm?id=xhr'] = 'xmlhttprequest';
- expected_entries[https_pathname + 'blank_page_green.htm?id=xhr'] = 'xmlhttprequest';
-
- test_resource_entries(entries, expected_entries);
-}
-window.setup_iframe = setup_iframe;
-</script>
-</head>
-<body>
-<h1>Description</h1>
-<p>This test validates that redirects do not alter the URL.</p>
-<div id="log"></div>
-<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe>
-</body>
-</html>
diff --git a/resource-timing/resources/entry-invariants.js b/resource-timing/resources/entry-invariants.js
index 26701ee..51d94e3 100644
--- a/resource-timing/resources/entry-invariants.js
+++ b/resource-timing/resources/entry-invariants.js
@@ -88,5 +88,50 @@
"domainLookupEnd",
"connectStart",
]);
+ },
+
+ // Asserts that attributes of the given PerformanceResourceTiming entry match
+ // what the spec dictates for any resource fetched over HTTPS through a
+ // cross-origin redirect.
+ // (e.g. GET http://remote.com/foo => 304 Location: https://remote.com/foo)
+ assert_cross_origin_redirected_resource: entry => {
+ assert_zeroed_(entry, [
+ "redirectStart",
+ "redirectEnd",
+ "domainLookupStart",
+ "domainLookupEnd",
+ "connectStart",
+ "connectEnd",
+ "secureConnectionStart",
+ "requestStart",
+ "responseStart",
+ ]);
+
+ assert_positive_(entry, [
+ "fetchStart",
+ "responseEnd",
+ ]);
}
};
+
+// Given a resource-loader and a PerformanceResourceTiming validator, loads a
+// resource and validates the resulting entry.
+const attribute_test = (load_resource, validate, test_label) => {
+ promise_test(
+ async () => {
+ // Clear out everything that isn't the one ResourceTiming entry under test.
+ performance.clearResourceTimings();
+
+ await load_resource();
+
+ const entry_list = performance.getEntriesByType("resource");
+ if (entry_list.length != 1) {
+ const names = entry_list
+ .map(e => e.name)
+ .join(", ");
+ throw new Error(`There should be one entry for one resource (found ${entry_list.length}: ${names})`);
+ }
+
+ validate(entry_list[0]);
+ }, test_label);
+}
diff --git a/resource-timing/resources/resource-loaders.js b/resource-timing/resources/resource-loaders.js
index 1d20d71..c5754d1 100644
--- a/resource-timing/resources/resource-loaders.js
+++ b/resource-timing/resources/resource-loaders.js
@@ -26,5 +26,56 @@
return document.fonts.ready.then(() => {
document.body.removeChild(div);
});
+ },
+
+ // Returns a promise that settles once the given path has been fetched as a
+ // stylesheet resource.
+ stylesheet: async path => {
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.type = "text/css";
+ link.href = path;
+
+ const loaded = new Promise(resolve => {
+ link.onload = link.onerror = resolve;
+ });
+
+ document.head.appendChild(link);
+ await loaded;
+ document.head.removeChild(link);
+ },
+
+ // Returns a promise that settles once the given path has been fetched as an
+ // iframe.
+ iframe: async path => {
+ const frame = document.createElement("iframe");
+ const loaded = new Promise(resolve => {
+ frame.onload = frame.onerror = resolve;
+ });
+ frame.src = path;
+ document.body.appendChild(frame);
+ await loaded;
+ document.body.removeChild(frame);
+ },
+
+ // Returns a promise that settles once the given path has been fetched as a
+ // script.
+ script: async path => {
+ const script = document.createElement("script");
+ const loaded = new Promise(resolve => {
+ script.onload = script.onerror = resolve;
+ });
+ script.src = path;
+ document.body.appendChild(script);
+ await loaded;
+ document.body.removeChild(script);
+ },
+
+ // Returns a promise that settles once the given path has been fetched
+ // through a synchronous XMLHttpRequest.
+ xhr_sync: async path => {
+ const xhr = new XMLHttpRequest;
+ xhr.open("GET", path, /* async = */ false);
+ xhr.send();
}
};