summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/navigation-timing
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/navigation-timing')
-rw-r--r--testing/web-platform/tests/navigation-timing/META.yml5
-rw-r--r--testing/web-platform/tests/navigation-timing/buffered-flag.window.js16
-rw-r--r--testing/web-platform/tests/navigation-timing/dom-interactive-image-document.html25
-rw-r--r--testing/web-platform/tests/navigation-timing/dom-interactive-media-document.html25
-rw-r--r--testing/web-platform/tests/navigation-timing/idlharness.window.js20
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-data-uri.html12
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-attributes-exist.html67
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-attributes-values.html137
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-document-open.html102
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-document-replaced.html60
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-frame-removed.html27
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-instance-accessible-from-the-start.html13
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-instance-accessors.html78
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-navigate-iframe.html40
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-navigate-within-document.html85
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-backforward.html82
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-navigate.html32
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-reload.html54
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-final-original-origin.html53
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-partial-opt-in.html52
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-redirect-none.html33
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-redirect-server.html49
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-redirect-xserver.html50
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-response-end-and-duration-before-during-and-after-load-event.html27
-rw-r--r--testing/web-platform/tests/navigation-timing/nav2-test-unique-nav-instances.html76
-rw-r--r--testing/web-platform/tests/navigation-timing/navigation-type-post-backforward.html64
-rw-r--r--testing/web-platform/tests/navigation-timing/nested-unload-timing.html62
-rw-r--r--testing/web-platform/tests/navigation-timing/po-navigation.html29
-rw-r--r--testing/web-platform/tests/navigation-timing/prefetch-transfer-size-executor.html66
-rw-r--r--testing/web-platform/tests/navigation-timing/prefetch-transfer-size-iframe.html51
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-green-with-onunload.html11
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-green.html10
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-meta-redirect.html11
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-unload.html25
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-yellow-with-onunload.html11
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank-page-yellow.html10
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html27
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html.headers1
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/iframe-prefetch-transfer-size.html31
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/navigation-type-post-back.html10
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/navigation_type_post_back.py12
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/performance-attribute-sender.html13
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/respond-slowly.py29
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html8
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html.headers3
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/secure-connection-test.html13
-rw-r--r--testing/web-platform/tests/navigation-timing/resources/webperftestharness.js113
-rw-r--r--testing/web-platform/tests/navigation-timing/secure-connection-start-non-zero.https.html22
-rw-r--r--testing/web-platform/tests/navigation-timing/secure-connection-start-reuse.https.html15
-rw-r--r--testing/web-platform/tests/navigation-timing/supported-navigation-type.window.js20
-rw-r--r--testing/web-platform/tests/navigation-timing/test-document-onload.html48
-rw-r--r--testing/web-platform/tests/navigation-timing/test-document-open.html83
-rw-r--r--testing/web-platform/tests/navigation-timing/test-document-readiness-exist.html49
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigate-within-document.html67
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigation-attributes-exist.html26
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigation-redirectCount-none.html31
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigation-type-backforward.html96
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigation-type-enums.html28
-rw-r--r--testing/web-platform/tests/navigation-timing/test-navigation-type-reload.html109
-rw-r--r--testing/web-platform/tests/navigation-timing/test-no-previous-document.html42
-rw-r--r--testing/web-platform/tests/navigation-timing/test-performance-attributes-exist-in-object.html29
-rw-r--r--testing/web-platform/tests/navigation-timing/test-performance-attributes-exist.html23
-rw-r--r--testing/web-platform/tests/navigation-timing/test-performance-attributes.sub.html29
-rw-r--r--testing/web-platform/tests/navigation-timing/test-readwrite.html28
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-attributes-dependent-on-document-load.html85
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-attributes-exist.html28
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-attributes-order.html111
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-client-redirect.html56
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-reload.html92
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-server-redirect.html49
-rw-r--r--testing/web-platform/tests/navigation-timing/test-timing-xserver-redirect.html72
-rw-r--r--testing/web-platform/tests/navigation-timing/test-unique-performance-objects.html30
-rw-r--r--testing/web-platform/tests/navigation-timing/unload-event-same-origin-check.html125
73 files changed, 3223 insertions, 0 deletions
diff --git a/testing/web-platform/tests/navigation-timing/META.yml b/testing/web-platform/tests/navigation-timing/META.yml
new file mode 100644
index 0000000000..bfb0e0f1f6
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/META.yml
@@ -0,0 +1,5 @@
+spec: https://w3c.github.io/navigation-timing/
+suggested_reviewers:
+ - plehegar
+ - igrigorik
+ - yoavweiss
diff --git a/testing/web-platform/tests/navigation-timing/buffered-flag.window.js b/testing/web-platform/tests/navigation-timing/buffered-flag.window.js
new file mode 100644
index 0000000000..c6b1e0bc85
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/buffered-flag.window.js
@@ -0,0 +1,16 @@
+async_test(t => {
+ function checkEntryList(entries) {
+ assert_equals(entries.length, 1, "Only one navigation timing entry");
+ assert_equals(entries[0].entryType, "navigation", "entryType is \"navigation\"");
+ assert_equals(entries[0].name, window.location.toString(), "name is the address of the document");
+ }
+ // First observer creates second in callback to ensure the entry has been dispatched by the time
+ // the second observer begins observing.
+ new PerformanceObserver(t.step_func(entryList => {
+ checkEntryList(entryList.getEntries());
+ // Second observer requires 'buffered: true' to see the navigation entry.
+ new PerformanceObserver(t.step_func_done(list => {
+ checkEntryList(list.getEntries());
+ })).observe({type: 'navigation', buffered: true});
+ })).observe({entryTypes: ["navigation"]});
+}, "PerformanceObserver with buffered flag sees previous navigation entry.");
diff --git a/testing/web-platform/tests/navigation-timing/dom-interactive-image-document.html b/testing/web-platform/tests/navigation-timing/dom-interactive-image-document.html
new file mode 100644
index 0000000000..36742f0eff
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/dom-interactive-image-document.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Test domInteractive on image document.</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <script>
+ const t = async_test("Test domInteractive on image document");
+ function frameLoaded() {
+ const timing = document.querySelector("iframe").contentWindow.performance.timing;
+ assert_greater_than(timing.domInteractive, 0,
+ "Expect domInteractive to be positive value.");
+ t.done();
+ }
+ </script>
+ <body>
+ <h1>Description</h1>
+ <p>This tests that a image document has positive-value domInteractive.</p>
+ <iframe src="../images/smiley.png" onload="frameLoaded()"></iframe>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/dom-interactive-media-document.html b/testing/web-platform/tests/navigation-timing/dom-interactive-media-document.html
new file mode 100644
index 0000000000..e4e45725d8
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/dom-interactive-media-document.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Test domInteractive on media document.</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <script>
+ const t = async_test("Test domInteractive on media document");
+ function frameLoaded() {
+ const timing = document.querySelector("iframe").contentWindow.performance.timing;
+ assert_greater_than(timing.domInteractive, 0,
+ "Expect domInteractive to be positive value.");
+ t.done();
+ }
+ </script>
+ <body>
+ <h1>Description</h1>
+ <p>This tests that a media document has positive-value domInteractive.</p>
+ <iframe src="../media/A4.mp4" onload="frameLoaded()"></iframe>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/idlharness.window.js b/testing/web-platform/tests/navigation-timing/idlharness.window.js
new file mode 100644
index 0000000000..72cf0c3a3d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/idlharness.window.js
@@ -0,0 +1,20 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+// META: timeout=long
+
+'use strict';
+
+// http://www.w3.org/TR/navigation-timing/
+
+idl_test(
+ ['navigation-timing', 'hr-time'],
+ ['resource-timing', 'performance-timeline', 'dom', 'html'],
+ idlArray => {
+ idlArray.add_objects({
+ Performance: ['performance'],
+ PerformanceNavigation: ['performance.navigation'],
+ PerformanceTiming: ['performance.timing'],
+ PerformanceNavigationTiming: ['performance.getEntriesByType("navigation")[0]']
+ });
+ }
+);
diff --git a/testing/web-platform/tests/navigation-timing/nav2-data-uri.html b/testing/web-platform/tests/navigation-timing/nav2-data-uri.html
new file mode 100644
index 0000000000..851691d6c4
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-data-uri.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>data URL source for navigation-timing/nav2_test_open_data_uri.html</title>
+<!-- NB: this file isn't actually used any where! -->
+<link rel="author" title="Google" href="http://www.google.com/" />
+<script>
+var observer = new PerformanceObserver(
+ function (entryList) {
+ parent.postMessage("observed", "*");
+ observer.disconnect();
+ });
+observer.observe({entryTypes: ["navigation"]});
+</script>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-attributes-exist.html b/testing/web-platform/tests/navigation-timing/nav2-test-attributes-exist.html
new file mode 100644
index 0000000000..b6048e061b
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-attributes-exist.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that PerformanceObserver can observe nav timing 2 instance and that the expected attributes in nav timing 2 instance exist (but does not validate that the values are correct).</p>
+
+ <script>
+ var navTiming2Attributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'decodedBodySize',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'duration',
+ 'encodedBodySize',
+ 'entryType',
+ 'fetchStart',
+ 'initiatorType',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'name',
+ 'nextHopProtocol',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'secureConnectionStart',
+ 'transferSize',
+ 'type',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ 'workerStart'
+ ];
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ var entries = entryList.getEntries();
+ assert_equals(entries.length, 1,
+ "There should be only one navigation timing instance.");
+ for (var i = 0; i < navTiming2Attributes.length; i++) {
+ assert_true(navTiming2Attributes[i] in entries[0],
+ "Expected attribute: " + navTiming2Attributes[i] + ".");
+ }
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Performance navigation timing entries are observable.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-attributes-values.html b/testing/web-platform/tests/navigation-timing/nav2-test-attributes-values.html
new file mode 100644
index 0000000000..f13a8988fc
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-attributes-values.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the values of nav timing 2 instance's timing-related attributes are in certain order and the others are of expected values.</p>
+
+ <script>
+ // Host names and ports may be configured at test execution time. The
+ // web-platform-tests server offers two mechanisms for retrieving these
+ // values dynamically: direct text substitution and the `get-host-info`
+ // script. The former is inapproprate for this test because it
+ // influences the size of the document, and this test includes static
+ // assertions for that value.
+ var host_info = get_host_info();
+ var expectedUrl = "http://" + host_info.ORIGINAL_HOST + ":" +
+ host_info.HTTP_PORT +
+ "/navigation-timing/nav2-test-attributes-values.html";
+ var navTiming2EventOrder1 = [
+ 'startTime',
+ 'redirectStart',
+ //'unloadEventStart',
+ 'redirectEnd',
+ //'unloadEventEnd',
+ 'fetchStart',
+ 'domainLookupStart',
+ 'domainLookupEnd',
+ 'connectStart',
+ //'secureConnectionStart',
+ 'connectEnd',
+ 'requestStart',
+ 'responseStart',
+ 'responseEnd',
+ 'domInteractive',
+ 'domContentLoadedEventStart',
+ 'domContentLoadedEventEnd',
+ 'domComplete',
+ 'loadEventStart',
+ 'loadEventEnd'
+ ];
+
+ var navTiming2EventOrder2 = [
+ 'redirectStart',
+ 'unloadEventStart',
+ 'redirectEnd',
+ 'unloadEventEnd',
+ 'fetchStart'
+ ];
+
+ var navTiming2EventOrder3 = [
+ 'connectStart',
+ 'secureConnectionStart',
+ 'connectEnd'
+ ];
+
+ // Navigation Timing attributes for comparison.
+ var navTiming1EventOrder = [
+ 'fetchStart',
+ 'domainLookupStart',
+ 'domainLookupEnd',
+ 'connectStart',
+ 'connectEnd',
+ 'requestStart',
+ 'responseStart',
+ 'responseEnd',
+ 'domInteractive',
+ 'domContentLoadedEventStart',
+ 'domContentLoadedEventEnd',
+ 'domComplete',
+ 'loadEventStart',
+ 'loadEventEnd'
+ ];
+
+ function verifyTimingEventOrder(eventOrder, timingEntry) {
+ for (var i = 0; i < eventOrder.length - 1; i++) {
+ assert_true(timingEntry[eventOrder[i]] <= timingEntry[eventOrder[i + 1]],
+ "Expected " + eventOrder[i] + " to be no greater than " + eventOrder[i + 1] + ".");
+ }
+ }
+
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ var entries = entryList.getEntries();
+ assert_equals(entries[0].entryType, "navigation",
+ "Expected entryType to be: navigation.");
+ assert_equals(entries[0].name, expectedUrl);
+ assert_equals(entries[0].startTime, 0,
+ "Expected startTime to be: 0.");
+ assert_equals(entries[0].duration, entries[0].loadEventEnd,
+ "Expected duration to be equal to loadEventEnd.");
+ assert_equals(entries[0].initiatorType, "navigation",
+ "Expected initiatorType to be: navigation.");
+ assert_equals(entries[0].nextHopProtocol, "http/1.1");
+ // This test may fail when response is from cach. Disable or clean cach before
+ // running this test.
+ assert_true(entries[0].transferSize > entries[0].encodedBodySize,
+ "Expected transferSize to be greater than encodedBodySize in uncached navigation.");
+ assert_equals(entries[0].encodedBodySize, 5949);
+ assert_equals(entries[0].decodedBodySize, 5949);
+ verifyTimingEventOrder(entries[0], navTiming2EventOrder1);
+ // Verify if the reported timing is not that different
+ // from what is reported by Navigation Timing 1.
+ navTiming1EventOrder.forEach(
+ function(event) {
+ if (window.performance.timing[event] -
+ window.performance.timing.navigationStart > 0) {
+ assert_greater_than(entries[0][event], 0,
+ "Expected " + event + " to be greater than 0");
+ }
+ });
+ // When unloadEvent happens
+ if (entries[0]["unloadEventStart"] != 0) {
+ verifyTimingEventOrder(entries[0], navTiming2EventOrder2);
+ }
+ // When a secure transport is used
+ if (entries[0]["secureConnectionStart"] != 0) {
+ verifyTimingEventOrder(entries[0], navTiming2EventOrder3);
+ }
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Performance navigation timing instance's value is reasonable.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-document-open.html b/testing/web-platform/tests/navigation-timing/nav2-test-document-open.html
new file mode 100644
index 0000000000..aa1097248d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-document-open.html
@@ -0,0 +1,102 @@
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ var navTiming2Attributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'decodedBodySize',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'duration',
+ 'encodedBodySize',
+ 'entryType',
+ 'fetchStart',
+ 'initiatorType',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'name',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'secureConnectionStart',
+ 'transferSize',
+ 'type',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ 'workerStart'
+ ];
+
+ var originalTiming = {};
+ var didOpen = false;
+
+ function onload_test()
+ {
+ if (!didOpen) {
+ setTimeout(testTimingWithDocumentOpen, 0);
+ didOpen = true;
+ }
+ }
+
+ function testTimingWithDocumentOpen()
+ {
+ var subcontentWindow = document.getElementById("frameContext").contentWindow;
+
+ var timing = subcontentWindow.performance.getEntriesByType("navigation")[0];
+ for (i in navTiming2Attributes) {
+ originalTiming[navTiming2Attributes[i]] = timing[navTiming2Attributes[i]];
+ }
+
+ var subdocument = subcontentWindow.document;
+ subdocument.open();
+ subdocument.write('<!DOCTYPE HTML>');
+ subdocument.write('<html>');
+ subdocument.write('<head>');
+ subdocument.write('<meta charset="utf-8" />');
+ subdocument.write('<title><Green Test Page</title>');
+ subdocument.write('</head>');
+ subdocument.write('<body style="background-color:#00FF00;">');
+ subdocument.write('</body>');
+ subdocument.write('</html>');
+ subdocument.close();
+
+ setTimeout(function() {
+ var timing = subcontentWindow.performance.getEntriesByType("navigation")[0];
+ for (var i in navTiming2Attributes) {
+ assert_equals(originalTiming[navTiming2Attributes[i]], timing[navTiming2Attributes[i]],
+ navTiming2Attributes[i] + " is the same after document open.");
+ }
+ done();
+ }, 0);
+ }
+ </script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates window.performance.getEntriesByType("navigation") remains constant when a
+ document is replaced using document.open.</p>
+
+ <p>This page should be loaded with a yellow frame below. It then replaces the
+ document in that frame with a green document.</p>
+
+ <p>The test passes if all of the checks to performance.getEntriesByType("navigation") are correct and
+ the frame below ends with a green background.</p>
+
+ <iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+ </html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-document-replaced.html b/testing/web-platform/tests/navigation-timing/nav2-test-document-replaced.html
new file mode 100644
index 0000000000..5972f20e9b
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-document-replaced.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ var navigation_frame;
+ var pnt1;
+ var step = 1;
+ function onload_test()
+ {
+ navigation_frame = document.getElementById("frameContext").contentWindow;
+ setTimeout("nav_frame();", 0);
+ }
+
+ function nav_frame()
+ {
+ switch (step)
+ {
+ case 1:
+ {
+ pnt1 = navigation_frame.performance.getEntriesByType("navigation")[0];
+ navigation_frame.location.href = '/navigation-timing/resources/blank_page_green_with_onunload.html';
+ step++;
+ break;
+ }
+ case 2:
+ {
+ navigation_frame.history.back();
+ step++;
+ break;
+ }
+ case 3:
+ {
+ var pnt2 = navigation_frame.performance.getEntriesByType("navigation")[0];
+ assert_equals(pnt1.type, "navigate");
+ assert_equals(pnt2.type, "back_forward");
+ done();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <h1>
+ Description</h1>
+ <p>
+ This test validates that a PerformanceNavigatingTiming corresponding to a detached document can't access a different document's state. </p>
+ <iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow_with_onunload.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-frame-removed.html b/testing/web-platform/tests/navigation-timing/nav2-test-frame-removed.html
new file mode 100644
index 0000000000..0bef297d4e
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-frame-removed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ function onload_test()
+ { test(function() {
+ var pnt = window.frames[0].performance.getEntriesByType("navigation")[0];
+ document.getElementById("frameContext").remove();
+ assert_equals(pnt.type, "navigate");
+ });
+ }
+ </script>
+ </head>
+ <body>
+ <h1>
+ Description</h1>
+ <p>
+ This test validates that PerformanceNavigationTiming::type()'s default value is navigate </p>
+ <iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow_with_onunload.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessible-from-the-start.html b/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessible-from-the-start.html
new file mode 100644
index 0000000000..ad50c6a87d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessible-from-the-start.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ var navigationTiming2 = window.performance.getEntriesByType('navigation')[0];
+ assert_not_equals(navigationTiming2, undefined);
+ assert_equals(navigationTiming2.entryType, "navigation");
+ assert_equals(navigationTiming2.startTime, 0);
+ assert_equals(navigationTiming2.initiatorType, "navigation");
+ done();
+}, "PerformanceNavigationTiming instance exists with reasonable values.");
+</script>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessors.html b/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessors.html
new file mode 100644
index 0000000000..17f36832c9
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-instance-accessors.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that nav timing 2 instance can be accessed by three different accessors once available: window.performance.getEntries()/getEntriesByType("navigation")/getEntriesByName("document")</p>
+
+ <script>
+ var host_info = get_host_info();
+ var expectedUrl = "http://" + host_info.ORIGINAL_HOST + ":" +
+ host_info.HTTP_PORT + "/navigation-timing/nav2-test-instance-accessors.html";
+ var navTiming2Attributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'decodedBodySize',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'duration',
+ 'encodedBodySize',
+ 'entryType',
+ 'fetchStart',
+ 'initiatorType',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'name',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'secureConnectionStart',
+ 'transferSize',
+ 'type',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ 'workerStart'
+ ];
+
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ var instance1 = performance.getEntries()[0];
+ var instance2 = performance.getEntriesByType("navigation")[0];
+ var instance3 = performance.getEntriesByName(expectedUrl)[0];
+
+ assert_equals(performance.getEntriesByType("navigation").length, 1, "Expected there is only one navigation timing instance.");
+ assert_equals(performance.getEntriesByName(expectedUrl).length, 1, "Expected there is only one navigation timing instance.");
+
+ for (var i = 0; i < navTiming2Attributes.length; i++) {
+ assert_equals(instance1[navTiming2Attributes[i]], instance2[navTiming2Attributes[i]]);
+ }
+
+ for (var i = 0; i < navTiming2Attributes.length; i++) {
+ assert_equals(instance1[navTiming2Attributes[i]], instance3[navTiming2Attributes[i]]);
+ }
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Performance navigation timing entries are accessible through three different accessors.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-navigate-iframe.html b/testing/web-platform/tests/navigation-timing/nav2-test-navigate-iframe.html
new file mode 100644
index 0000000000..0c144bda45
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-navigate-iframe.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>PerformanceNavigationTiming.name updated in iframes</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+promise_test(async function (t) {
+ var ifr = document.createElement("iframe");
+ document.body.appendChild(ifr);
+
+ ifr.src="resources/blank_page_green.html";
+ await new Promise(resolve => {
+ ifr.onload = function() {
+ assert_equals(ifr.contentWindow.performance.getEntriesByType("navigation").length, 1, "Only one navigation time entry");
+ assert_equals(ifr.contentWindow.performance.getEntriesByType("navigation")[0].name, ifr.contentWindow.location.toString(), "navigation name matches the window.location");
+ assert_true(ifr.contentWindow.performance.getEntriesByType("navigation")[0].name.endsWith("blank_page_green.html"), "navigation name is blank_page_green.html");
+ resolve();
+ }
+ });
+
+
+ await new Promise(resolve => { setTimeout(resolve, 100); });
+ ifr.src ="resources/blank_page_yellow.html";
+
+ await new Promise(resolve => {
+ ifr.onload = function() {
+ assert_equals(ifr.contentWindow.performance.getEntriesByType("navigation").length, 1, "Only one navigation time entry");
+ assert_equals(ifr.contentWindow.performance.getEntriesByType("navigation")[0].name, ifr.contentWindow.location.toString(), "navigation name matches the window.location");
+ assert_true(ifr.contentWindow.performance.getEntriesByType("navigation")[0].name.endsWith("blank_page_yellow.html"), "navigation name is blank_page_yellow.html");
+ resolve();
+ }
+ });
+}, "navigation.name updated when iframe URL changes");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-navigate-within-document.html b/testing/web-platform/tests/navigation-timing/nav2-test-navigate-within-document.html
new file mode 100644
index 0000000000..75e6e113b6
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-navigate-within-document.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" >
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that all of the window.performance.getEntriesByType("navigation") attributes remain unchanged after an in document navigation (URL fragment change).</p>
+
+ <script>
+ setup({ single_test: true });
+
+ var navTiming2Attributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'decodedBodySize',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'duration',
+ 'encodedBodySize',
+ 'entryType',
+ 'fetchStart',
+ 'initiatorType',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'name',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'secureConnectionStart',
+ 'transferSize',
+ 'type',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ 'workerStart'
+ ];
+
+ var initial_timing = {};
+
+ function check_timing_not_changed()
+ {
+ var timing = window.performance.getEntriesByType("navigation")[0];
+ for (var i = 0; i < navTiming2Attributes.length; ++i)
+ {
+ var property = navTiming2Attributes[i];
+ assert_equals(timing[property], initial_timing[property],
+ property + " is the same after in document navigation.");
+ }
+ done();
+ }
+
+ function save_timing_after_load()
+ {
+ var timing = window.performance.getEntriesByType("navigation")[0];
+ for (var i = 0; i < navTiming2Attributes.length; ++i)
+ {
+ var property = navTiming2Attributes[i];
+ initial_timing[property] = timing[property];
+ }
+ window.location.href = "#1";
+ setTimeout("check_timing_not_changed()", 0);
+ }
+
+ function load_handler()
+ {
+ window.removeEventListener("load", load_handler);
+ setTimeout("save_timing_after_load()", 0);
+ }
+
+ window.addEventListener("load", load_handler, false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-backforward.html b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-backforward.html
new file mode 100644
index 0000000000..d0045415b8
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-backforward.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ function onload_test()
+ {
+ // do this with a timeout to see the visuals of the navigations.
+ setTimeout("nav_frame();", 100);
+ }
+
+ var step = 1;
+ function nav_frame()
+ {
+ var navigation_frame = document.getElementById("frameContext").contentWindow;
+ switch (step)
+ {
+ case 1:
+ {
+ navigation_frame.location.href = '/navigation-timing/resources/blank_page_green_with_onunload.html';
+ step++;
+ break;
+ }
+ case 2:
+ {
+ assert_equals(navigation_frame.performance.getEntriesByType("navigation")[0].type,
+ "navigate",
+ 'Expected navigation type to be navigate.');
+ navigation_frame.history.back();
+ step++;
+ break;
+ }
+ case 3:
+ {
+ assert_equals(navigation_frame.performance.getEntriesByType("navigation")[0].type,
+ "back_forward",
+ 'Expected navigation type to be back_forward.');
+ step++;
+ navigation_frame.history.forward();
+ break;
+ }
+ case 4:
+ {
+ assert_equals(navigation_frame.performance.getEntriesByType("navigation")[0].type,
+ "back_forward",
+ 'Expected navigation type to be back_forward.');
+ done();
+ step++;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>
+ Description</h1>
+ <p>
+ This test validates the value of window.performance.getEntriesByType("navigation")[0].type with a forward
+ and back navigation.</p>
+
+ <p>This page should be loaded with a yellow background frame below. It should turn green for a starting
+ navigation, back to yellow for a back navigation and then back to green again for a forward navigation.</p>
+
+ <p>Along the navigation timeline the window.performance.getEntriesByType("navigation")[0].type is checked for back_forward.</p>
+
+ <p>This test passes if all of the checks to the window.performance.getEntriesByType("navigation")[0].type are correct throughout the navigation
+ scenario and the frame below ends with a green background. Otherwise, this test fails.</p>
+
+ <iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow_with_onunload.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-navigate.html b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-navigate.html
new file mode 100644
index 0000000000..efaef1ec0b
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-navigate.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ assert_equals(entryList.getEntries()[0].type, "navigate", "Expected navigation type to be navigate.");
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Navigation type to be navigate.");
+ </script>
+
+ </head>
+ <body>
+ <h1>
+ Description</h1>
+ <p>
+ This test validates the value of window.performance.getEntriesByType("navigation")[0].type to be navigate.</p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-reload.html b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-reload.html
new file mode 100644
index 0000000000..0f03f07c57
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-navigation-type-reload.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ var reload_frame;
+
+ function onload_test()
+ {
+ reload_frame = document.getElementById("frameContext");
+ reload_frame.onload = function() {
+ setTimeout(do_test, 0);
+ }
+ setTimeout("reload_the_frame();", 100);
+ }
+
+ function reload_the_frame()
+ {
+ reload_frame.contentWindow.location.reload(true);
+ }
+
+ function do_test()
+ {
+ var newNavTiming = document.getElementById("frameContext").contentWindow.performance.getEntriesByType("navigation")[0];
+ assert_equals(newNavTiming.type, "reload", "Expected navigation type to be reload.");
+ assert_true(newNavTiming.unloadEventStart > 0, "Expected unloadEventStart to be greater than 0.");
+ assert_true(newNavTiming.unloadEventEnd > 0, "Expected unloadEventEnd to be greater than 0.");
+ done();
+ }
+ </script>
+ </head>
+ <body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates the value of window.performance.getEntriesByType("navigation")[0].(type/unloadEventEnd/unloadEventStart) with a reloaded navigation.</p>
+
+ <p>This page should be loaded with a green background frame below. The frame will be automatically reloaded
+ and then verified that
+ <ul>
+ <li>The window.performance.getEntriesByType("navigation").type = "reload" after reload</li>
+ <li>The window.performance.getEntriesByType("navigation").unloadEventStart > 0 after reload</li>
+ <li>The window.performance.getEntriesByType("navigation").unloadEventEnd > 0 after reload</li>
+ </ul>
+ </p>
+
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-final-original-origin.html b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-final-original-origin.html
new file mode 100644
index 0000000000..fdefa20250
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-final-original-origin.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ function onload_test()
+ {
+ const frame_performance = document.getElementById("frameContext").contentWindow.performance;
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].type,
+ "navigate",
+ "Expected navigation type to be navigate.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectCount, 0,
+ "Expected redirectCount to be 0.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectStart, 0,
+ "Expected redirectStart to be 0.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectEnd, 0,
+ "Expected redirectEnd to be 0.");
+ done();
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.getEntriesByType("navigation")[0].redirectCount and the
+ window.performance.getEntriesByType("navigation")[0].redirectStart/End times for a cross-origin server side redirect navigation when the final
+ document is the same as the original origin.</p>
+
+ <iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe>
+ <script>
+ // combine the page origin and redirect origin into the IFRAME's src URL
+ const destUrl_first = make_absolute_url({subdomain: "www",
+ path: "/common/redirect-opt-in.py",
+ query: "location=" + make_absolute_url(
+ {path: "/navigation-timing/resources/blank_page_green.html"})
+ });
+ const destUrl = make_absolute_url({
+ path: "/common/redirect.py",
+ query: "location=" + destUrl_first});
+ let frameContext = document.getElementById("frameContext");
+ frameContext.onload = onload_test;
+ frameContext.src = destUrl;
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-partial-opt-in.html b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-partial-opt-in.html
new file mode 100644
index 0000000000..0feb3bfa7f
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-chain-xserver-partial-opt-in.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ function onload_test()
+ {
+ const frame_performance = document.getElementById("frameContext").contentWindow.performance;
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].type,
+ "navigate",
+ "Expected navigation type to be navigate.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectCount, 0,
+ "Expected redirectCount to be 0.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectStart, 0,
+ "Expected redirectStart to be 0.");
+ assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectEnd, 0,
+ "Expected redirectEnd to be 0.");
+ done();
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.getEntriesByType("navigation")[0].redirectCount and the
+ window.performance.getEntriesByType("navigation")[0].redirectStart/End times for a cross-origin server side redirect navigation when the redirect chooses to opt-in.</p>
+
+ <iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe>
+ <script>
+ // combine the page origin and redirect origin into the IFRAME's src URL
+ const destUrl_first = make_absolute_url({subdomain: "www",
+ path: "/common/redirect-opt-in.py",
+ query: "location=" + make_absolute_url(
+ {path: "/navigation-timing/resources/blank_page_green.html"})
+ });
+ const destUrl = make_absolute_url({subdomain: "www",
+ path: "/common/redirect.py",
+ query: "location=" + destUrl_first});
+ let frameContext = document.getElementById("frameContext");
+ frameContext.onload = onload_test;
+ frameContext.src = destUrl;
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-redirect-none.html b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-none.html
new file mode 100644
index 0000000000..97437e1a5e
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-none.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the value of the window.performance.getEntriesByType("navigation")[0].redirectCount attribute, as well as the window.performance.getEntriesByType("navigation")[0].redirectStart and redirectEnd attributes on a non-redirected navigation.</p>
+
+ <script>
+
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ var navTiming = performance.getEntriesByType("navigation")[0];
+ assert_equals(navTiming.redirectCount, 0, "Expected redirectCount to be 0.");
+ assert_equals(navTiming.redirectStart, 0, "Expected redirectStart to be 0.");
+ assert_equals(navTiming.redirectEnd, 0, "Expected redirectEnd to be 0.");
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Naivation without redirects.");
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-redirect-server.html b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-server.html
new file mode 100644
index 0000000000..9ec2992bef
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-server.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script>
+ setup({ single_test: true });
+
+ function verifyTimingEventOrder(eventOrder, timingEntry) {
+ for (let i = 0; i < eventOrder.length - 1; i++) {
+ assert_true(timingEntry[eventOrder[i]] < timingEntry[eventOrder[i + 1]],
+ "Expected " + eventOrder[i] + " to be no greater than " + eventOrder[i + 1] + ".");
+ }
+ }
+
+ function onload_test()
+ {
+ const frame_performance = document.getElementById("frameContext").contentWindow.performance;
+ const navigation_entry = frame_performance.getEntriesByType("navigation")[0];
+ assert_equals(navigation_entry.type,
+ "navigate",
+ "Expected navigation type to be navigate.");
+ assert_equals(navigation_entry.redirectCount, 1, "Expected redirectCount to be 1.");
+ assert_equals(navigation_entry.name, 'http://' + document.location.host + '/navigation-timing/resources/blank_page_green.html');
+
+ var timgingEvents = [
+ 'startTime',
+ 'redirectStart',
+ 'redirectEnd',
+ ];
+ verifyTimingEventOrder(timgingEvents, frame_performance.getEntriesByType("navigation")[0]);
+ done();
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.redirectCount and the
+ window.performance.timing.redirectStart/End times for a same-origin server side redirect navigation.</p>
+
+ <iframe id="frameContext" onload="onload_test();" src="/common/redirect.py?location=/navigation-timing/resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-redirect-xserver.html b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-xserver.html
new file mode 100644
index 0000000000..d8acc8054d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-redirect-xserver.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ function onload_test()
+ {
+ var performanceNamespace = document.getElementById("frameContext").contentWindow.performance;
+ assert_equals(performanceNamespace.getEntriesByType("navigation")[0].type,
+ "navigate",
+ "Expected navigation type to be navigate.");
+ assert_equals(performanceNamespace.getEntriesByType("navigation")[0].redirectCount, 0,
+ "Expected redirectCount to be 0.");
+ assert_equals(performanceNamespace.getEntriesByType("navigation")[0].redirectStart, 0,
+ "Expected redirectStart to be 0.");
+ assert_equals(performanceNamespace.getEntriesByType("navigation")[0].redirectEnd, 0,
+ "Expected redirectEnd to be 0.");
+
+ done();
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.getEntriesByType("navigation")[0].redirectCount and the
+ window.performance.getEntriesByType("navigation")[0].redirectStart/End times for a cross-origin server side redirect navigation.</p>
+
+ <iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe>
+ <script>
+ // combine the page origin and redirect origin into the IFRAME's src URL
+ var destUrl = make_absolute_url({subdomain: "www",
+ path: "/common/redirect.py",
+ query: "location=" + make_absolute_url(
+ {path: "/navigation-timing/resources/blank_page_green.html"})
+ });
+ var frameContext = document.getElementById("frameContext");
+ frameContext.onload = onload_test;
+ frameContext.src = destUrl;
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-response-end-and-duration-before-during-and-after-load-event.html b/testing/web-platform/tests/navigation-timing/nav2-test-response-end-and-duration-before-during-and-after-load-event.html
new file mode 100644
index 0000000000..3876ce7e86
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-response-end-and-duration-before-during-and-after-load-event.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe src="resources/respond-slowly.py"></iframe>
+<body>
+<script>
+async_test(function(t) {
+ window.addEventListener('message', t.step_func_done(function(event) {
+ let originalResponseEnd = event.data[0];
+ let originalDuration = event.data[1];
+ let responseEndDuringLoadEvent = event.data[2];
+ let durationDuringLoadEvent = event.data[3];
+ let responseEndAfterLoadEvent = event.data[4];
+ let durationAfterLoadEvent = event.data[5];
+ assert_equals(originalResponseEnd, 0, "PerformanceNavigationTiming.responseEnd == 0 before load event");
+ assert_equals(originalDuration, 0, "PerformanceNavigationTiming.duration is 0 before load event");
+ assert_greater_than(responseEndDuringLoadEvent, 500, "PerformanceNavigationTiming.responseEnd is reasonable during load event");
+ assert_equals(durationDuringLoadEvent, 0, "PerformanceNavigationTiming.duration is 0 during load event");
+ assert_greater_than(responseEndAfterLoadEvent, 500, "PerformanceNavigationTiming.responseEnd is reasonable after load event");
+ assert_greater_than(durationAfterLoadEvent, 500, "PerformanceNavigationTiming.duration is reasonable after load event");
+ }));
+}, "Check that performance.getEntriesByType('navigation')[0].responseEnd has reasonable values before and after the load has finished");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nav2-test-unique-nav-instances.html b/testing/web-platform/tests/navigation-timing/nav2-test-unique-nav-instances.html
new file mode 100644
index 0000000000..1d77ab6bae
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nav2-test-unique-nav-instances.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that each window has a unique nav timing 2 instance.</p>
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="display:none;";></iframe>
+ <script>
+
+ var navTiming2Attributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'decodedBodySize',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'duration',
+ 'encodedBodySize',
+ 'entryType',
+ 'fetchStart',
+ 'initiatorType',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'name',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'secureConnectionStart',
+ 'transferSize',
+ 'type',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ 'workerStart'
+ ];
+
+ function not_same_instance(instance1, instance2, attributes) {
+ for (var i in attributes) {
+ if (instance1[attributes[i]] != instance2[attributes[i]])
+ return true;
+ }
+ return false;
+ }
+
+ async_test(function (t) {
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList) {
+ assert_equals(entryList.getEntriesByType("navigation").length, 1, "Only one nav timing instance exists.");
+ assert_equals(document.getElementById("frameContext").contentWindow.performance.getEntriesByType("navigation").length, 1,
+ "Only one nav timing instance exists.");
+ var main_frame_instance = entryList.getEntriesByType("navigation")[0];
+ var iframe_instance = document.getElementById("frameContext").contentWindow.performance.getEntriesByType("navigation")[0];
+ assert_true(not_same_instance(main_frame_instance, iframe_instance, navTiming2Attributes),
+ "Two nav timing instances are not the same instance.");
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+
+ }, "Each window has a unique nav timing 2 instance.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/navigation-type-post-backforward.html b/testing/web-platform/tests/navigation-timing/navigation-type-post-backforward.html
new file mode 100644
index 0000000000..1fbdf1ae9b
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/navigation-type-post-backforward.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Navigation Type Post Back Forward</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+ <script>
+ function execute_helper(fn, args) {
+ return new Promise(resolve => {
+ frame.addEventListener('load', () => {
+ resolve(frame);
+ }, { once: true });
+ fn.apply(null, args);
+ });
+ }
+
+ // Create an iframe.
+ function create_iframe(url) {
+ const frame = document.createElement('iframe');
+ frame.src = url;
+ return frame;
+ }
+
+ // Attach an iframe.
+ function attach_iframe(frame) {
+ document.body.appendChild(frame);
+ }
+
+ // Post by submit method.
+ function submit_form(frame) {
+ frame.contentWindow.document.getElementsByTagName("form")[0].submit();
+ }
+
+ // Navigate away by simulating a click on the link.
+ function navigate_away(frame) {
+ frame.contentWindow.document.getElementsByTagName("a")[0].click();
+ }
+
+ // Navigate back.
+ function navigate_back(frame) {
+ frame.contentWindow.history.back();
+ }
+
+ promise_test(async t => {
+ // Add an iframe and Load page in the iframe.
+ let url = 'resources/navigation-type-post-back.html';
+
+ frame = create_iframe(url);
+ await execute_helper(attach_iframe, [frame]);
+ await execute_helper(submit_form, [frame]);
+ await execute_helper(navigate_away, [frame]);
+ await execute_helper(navigate_back, [frame]);
+
+ assert_equals(frame.contentWindow.performance.getEntriesByType('navigation')[0].type,
+ 'back_forward');
+ }, "Navigation type after posting and navigating away and back should be back_forward.");
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/nested-unload-timing.html b/testing/web-platform/tests/navigation-timing/nested-unload-timing.html
new file mode 100644
index 0000000000..1130fb6840
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/nested-unload-timing.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="timeout" content="long">
+ <title>Navigation Timing: unload event with nested contexts</title>
+ <link rel="help" href="https://w3c.github.io/navigation-timing/"/>
+ <script src="/common/utils.js"></script>
+ <script src="/common/dispatcher/dispatcher.js"></script>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+ const dummyURL = () => `/navigation-timing/resources/blank_page_green.html?uid=${token()}`;
+
+ promise_test(async t => {
+ const mainWindowUnloadDuration = 100;
+ const iframeUnloadDuration = 400;
+ /*
+ We create 3 contexts: One for a popup window that will load a document and then later
+ unload it, one for an iframe inside that popup window, that will unload with the parent
+ document as well, and one for document the popup window will load in order to trigger
+ those previous unload events.
+
+ The iframe is going to busy-wait on unload for 400ms, and the unloading top-level
+ document is going to busy-wait on unload for 100ms.
+
+ We verify that the total unloadEvent duration measured at the final document is ~100 but
+ less than 500ms - does not include the unload event duration from the iframe.
+ */
+ const popupContext = new RemoteContext(token());
+ const iframeContext = new RemoteContext(token());
+ const finalContext = new RemoteContext(token());
+ const popup = window.open(remoteExecutorUrl(popupContext.context_id));
+ t.add_cleanup(() => popup.close());
+ const registerBusyWaitUnload = duration => window.addEventListener('unload', () => {
+ const buffer = 3;
+ const timeoutEnd = performance.now() + duration + buffer;
+ while (timeoutEnd > performance.now()) {}
+ });
+
+ await popupContext.execute_script(registerBusyWaitUnload, [mainWindowUnloadDuration]);
+
+ const unloadIframe = iframeContext.execute_script(registerBusyWaitUnload, [iframeUnloadDuration]);
+ const loadPopup = popupContext.execute_script(async iframeUid => {
+ const iframe = document.createElement('iframe');
+ iframe.src = `/common/dispatcher/remote-executor.html?uuid=${iframeUid}`;
+ document.body.appendChild(iframe);
+ await new Promise(resolve => iframe.addEventListener('load', resolve));
+ }, [iframeContext.context_id]);
+
+ await Promise.all([unloadIframe, loadPopup]);
+ await popupContext.execute_script((uid) => location.href = `/common/dispatcher/remote-executor.html?uuid=${uid}`, [finalContext.context_id]);
+ const navigationTimingEntry = await finalContext.execute_script(() => performance.getEntriesByType('navigation')[0].toJSON());
+ const unloadDuration = navigationTimingEntry.unloadEventEnd - navigationTimingEntry.unloadEventStart;
+ assert_greater_than_equal(unloadDuration, mainWindowUnloadDuration);
+ assert_less_than(unloadDuration, mainWindowUnloadDuration + iframeUnloadDuration);
+ });
+</script>
+</body>
diff --git a/testing/web-platform/tests/navigation-timing/po-navigation.html b/testing/web-platform/tests/navigation-timing/po-navigation.html
new file mode 100644
index 0000000000..a54fb2aff8
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/po-navigation.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>PerformanceObservers: navigation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<h1>PerformanceObservers: navigation</h1>
+<p>
+Navigation will <a href="https://w3c.github.io/performance-timeline/#dfn-queue-a-performanceentry">queue a PerformanceEntry</a>.
+</p>
+<div id="log"></div>
+<script>
+ async_test(function (t) {
+ function checkEntry(pes) {
+ assert_equals(pes.length, 1, "Only one navigation timing entry");
+ assert_equals(pes[0].entryType, "navigation", "entryType is \"navigation\"");
+ assert_equals(pes[0].name, window.location.toString(), "name is the address of the document");
+ }
+ var observer = new PerformanceObserver(
+ t.step_func(function (entryList, obs) {
+ checkEntry(entryList.getEntries());
+ checkEntry(entryList.getEntriesByType("navigation"));
+ checkEntry(entryList.getEntriesByName(window.location.toString()));
+ observer.disconnect();
+ t.done();
+ })
+ );
+ observer.observe({entryTypes: ["navigation"]});
+ }, "navigation entry is observable");
+</script>
diff --git a/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-executor.html b/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-executor.html
new file mode 100644
index 0000000000..b791fd89b6
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-executor.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Navigation Timing Transfert Size of Prefetched Page</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <script src="/common/dispatcher/dispatcher.js"></script>
+</head>
+<!--
+ This test uses RemoteContext and Executor to execute JavaScript in another
+ page opened by this test page. This is because we need to simulate
+ navigating away from current page in this test. It will cause all Javascript
+ code on the test page to be lost if we do it in the test page. We can't do it
+ in an iframe because currently the prefetch behaves differently in an iframe
+ in this particular test case. For detailed information about RemoteContext and
+ Executor, see /common/dispatcher/README.md.
+-->
+<body>
+ <script>
+ const addLink = (url) => {
+ return new Promise(resolve => {
+ const link = document.createElement('link');
+ link.onload = function () { resolve(); };
+ link.rel = 'prefetch';
+ link.as = 'document';
+ link.href = url;
+ document.body.appendChild(link);
+ });
+ }
+
+ const navigateToPrefetchedUrl = (url) => {
+ document.location.href = url;
+ }
+
+ const getTransferSize = () => window.performance.getEntriesByType('navigation')[0].transferSize;
+
+ promise_test(async t => {
+ const testPage = new RemoteContext(token());
+
+ // Function remoteExecutorUrl is defined in /common/dispatcher/dispatcher.js
+ const url = remoteExecutorUrl(testPage.context_id);
+ const handler = window.open(url);
+ t.add_cleanup(() => handler.close());
+
+ const prefetchedPage = new RemoteContext(token());
+
+ const url_to_prefetch = '/navigation-timing/resources/blank_page_prefetch.html?uuid='
+ + prefetchedPage.context_id;
+
+ // Prefetch link.
+ await testPage.execute_script(addLink, [url_to_prefetch]);
+
+ // Navigate to the prefetched link.
+ await testPage.execute_script(navigateToPrefetchedUrl, [url_to_prefetch]);
+
+ // Get navigation timing transfer size.
+ const size = await prefetchedPage.execute_script(getTransferSize);
+
+ assert_equals(0, size);
+ }, "Navigation timing transfer size for a prefetched navigation should be 0.");
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-iframe.html b/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-iframe.html
new file mode 100644
index 0000000000..316f78b955
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/prefetch-transfer-size-iframe.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Navigation Timing Transfert Size of Prefetched Page</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <script src="/common/dispatcher/dispatcher.js"></script>
+</head>
+
+<body>
+ <script>
+ function add_iframe(url) {
+ return new Promise(resolve => {
+ const frame = document.createElement('iframe');
+ frame.src = url;
+ frame.addEventListener('load', () => {
+ resolve(frame);
+ }, { once: true });
+ document.body.appendChild(frame);
+ });
+ };
+
+ promise_test(async t => {
+ // Add an iframe
+ let iframe_url = 'resources/iframe-prefetch-transfer-size.html';
+ frame = await add_iframe(iframe_url)
+
+ // Prefetch a url as link element.
+ await frame.contentWindow.addLink();
+
+ // navigate to the prefetched url.
+ await new Promise(resolve => {
+ frame.addEventListener('load', () => {
+ resolve();
+ }, { once: true });
+ frame.contentWindow.navigateToPrefetchedUrl();
+ });
+
+ // Verify navigation timing transfer size is 0.;
+ let transferSize =
+ frame.contentWindow.performance.getEntriesByType('navigation')[0].transferSize;
+
+ assert_equals(transferSize, 0);
+
+ }, "Navigation timing transfer size for a prefetched navigation should be 0.");
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-green-with-onunload.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-green-with-onunload.html
new file mode 100644
index 0000000000..2f401747b0
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-green-with-onunload.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Green Test Page</title>
+ </head>
+ <!-- use onunload to ensure this does not trigger bfcache -->
+ <body style="background-color:#00FF00;" onunload="1;">
+ <h1>Placeholder</h1>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-green.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-green.html
new file mode 100644
index 0000000000..b8a1947b77
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-green.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Green Test Page</title>
+ </head>
+ <body style="background-color:#00FF00;">
+ <h1>Placeholder</h1>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-meta-redirect.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-meta-redirect.html
new file mode 100644
index 0000000000..4b4bda096c
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-meta-redirect.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <meta http-equiv="refresh" content="1;URL='blank-page-green.html'" />
+ <title>Redirect Placeholder</title>
+ </head>
+ <body style="background-color:#FFFF00";>
+ <h1>Placeholder</h1>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-unload.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-unload.html
new file mode 100644
index 0000000000..bb2a27f168
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-unload.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+
+ <title>Yellow Test Page</title>
+
+ <script type="text/javascript">
+ function onbeforeunload_handler()
+ {
+ var temp = "onbeforeunload";
+ }
+
+ function onunload_handler()
+ {
+ var temp = "onunload";
+ }
+ </script>
+ </head>
+ <body onbeforeunload="onbeforeunload_handler();"
+ onunload="onunload_handler();"
+ style="background-color:#FFFF00;">
+ <h1>Unload</h1>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow-with-onunload.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow-with-onunload.html
new file mode 100644
index 0000000000..771e0701d9
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow-with-onunload.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Yellow Test Page</title>
+ </head>
+ <!-- use onunload to ensure this does not trigger bfcache -->
+ <body style="background-color:#FFFF00;" onunload="1;">
+ <h1>Placeholder</h1>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow.html b/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow.html
new file mode 100644
index 0000000000..4e5e1a000c
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank-page-yellow.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Yellow Test Page</title>
+ </head>
+ <body style="background-color:#FFFF00;">
+ <h1>Placeholder</h1>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html b/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html
new file mode 100644
index 0000000000..1112ca28ec
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Page to be Prefetched</title>
+ <script src="/common/dispatcher/dispatcher.js"></script>
+</head>
+
+<body>
+ <script>
+ const pageshowPromise = new Promise(resolve => {
+ window.addEventListener('pageshow', resolve, { once: true });
+ });
+
+ async function getTransferSize() {
+ await pageshowPromise;
+ return window.performance.getEntriesByType('navigation')[0].transferSize;
+ }
+ const params = new URLSearchParams(window.location.search);
+ const uuid = params.get("uuid");
+ const executor = new Executor(uuid);
+ </script>
+
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html.headers b/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html.headers
new file mode 100644
index 0000000000..771aba7f94
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/blank_page_prefetch.html.headers
@@ -0,0 +1 @@
+Cache-Control: max-age=300
diff --git a/testing/web-platform/tests/navigation-timing/resources/iframe-prefetch-transfer-size.html b/testing/web-platform/tests/navigation-timing/resources/iframe-prefetch-transfer-size.html
new file mode 100644
index 0000000000..fde01775b7
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/iframe-prefetch-transfer-size.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset="utf-8" />
+ <title>Iframe Transfer Size Prefetch</title>
+</head>
+
+<body>
+ <p>Placeholder</p>
+ <script>
+ const urlToPrefetch = 'blank_page_prefetch.html';
+
+ function addLink() {
+ return new Promise(resolve => {
+ const link = document.createElement('link');
+ link.onload = function () { resolve(); };
+ link.rel = 'prefetch';
+ link.as = 'document';
+ link.href = urlToPrefetch;
+ document.body.appendChild(link);
+ });
+ };
+
+ function navigateToPrefetchedUrl() {
+ document.location.href = urlToPrefetch;
+ }
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/navigation-type-post-back.html b/testing/web-platform/tests/navigation-timing/resources/navigation-type-post-back.html
new file mode 100644
index 0000000000..8c19a2f5a5
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/navigation-type-post-back.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+
+<body>
+ <form action="navigation_type_post_back.py" method="post">
+ Post to page <button type="submit">Press to POST page</button>
+ </form>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/navigation_type_post_back.py b/testing/web-platform/tests/navigation-timing/resources/navigation_type_post_back.py
new file mode 100644
index 0000000000..9da06f4f03
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/navigation_type_post_back.py
@@ -0,0 +1,12 @@
+# Accoridng to routes.py in the wpt server implementation, POST method is
+# handled by a Python script handler which requires this file to return an html.
+def main(request, response):
+ content = """
+ <!DOCTYPE html>
+ <html>
+ <body>
+ <a href="blank_page_green.html">navigate away</a>.
+ </body>
+ </html>
+ """
+ return content
diff --git a/testing/web-platform/tests/navigation-timing/resources/performance-attribute-sender.html b/testing/web-platform/tests/navigation-timing/resources/performance-attribute-sender.html
new file mode 100644
index 0000000000..99f544690d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/performance-attribute-sender.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script>
+parent.postMessage([
+ performance.timing.connectStart,
+ performance.timing.navigationStart,
+ performance.timing.secureConnectionStart,
+ performance.timing.connectEnd
+], '*');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/resources/respond-slowly.py b/testing/web-platform/tests/navigation-timing/resources/respond-slowly.py
new file mode 100644
index 0000000000..e58e16f1f0
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/respond-slowly.py
@@ -0,0 +1,29 @@
+import time
+
+
+def main(request, response):
+ head = b"""<script>
+ let navigationTiming = performance.getEntriesByType('navigation')[0];
+ let originalResponseEnd = navigationTiming.responseEnd;
+ let originalDuration = navigationTiming.duration;
+ function checkResponseEnd() {
+ let responseEndDuringLoadEvent = navigationTiming.responseEnd;
+ let durationDuringLoadEvent = navigationTiming.duration;
+ setTimeout(function() {
+ parent.postMessage([
+ originalResponseEnd,
+ originalDuration,
+ responseEndDuringLoadEvent,
+ durationDuringLoadEvent,
+ navigationTiming.responseEnd,
+ navigationTiming.duration], '*');
+ }, 0);
+ }
+ </script><body onload='checkResponseEnd()'>"""
+ response.headers.set(b"Content-Length", str(len(head) + 1000))
+ response.headers.set(b"Content-Type", b"text/html")
+ response.write_status_headers()
+ response.writer.write_content(head)
+ for i in range(100):
+ response.writer.write_content(b"1234567890")
+ time.sleep(0.01)
diff --git a/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html b/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html
new file mode 100644
index 0000000000..e40b00bedb
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<script>
+ window.addEventListener("message", e => {
+ window.top.postMessage(e.data, "*");
+ });
+</script>
+<iframe src="secure-connection-test.html">
+
diff --git a/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html.headers b/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html.headers
new file mode 100644
index 0000000000..b70fbaf3b0
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/secure-connection-interim.html.headers
@@ -0,0 +1,3 @@
+Connection: Keep-Alive
+Content-Length: 170
+
diff --git a/testing/web-platform/tests/navigation-timing/resources/secure-connection-test.html b/testing/web-platform/tests/navigation-timing/resources/secure-connection-test.html
new file mode 100644
index 0000000000..63a80e062b
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/secure-connection-test.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<script>
+const entries = performance.getEntriesByType("navigation");
+if (!entries) {
+ window.top.postMessage("FAIL - not supported", "*");
+}
+const entry = entries[0];
+if (entry.secureConnectionStart != entry.fetchStart) {
+ window.top.postMessage("FAIL - unexpected secureConnectionStart value of " +
+ entry.secureConnectionStart + " does not equal " + entry.fetchStart, "*");
+}
+window.top.postMessage("PASS", "*");
+</script>
diff --git a/testing/web-platform/tests/navigation-timing/resources/webperftestharness.js b/testing/web-platform/tests/navigation-timing/resources/webperftestharness.js
new file mode 100644
index 0000000000..afe09530d7
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/resources/webperftestharness.js
@@ -0,0 +1,113 @@
+//
+// Helper functions for Navigation Timing tests
+//
+
+var timingAttributes = [
+ 'connectEnd',
+ 'connectStart',
+ 'domComplete',
+ 'domContentLoadedEventEnd',
+ 'domContentLoadedEventStart',
+ 'domInteractive',
+ 'domLoading',
+ 'domainLookupEnd',
+ 'domainLookupStart',
+ 'fetchStart',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'navigationStart',
+ 'redirectEnd',
+ 'redirectStart',
+ 'requestStart',
+ 'responseEnd',
+ 'responseStart',
+ 'unloadEventEnd',
+ 'unloadEventStart'
+];
+
+function test_namespace(child_name, skip_root)
+{
+ if (skip_root === undefined) {
+ var msg = 'window.performance is defined';
+ wp_test(function () { assert_not_equals(performanceNamespace, undefined, msg); }, msg);
+ }
+
+ if (child_name !== undefined) {
+ var msg2 = 'window.performance.' + child_name + ' is defined';
+ wp_test(function() { assert_not_equals(performanceNamespace[child_name], undefined, msg2); }, msg2);
+ }
+}
+
+function test_attribute_exists(parent_name, attribute_name, properties)
+{
+ var msg = 'window.performance.' + parent_name + '.' + attribute_name + ' is defined.';
+ wp_test(function() { assert_not_equals(performanceNamespace[parent_name][attribute_name], undefined, msg); }, msg, properties);
+}
+
+function test_enum(parent_name, enum_name, value, properties)
+{
+ var msg = 'window.performance.' + parent_name + '.' + enum_name + ' is defined.';
+ wp_test(function() { assert_not_equals(performanceNamespace[parent_name][enum_name], undefined, msg); }, msg, properties);
+
+ msg = 'window.performance.' + parent_name + '.' + enum_name + ' = ' + value;
+ wp_test(function() { assert_equals(performanceNamespace[parent_name][enum_name], value, msg); }, msg, properties);
+}
+
+function test_timing_order(attribute_name, greater_than_attribute, properties)
+{
+ // ensure it's not 0 first
+ var msg = "window.performance.timing." + attribute_name + " > 0";
+ wp_test(function() { assert_true(performanceNamespace.timing[attribute_name] > 0, msg); }, msg, properties);
+
+ // ensure it's in the right order
+ msg = "window.performance.timing." + attribute_name + " >= window.performance.timing." + greater_than_attribute;
+ wp_test(function() { assert_true(performanceNamespace.timing[attribute_name] >= performanceNamespace.timing[greater_than_attribute], msg); }, msg, properties);
+
+ // ensure we have at least 5 microseconds difference or it's 0
+ msg = "window.performance.timing." + attribute_name + " difference with window.performance.timing." + greater_than_attribute + " is 0 or at least 5 microseconds";
+ var diff = performanceNamespace.timing[attribute_name] - performanceNamespace.timing[greater_than_attribute];
+ wp_test(function() { assert_true((diff === 0) || ((diff * 1000) >= 5), msg); }, msg, properties);
+}
+
+function test_timing_greater_than(attribute_name, greater_than, properties)
+{
+ var msg = "window.performance.timing." + attribute_name + " > " + greater_than;
+ test_greater_than(performanceNamespace.timing[attribute_name], greater_than, msg, properties);
+}
+
+function test_timing_equals(attribute_name, equals, msg, properties)
+{
+ var test_msg = msg || "window.performance.timing." + attribute_name + " == " + equals;
+ test_equals(performanceNamespace.timing[attribute_name], equals, test_msg, properties);
+}
+
+//
+// Non-test related helper functions
+//
+
+function sleep_milliseconds(n)
+{
+ var start = new Date().getTime();
+ while (true) {
+ if ((new Date().getTime() - start) >= n) break;
+ }
+}
+
+//
+// Common helper functions
+//
+
+function test_greater_than(value, greater_than, msg, properties)
+{
+ wp_test(function () { assert_true(value > greater_than, msg); }, msg, properties);
+}
+
+function test_greater_or_equals(value, greater_than, msg, properties)
+{
+ wp_test(function () { assert_true(value >= greater_than, msg); }, msg, properties);
+}
+
+function test_not_equals(value, notequals, msg, properties)
+{
+ wp_test(function() { assert_not_equals(value, notequals, msg); }, msg, properties);
+}
diff --git a/testing/web-platform/tests/navigation-timing/secure-connection-start-non-zero.https.html b/testing/web-platform/tests/navigation-timing/secure-connection-start-non-zero.https.html
new file mode 100644
index 0000000000..e95468ef91
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/secure-connection-start-non-zero.https.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>secureConnectionStart non-zero value test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>The tests that secureConnectionStart has a non-zero value.</p>
+<script>
+ window.onload = () => {
+ test(t => {
+ const entry = performance.getEntriesByType("navigation")[0];
+ assert_greater_than(entry.secureConnectionStart, 0, "secureConnectionStart is non-zero");
+ }, "Test that secureConnectionStart is not zero");
+ };
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/secure-connection-start-reuse.https.html b/testing/web-platform/tests/navigation-timing/secure-connection-start-reuse.https.html
new file mode 100644
index 0000000000..f52a259ecd
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/secure-connection-start-reuse.https.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<title>Navigation Timing secureconnectionstart reuse</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const t = async_test("Test that secureConnectionStart value is as expected when reused");
+window.addEventListener("message", t.step_func_done(e => {
+ assert_equals(e.data, "PASS");
+}));
+</script>
+<iframe src="resources/secure-connection-interim.html">
+
diff --git a/testing/web-platform/tests/navigation-timing/supported-navigation-type.window.js b/testing/web-platform/tests/navigation-timing/supported-navigation-type.window.js
new file mode 100644
index 0000000000..3239c7d29f
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/supported-navigation-type.window.js
@@ -0,0 +1,20 @@
+test(() => {
+ if (typeof PerformanceObserver.supportedEntryTypes === "undefined")
+ assert_unreached("supportedEntryTypes is not supported.");
+ assert_true(PerformanceObserver.supportedEntryTypes.includes("navigation"),
+ "There should be an entry 'navigation' in PerformanceObserver.supportedEntryTypes");
+}, "supportedEntryTypes contains 'navigation'.");
+
+if (typeof PerformanceObserver.supportedEntryTypes !== "undefined") {
+ const entryType = "navigation";
+ if (PerformanceObserver.supportedEntryTypes.includes(entryType)) {
+ promise_test(async() => {
+ await new Promise((resolve) => {
+ new PerformanceObserver(function (list, observer) {
+ observer.disconnect();
+ resolve();
+ }).observe({entryTypes: [entryType]});
+ })
+ }, `'${entryType}' entries should be observable.`)
+ }
+}
diff --git a/testing/web-platform/tests/navigation-timing/test-document-onload.html b/testing/web-platform/tests/navigation-timing/test-document-onload.html
new file mode 100644
index 0000000000..7cc18491d6
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-document-onload.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>window.performance.navigation attributes</title>
+ <link rel="author" title="Mozilla" href="https://www.mozilla.org/" />
+ <link rel="help" href="https://www.w3.org/TR/navigation-timing-2/#processing-model"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test checks that the transferSize, encodedBodySize and decodedBodySize attributes have correct values when checked in the onload handler</p>
+
+ <div id="log"></div>
+
+ <script>
+ async_test(function (t) {
+ document.addEventListener("DOMContentLoaded", t.step_func_done(() => {
+ let entry = window.performance.getEntriesByType("navigation")[0];
+ assert_greater_than(entry.transferSize, 1000, "descr");
+ assert_greater_than(entry.encodedBodySize, 1000, "descr");
+ assert_greater_than(entry.decodedBodySize, 1000, "descr");
+ }));
+ }, "Test that the attributes have a proper value during DOMContentLoaded");
+
+ async_test(function (t) {
+ window.addEventListener("load", t.step_func_done(() => {
+ let entry = window.performance.getEntriesByType("navigation")[0];
+ assert_greater_than(entry.transferSize, 1000, "descr");
+ assert_greater_than(entry.encodedBodySize, 1000, "descr");
+ assert_greater_than(entry.decodedBodySize, 1000, "descr");
+ async_test(function (t) {
+ setTimeout(t.step_func_done(() => {
+ let entry = window.performance.getEntriesByType("navigation")[0];
+ assert_greater_than(entry.transferSize, 1000, "descr");
+ assert_greater_than(entry.encodedBodySize, 1000, "descr");
+ assert_greater_than(entry.decodedBodySize, 1000, "descr");
+ }), 0);
+ }, "Test that the attributes have a proper value during a task after onload");
+ }));
+ }, "Test that the attributes have a proper value during onload");
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-document-open.html b/testing/web-platform/tests/navigation-timing/test-document-open.html
new file mode 100644
index 0000000000..1986b3fb98
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-document-open.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<title>window.performance.timing for dynamically created documents</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+<link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/performance-timeline-utils.js"></script>
+<script src="resources/webperftestharness.js"></script>
+<script>
+setup({explicit_done: true});
+
+// explicitly test the namespace before we start testing
+test_namespace();
+
+var originalTiming = {};
+var didOpen = false;
+
+function onload_test() {
+ if (!didOpen) {
+ step_timeout(testTimingWithDocumentOpen, 0);
+ didOpen = true;
+ }
+}
+
+function testTimingWithDocumentOpen() {
+ var subcontentWindow = document.getElementById("frameContext").contentWindow;
+
+ if (subcontentWindow.performance === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ var timing = subcontentWindow.performance.timing;
+ for (i in timingAttributes) {
+ originalTiming[timingAttributes[i]] = timing[timingAttributes[i]];
+ }
+
+ var subdocument = subcontentWindow.document;
+ subdocument.open();
+ subdocument.write('<!DOCTYPE HTML>');
+ subdocument.write('<html>');
+ subdocument.write('<head>');
+ subdocument.write('<meta charset="utf-8" />');
+ subdocument.write('<title><Green Test Page</title>');
+ subdocument.write('</head>');
+ subdocument.write('<body style="background-color:#00FF00;">');
+ subdocument.write('</body>');
+ subdocument.write('</html>');
+ subdocument.close();
+
+ step_timeout(function() {
+ var timing = subcontentWindow.performance.timing;
+ for (var i in timingAttributes) {
+ test_equals(timing[timingAttributes[i]],
+ originalTiming[timingAttributes[i]],
+ timingAttributes[i] + " is the same after document open.");
+ }
+ done();
+ }, 0);
+}
+</script>
+</head>
+<body>
+<h1>Description</h1>
+<p>This test validates window.performance.timing remains constant when a
+document is replaced using document.open.</p>
+
+<p>This page should be loaded with a yellow frame below. It then replaces the
+document in that frame with a green document.</p>
+
+<p>The test passes if all of the checks to performance.timing are correct and
+the frame below ends with a green background.</p>
+
+<div id="log"></div>
+<br />
+<iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow.html" style="width: 250px; height: 250px;"></iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-document-readiness-exist.html b/testing/web-platform/tests/navigation-timing/test-document-readiness-exist.html
new file mode 100644
index 0000000000..58f5659a09
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-document-readiness-exist.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>document.readyState values exist during a navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/html5/dom.html#resource-metadata-management"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ explicit_done: true });
+ var has_loading = (document.readyState == "loading");
+ var has_interactive = (document.readyState == "interactive");
+ var has_complete = (document.readyState == "complete");
+
+ document.onreadystatechange = function()
+ {
+ if (document.readyState == "loading")
+ {
+ has_loading = true;
+ }
+ if (document.readyState == "interactive")
+ {
+ has_interactive = true;
+ }
+ if (document.readyState = "complete")
+ {
+ has_complete = true;
+ }
+ };
+
+ function onload_test()
+ {
+ test(function () { assert_true(has_loading); }, "Document readiness has loading state.");
+ test(function () { assert_true(has_interactive); }, "Document readiness has interactive state.");
+ test(function () { assert_true(has_complete); }, "Document readiness has complete state.");
+ done();
+ }
+ </script>
+
+</head>
+<body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates that the "loading", "interactive" and "complete"
+ document.readyState states are available during a navigation.</p>
+ <p>Refresh this page to guarantee all readyState phases.</p>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigate-within-document.html b/testing/web-platform/tests/navigation-timing/test-navigate-within-document.html
new file mode 100644
index 0000000000..e17020b7bb
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigate-within-document.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" >
+ <title>window.performance.timing in document navigation</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that all of the window.performance.timing attributes remain unchanged after an in document navigation (URL fragment change).</p>
+
+ <div id="log"></div>
+ <script>
+ setup({explicit_done: true});
+
+ // explicitly test the namespace before we start testing
+ test_namespace('timing');
+
+ var timing;
+
+ function check_timing_not_changed()
+ {
+ for (var i = 0; i < timingAttributes.length; ++i)
+ {
+ var property = timingAttributes[i];
+ test_equals(timing[property], initial_timing[property],
+ property + " is the same after in document navigation.");
+ }
+ done();
+ }
+
+ var initial_timing = {};
+ function save_timing_after_load()
+ {
+ for (var i = 0; i < timingAttributes.length; ++i)
+ {
+ var property = timingAttributes[i];
+ initial_timing[property] = timing[property];
+ }
+ window.location.href = "#1";
+ step_timeout(check_timing_not_changed, 0);
+ }
+
+ function load_handler()
+ {
+ if (performanceNamespace === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ timing = performanceNamespace.timing;
+
+ window.removeEventListener("load", load_handler);
+ step_timeout(save_timing_after_load, 0);
+ }
+
+ window.addEventListener("load", load_handler, false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigation-attributes-exist.html b/testing/web-platform/tests/navigation-timing/test-navigation-attributes-exist.html
new file mode 100644
index 0000000000..845523d1a2
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigation-attributes-exist.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>window.performance.navigation attributes</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that all of the window.performance.navigation attributes exist (but does not validate that their values are correct).</p>
+
+ <div id="log"></div>
+
+ <script>
+ test_namespace('navigation');
+
+ test_attribute_exists('navigation', 'type');
+ test_attribute_exists('navigation', 'redirectCount');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigation-redirectCount-none.html b/testing/web-platform/tests/navigation-timing/test-navigation-redirectCount-none.html
new file mode 100644
index 0000000000..da94d24c74
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigation-redirectCount-none.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.navigation.redirectCount on a non-redirected navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the value of the window.performance.navigation.redirectCount attribute, as well as the window.performance.timing.redirectStart and redirectEnd attributes on a non-redirected navigation.</p>
+
+ <div id="log"></div>
+
+ <script>
+ test_namespace('navigation');
+
+ if (performanceNamespace !== undefined)
+ {
+ test_equals(performanceNamespace.timing.redirectStart, 0, 'timing.redirectStart on an non-redirected navigation');
+ test_equals(performanceNamespace.timing.redirectEnd, 0, 'timing.redirectEnd on an non-redirected navigation');
+ test_equals(performanceNamespace.navigation.redirectCount, 0, 'navigation.redirectCount on an non-redirected navigation');
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigation-type-backforward.html b/testing/web-platform/tests/navigation-timing/test-navigation-type-backforward.html
new file mode 100644
index 0000000000..b5920953cb
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigation-type-backforward.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.navigation.type for back and forward navigations</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ // explicitly test the namespace before we start testing
+ test_namespace('navigation');
+
+ function onload_test()
+ {
+ if (performanceNamespace === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ // do this with a timeout to see the visuals of the navigations.
+ step_timeout(nav_frame, 100);
+ }
+
+ var step = 1;
+ function nav_frame()
+ {
+ var navigation_frame = document.getElementById("frameContext").contentWindow;
+ switch (step)
+ {
+ case 1:
+ {
+ navigation_frame.location.href = '/navigation-timing/resources/blank_page_green_with_onunload.html';
+ step++;
+ break;
+ }
+ case 2:
+ {
+ test_equals(navigation_frame.performance.navigation.type,
+ performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'window.performance.navigation.type == TYPE_NAVIGATE');
+ navigation_frame.history.back();
+ step++;
+ break;
+ }
+ case 3:
+ {
+ test_equals(navigation_frame.performance.navigation.type,
+ performanceNamespace.navigation.TYPE_BACK_FORWARD,
+ 'window.performance.navigation.type == TYPE_BACK_FORWARD after history.back()');
+ step++;
+ navigation_frame.history.forward();
+ break;
+ }
+ case 4:
+ {
+ test_equals(navigation_frame.performance.navigation.type,
+ performanceNamespace.navigation.TYPE_BACK_FORWARD,
+ 'window.performance.navigation.type == TYPE_BACK_FORWARD after history.forward()');
+ done();
+ step++;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>
+ Description</h1>
+ <p>
+ This test validates the value of window.performance.navigation.type with a forward
+ and back navigation.</p>
+
+ <p>This page should be loaded with a yellow background frame below. It should turn green for a starting
+ navigation, back to yellow for a back navigation and then back to green again for a forward navigation.</p>
+
+ <p>Along the navigation timeline the frame.window.performance.type is checked for TYPE_BACK_FORWARD.</p>
+
+ <p>This test passes if all of the checks to the navigation.type are correct throughout the navigation
+ scenario and the frame below ends with a green background. Otherwise, this test fails.</p>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext" onload="onload_test();" src="resources/blank_page_yellow_with_onunload.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigation-type-enums.html b/testing/web-platform/tests/navigation-timing/test-navigation-type-enums.html
new file mode 100644
index 0000000000..ecf6ddc89d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigation-type-enums.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.navigation enums</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the TYPE_* enumerations of window.performance.navigation exist and their values are correct.</p>
+
+ <div id="log"></div>
+
+ <script>
+ test_namespace('navigation');
+
+ test_enum('navigation', 'TYPE_NAVIGATE', 0);
+ test_enum('navigation', 'TYPE_RELOAD', 1);
+ test_enum('navigation', 'TYPE_BACK_FORWARD', 2);
+ test_enum('navigation', 'TYPE_RESERVED', 255);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-navigation-type-reload.html b/testing/web-platform/tests/navigation-timing/test-navigation-type-reload.html
new file mode 100644
index 0000000000..d3331b8197
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-navigation-type-reload.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.navigation.type with a reloaded navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ // explicitly test the namespace before we start testing
+ test_namespace('navigation');
+ var reload_frame;
+ var startingTime;
+
+ function deepCopy(p, c)
+ {
+ var c = c || {};
+ for (var i in p)
+ {
+ if (typeof p[i] === 'object')
+ {
+ c[i] = (p[i].constructor === Array) ? [] : {};
+ deepCopy(p[i], c[i]);
+ } else c[i] = p[i];
+ }
+ return c;
+ }
+
+
+ function onload_test()
+ {
+ reload_frame = document.getElementById("frameContext");
+ reload_frame.onload = function() {
+ /* Need to make sure we don't examine loadEventEnd
+ until after the load event has finished firing */
+ step_timeout(do_test, 0);
+ }
+ step_timeout(reload_the_frame, 100);
+ }
+
+ function reload_the_frame()
+ {
+ //Before reloading, save the current timing
+ startingTime = deepCopy(reload_frame.contentWindow.performance.timing);
+ reload_frame.contentWindow.location.reload(true);
+ }
+
+ function do_test()
+ {
+ reload_frame.onload = null;
+ if (performanceNamespace)
+ {
+ //Verify that the navigation type has updated to reload
+ test_equals(reload_frame.contentWindow.performance.navigation.type,
+ performanceNamespace.navigation.TYPE_RELOAD,
+ 'window.performance.navigation.type == TYPE_RELOAD');
+
+ //Verify that the timing data has been updated into the future
+ var reloadTime = reload_frame.contentWindow.performance.timing;
+ for (attribute in timingAttributes)
+ {
+ var time = timingAttributes[attribute];
+ if (reloadTime[time] === 0)
+ {
+ test_equals(reloadTime[time],
+ startingTime[time],
+ "Reload " + time + "(" + reloadTime[time] + ")" +
+ " == " +
+ "Original " + time + "(" + startingTime[time] + ")");
+ }
+ else
+ {
+ test_greater_than(reloadTime[time],
+ startingTime[time],
+ "Reload " + time +
+ " > " +
+ "Original " + time);
+ }
+ }
+ }
+
+ done();
+ }
+ </script>
+ </head>
+ <body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates the value of window.performance.navigation.type and the values of
+ window.performance.timing.* with a reloaded navigation.</p>
+
+ <p>This page should be loaded with a green background frame below. The frame will be automatically reloaded
+ and then verified that
+ <ul>
+ <li>The window.performance.navigation.type = TYPE_RELOAD</li>
+ <li>All of the widow.performance.timing.* values after reload are > all of the window.performance.timing.* values
+ prior to reload.</li>
+ </ul>
+ </p>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-no-previous-document.html b/testing/web-platform/tests/navigation-timing/test-no-previous-document.html
new file mode 100644
index 0000000000..0bce16525c
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-no-previous-document.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing attributes on an initial navigation</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+
+ <script>
+ setup({explicit_done: true});
+
+ var frame;
+ function onload_test()
+ {
+ frame = document.getElementById("frameContext");
+ test_namespace('navigation');
+ if (performanceNamespace)
+ {
+ test_true(frame.contentWindow.performance.navigation.type == performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'timing.navigation.type is TYPE_NAVIGATE');
+
+ test_equals(frame.contentWindow.performance.timing.unloadEventStart, 0, 'timing.unloadEventStart == 0 on navigation with no previous document');
+ test_equals(frame.contentWindow.performance.timing.unloadEventEnd, 0, 'timing.unloadEventEnd == 0 navigation with no previous document');
+ }
+ done();
+ }
+ </script>
+
+ </head>
+ <body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates the unload event times are 0 when there is no previous document.</p>
+
+ <div id="log"></div><br />
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist-in-object.html b/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist-in-object.html
new file mode 100644
index 0000000000..25fa6b782e
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist-in-object.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance attribute exists in an object</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-window.performance-attribute"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ function onload_test() {
+ var objWindow =
+ document.getElementById("objectContext").contentDocument.defaultView;
+ performanceNamespace = objWindow.performance;
+ test_namespace('timing');
+ test_namespace('navigation', true);
+ }
+ </script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the window.performance object exists in an
+ object element (but does not validate that their values are correct).</p>
+ <object id="objectContext" onload="onload_test();" data="resources/blank-page-green.html"></object>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist.html b/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist.html
new file mode 100644
index 0000000000..ca3a6be5aa
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-performance-attributes-exist.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance attributes</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-window.performance-attribute"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the navigation and timing attributes exist for window.performance
+ (but does not validate that their values are correct).</p>
+ <div id="log"></div>
+ <script>
+ test_namespace('navigation');
+ test_namespace('timing', true);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-performance-attributes.sub.html b/testing/web-platform/tests/navigation-timing/test-performance-attributes.sub.html
new file mode 100644
index 0000000000..50d027e80c
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-performance-attributes.sub.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!-- Use https to ensure secureConnectionStart is nontrivial, if it is supported. -->
+<iframe src="https://{{host}}:{{ports[https][0]}}/navigation-timing/resources/performance-attribute-sender.html"></iframe>
+<body>
+<script>
+async_test(function(t) {
+ window.addEventListener('message', t.step_func_done(function(event) {
+ const connectStart = event.data[0];
+ const navigationStart = event.data[1];
+ const secureConnectionStart = event.data[2];
+ const connectEnd = event.data[3];
+ assert_greater_than_equal(connectStart, navigationStart,
+ 'performance.timing.connectStart >= performance.timing.navigationStart');
+ // secureConnectionStart is an optional attribute.
+ if (secureConnectionStart == undefined) {
+ return;
+ }
+ assert_greater_than_equal(secureConnectionStart, connectStart,
+ 'performance.timing.secureConnectionStart >= performance.timing.connectStart');
+ assert_greater_than_equal(connectEnd, secureConnectionStart,
+ 'performance.timing.connectEnd >= performance.timing.secureConnectionStart');
+ }));
+}, 'Check that performance.timing has reasonable values for secureConnectionStart and other attributes');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-readwrite.html b/testing/web-platform/tests/navigation-timing/test-readwrite.html
new file mode 100644
index 0000000000..a078329dd4
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-readwrite.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance is read/write</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-window.performance-attribute"/>
+ <meta name="assert" content="The window.performance attribute provides a hosting area for performance related attributes. "/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that the window.performance object is read/write.</p>
+ <div id="log"></div>
+ <script>
+ test_namespace();
+
+ window.performance = 'foo';
+ test_equals(window.performance, 'foo', 'window.performance is read/write');
+
+ var performance = 'bar';
+ test_equals(performance, 'bar', 'var performance is read/write');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-attributes-dependent-on-document-load.html b/testing/web-platform/tests/navigation-timing/test-timing-attributes-dependent-on-document-load.html
new file mode 100644
index 0000000000..9eac7bd033
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-attributes-dependent-on-document-load.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+ var reload_frame;
+
+ // Array of navigation timing entries dependent on Document Load Timing.
+ var navTimingAttributes = [
+ 'fetchStart',
+ 'loadEventEnd',
+ 'loadEventStart',
+ 'redirectCount',
+ 'redirectEnd',
+ 'redirectStart',
+ 'responseEnd',
+ 'unloadEventEnd',
+ 'unloadEventStart',
+ ];
+
+ // Function to run the test when the page loads.
+ function onload_test() {
+ reload_frame = document.getElementById("frameContext");
+ reload_frame.onload = function() {
+ step_timeout(do_test, 0);
+ }
+ step_timeout(reload_the_frame, 0);
+ }
+
+ /*
+ Function to reload the iframe and observe values for navigation timing entries:
+ redirectStart, redirectEnd and redirectCount dependent on Document Load Timing.
+ */
+ function reload_the_frame() {
+ reload_frame.contentWindow.location.href =
+ "/common/redirect.py?location=/navigation-timing/resources/blank-page-green.html";
+ }
+
+ /*
+ Function to obtain navigation timing entries and,
+ check if the values are greater than 0.
+ */
+ function do_test() {
+ var nav_frame = document.getElementById("frameContext").contentWindow;
+ var pnt1 = nav_frame.performance.getEntriesByType("navigation")[0];
+ for (i in navTimingAttributes) {
+ assert_greater_than(pnt1[navTimingAttributes[i]], 0,
+ `Expected navigation timing entries: ${navTimingAttributes[i]} greater than 0`);
+ }
+ step_timeout(remove, 0);
+ done(); // Avoids scripting errors
+ }
+
+ /*
+ Function to remove the iframe from the parent body and,
+ check if the navigation timing entries of detached iframe are 0.
+ */
+ function remove() {
+ var nav_frame = document.getElementById("frameContext").contentWindow;
+ var pnt1 = nav_frame.performance.getEntriesByType("navigation")[0];
+ document.body.removeChild(document.getElementById("frameContext"));
+ for (i in navTimingAttributes) {
+ assert_equals(pnt1[navTimingAttributes[i]], 0,
+ `${navTimingAttributes[i]} dependent on Document Load Timing: returns 0`);
+ }
+ }
+ </script>
+</head>
+<body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test observes values of navigation timing entries,</p>
+ <p>dependent on Document Load Timing for a detached iframe.</p>
+ <br />
+ <p>This page should be loaded with a green background frame below,</p>
+ <p>which disappears after the iframe is detached.</p>
+ <br />
+ <iframe id="frameContext"
+ src="/navigation-timing/resources/blank-page-green.html"
+ style="width: 250px; height: 250px;"></iframe>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-attributes-exist.html b/testing/web-platform/tests/navigation-timing/test-timing-attributes-exist.html
new file mode 100644
index 0000000000..5db07459b4
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-attributes-exist.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing attributes</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that all of the window.performance.timing attributes exist (but does not validate that their values are correct).</p>
+
+ <div id="log"></div>
+
+ <script>
+ test_namespace('timing');
+
+ for (var i = 0; i < timingAttributes.length; ++i)
+ {
+ test_attribute_exists('timing', timingAttributes[i]);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-attributes-order.html b/testing/web-platform/tests/navigation-timing/test-timing-attributes-order.html
new file mode 100644
index 0000000000..5e885ea7ec
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-attributes-order.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing attribute ordering on a simple navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ test_namespace('timing');
+
+ var step = 1;
+ function onload_test()
+ {
+ if (step === 1 && window.performance === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ var navigation_frame = document.getElementById("frameContext").contentWindow;
+ performanceNamespace = navigation_frame.performance;
+ switch (step)
+ {
+ case 1:
+ {
+ navigation_frame.location.href = '/navigation-timing/resources/blank_page_green.html';
+ step++;
+ break;
+ }
+ case 2:
+ {
+ test_namespace('navigation', true);
+
+ //
+ // Tests
+ //
+ test_equals(performanceNamespace.navigation.type,
+ performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'window.performance.navigation.type == TYPE_NAVIGATE');
+
+ // navigiation must be non-0
+ test_timing_greater_than('navigationStart', 0);
+
+ // must be no redirection for this test case
+ test_timing_equals('redirectStart', 0);
+ test_timing_equals('redirectEnd', 0);
+
+ // validate attribute ordering
+ test_timing_order('fetchStart', 'navigationStart');
+ test_timing_order('domainLookupStart', 'fetchStart');
+ test_timing_order('domainLookupEnd', 'domainLookupStart');
+ test_timing_order('connectStart', 'domainLookupEnd');
+ test_timing_order('connectEnd', 'connectStart');
+ test_timing_order('requestStart', 'connectEnd');
+ test_timing_order('responseStart', 'requestStart');
+ test_timing_order('responseEnd', 'responseStart');
+ test_timing_order('domLoading', 'fetchStart');
+ test_timing_order('domInteractive', 'responseEnd');
+ test_timing_order('domContentLoadedEventStart', 'domInteractive');
+ test_timing_order('domContentLoadedEventEnd', 'domContentLoadedEventStart');
+ test_timing_order('domComplete', 'domContentLoadedEventEnd');
+ test_timing_order('loadEventStart', 'domContentLoadedEventEnd');
+ test_timing_order('loadEventEnd', 'loadEventStart');
+
+ // setup requires the frame to have a previous page with an onunload event handler.
+ test_timing_order('unloadEventStart', 'navigationStart');
+ test_timing_order('unloadEventEnd', 'unloadEventStart');
+
+ step++;
+ done();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the ordering of the window.performance.timing attributes.</p>
+
+ <p>This page should be loaded with a yellow background frame below which contains an unload event
+ handler.</p>
+
+ <p>After the page loads, the frame is navigated to a new blank page with a green background. At this point, the navigation timeline is verified</p>
+
+ <p>This test passes if all of the checks to the frame.window.performance.timing attributes are
+ correct throughout the navigation scenario and the frame below ends with a green background.
+ Otherwise, this test fails.</p>
+
+ <h1>Setup</h1>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext"
+ onload="/* Need to make sure we don't examine loadEventEnd
+ until after the load event has finished firing */
+ step_timeout(onload_test, 0);"
+ src="resources/blank_page_unload.html"
+ style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-client-redirect.html b/testing/web-platform/tests/navigation-timing/test-timing-client-redirect.html
new file mode 100644
index 0000000000..c376f42bb7
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-client-redirect.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing.redirect attributes on a client redirect navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ test_namespace('navigation');
+ test_namespace('timing', true);
+
+ var redirect_frame;
+ function onload_test()
+ {
+ if (performanceNamespace === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ redirect_frame = document.getElementById("frameContext");
+ redirect_frame.onload = do_test;
+ }
+
+ function do_test()
+ {
+ redirect_frame.onload = "";
+ test_true(redirect_frame.contentWindow.performance.navigation.type == performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'timing.navigation.type is TYPE_NAVIGATE');
+
+ test_equals(redirect_frame.contentWindow.performance.navigation.redirectCount, 0, 'navigation.redirectCount == 0 on an client redirected navigation');
+ test_equals(redirect_frame.contentWindow.performance.timing.redirectStart, 0, 'timing.redirectStart == 0 on an client redirected navigation');
+ test_equals(redirect_frame.contentWindow.performance.timing.redirectEnd, 0, 'timing.redirectEnd == 0 on an client redirected navigation');
+
+ done();
+ }
+ </script>
+
+ </head>
+ <body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates the values of the window.navigation.redirectCount and the
+ window.performance.timing.redirectStart/End times on a client side redirect.</p>
+
+ <div id="log"></div><br />
+ <iframe id="frameContext" src="resources/blank-page-meta-redirect.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-reload.html b/testing/web-platform/tests/navigation-timing/test-timing-reload.html
new file mode 100644
index 0000000000..a660caf4ef
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-reload.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing attributes after a reloaded navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ // explicitly test the namespace before we start testing
+ test_namespace('navigation');
+
+ var reload_frame;
+ var initial_timing;
+
+ function onload_test()
+ {
+ reload_frame = document.getElementById("frameContext");
+
+ if (reload_frame.contentWindow.performance === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ reload_frame.onload = do_test;
+
+ // save frame's initial timings
+ initial_timing = {};
+ var timing = reload_frame.contentWindow.performance.timing;
+
+ for (var i = 0; i < timingAttributes.length; ++i)
+ {
+ var property = timingAttributes[i];
+ initial_timing[property] = timing[property];
+ }
+
+ step_timeout(reload_the_frame, 100);
+ }
+
+ function reload_the_frame()
+ {
+ reload_frame.contentWindow.location.reload(true);
+ }
+
+ function do_test()
+ {
+ reload_frame.onload = "";
+
+ // ensure the frame reloaded
+ test_equals(reload_frame.contentWindow.performance.navigation.type,
+ performanceNamespace.navigation.TYPE_RELOAD,
+ "window.performance.navigation.type == TYPE_RELOAD");
+
+ // ensure reload timings changed
+ var timing = reload_frame.contentWindow.performance.timing;
+ for (var i = 0; i < timingAttributes.length; ++i)
+ {
+ var property = timingAttributes[i];
+
+ // ignore any timings that were zero initially
+ if (initial_timing[property] !== 0)
+ {
+ test_not_equals(timing[property], initial_timing[property],
+ property + " is different after the reload.");
+ }
+ }
+
+ done();
+ }
+ </script>
+ </head>
+ <body onload="onload_test();">
+ <h1>Description</h1>
+ <p>This test validates that the window.performance.timing attributes change when a page is reloaded.</p>
+
+ <p>This page should be loaded with a green background frame below. The frame will be automatically reloaded
+ and then verified that the window.performance.timing attributes have been updated to the new reloaded navigation timings.</p>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-server-redirect.html b/testing/web-platform/tests/navigation-timing/test-timing-server-redirect.html
new file mode 100644
index 0000000000..16567e8997
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-server-redirect.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing.redirect attributes on a same-origin server redirected navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+
+ <script>
+ function onload_test()
+ {
+ test_namespace('navigation');
+ if (performanceNamespace === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ performanceNamespace = document.getElementById("frameContext").contentWindow.performance;
+ test_equals(performanceNamespace.navigation.type,
+ performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'timing.navigation.type is TYPE_NAVIGATE');
+ test_equals(performanceNamespace.navigation.redirectCount, 1, 'navigation.redirectCount == 1 on an server redirected navigation');
+
+ test_timing_greater_than('navigationStart', 0);
+
+ test_timing_order('redirectStart', 'navigationStart');
+ test_timing_order('redirectEnd', 'redirectStart');
+ test_timing_order('fetchStart', 'redirectEnd');
+ test_timing_order('requestStart', 'fetchStart');
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.redirectCount and the
+ window.performance.timing.redirectStart/End times for a same-origin server side redirect navigation.</p>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext" onload="onload_test();" src="/common/redirect.py?location=/navigation-timing/resources/blank_page_green.html" style="width: 250px; height: 250px;"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-timing-xserver-redirect.html b/testing/web-platform/tests/navigation-timing/test-timing-xserver-redirect.html
new file mode 100644
index 0000000000..a39f7c2642
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-timing-xserver-redirect.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>window.performance.timing.redirect attributes on a cross-origin server redirected navigation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface"/>
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ <script src="/common/utils.js"></script>
+ <script>
+ setup({explicit_done: true});
+
+ //
+ // Test configuration
+ //
+
+ var subdomain = "www";
+
+ //
+ // Tests
+ //
+ function onload_test()
+ {
+ test_namespace('navigation');
+ if (performanceNamespace === undefined)
+ {
+ // avoid script errors
+ done();
+ return;
+ }
+
+ performanceNamespace = document.getElementById("frameContext").contentWindow.performance;
+ test_equals(performanceNamespace.navigation.type,
+ performanceNamespace.navigation.TYPE_NAVIGATE,
+ 'timing.navigation.type is TYPE_NAVIGATE');
+ test_equals(performanceNamespace.navigation.redirectCount, 0, 'navigation.redirectCount == 0 on a cross-origin server redirected navigation');
+
+ test_timing_greater_than('navigationStart', 0);
+
+ test_equals(performanceNamespace.timing.redirectStart, 0, 'timing.redirectStart == 0 on a server redirected navigation from another domain');
+ test_equals(performanceNamespace.timing.redirectEnd, 0, 'timing.redirectEnd == 0 on a server redirected navigation from another domain');
+
+ done();
+ }
+ </script>
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates the values of the window.performance.redirectCount and the
+ window.performance.timing.redirectStart/End times for a cross-origin server side redirect navigation.</p>
+
+ <div id="log"></div>
+ <br />
+ <iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe>
+ <script>
+ // combine the page origin and redirect origin into the IFRAME's src URL
+ var destUrl = make_absolute_url({subdomain: subdomain,
+ path: "/common/redirect.py",
+ query: "location=" + make_absolute_url(
+ {path: "/navigation-timing/resources/blank_page_green.html"})
+ });
+ var frameContext = document.getElementById("frameContext");
+ frameContext.onload = onload_test;
+ frameContext.src = destUrl;
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/test-unique-performance-objects.html b/testing/web-platform/tests/navigation-timing/test-unique-performance-objects.html
new file mode 100644
index 0000000000..a8f7e6002d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/test-unique-performance-objects.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Each window object has a unique performance object</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing/#sec-window.performance-attribute" />
+ <meta name="assert" content="Each browsing context must have a unique window.performance.timing attribute."/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/performance-timeline-utils.js"></script>
+ <script src="resources/webperftestharness.js"></script>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test validates that each window has a unique window.performance object.</p>
+ <iframe id="frameContext" src="resources/blank_page_green.html" style="display:none;";></iframe>
+ <div id="log"></div>
+ <script>
+ test_namespace('timing');
+
+ if (performanceNamespace !== undefined)
+ {
+ test_not_equals(performanceNamespace.timing,
+ document.getElementById("frameContext").contentWindow.performance.timing,
+ "Different window objects have unique performance objects");
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/navigation-timing/unload-event-same-origin-check.html b/testing/web-platform/tests/navigation-timing/unload-event-same-origin-check.html
new file mode 100644
index 0000000000..319d04462d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-timing/unload-event-same-origin-check.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Navigation Timing 2 WPT</title>
+ <link rel="author" title="Google" href="http://www.google.com/" />
+ <link rel="help" href="http://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ </head>
+ <body>
+ <script>
+
+ const start_page = "/navigation-timing/resources/blank_page_green.html";
+ const end_page = "/navigation-timing/resources/blank_page_yellow.html";
+ const host_info = get_host_info();
+ const redirect_chain_partial_tao = () => {
+ let url = host_info["HTTP_REMOTE_ORIGIN"];
+ url += "/common/redirect.py";
+ url += "?location=";
+ url += host_info["HTTP_REMOTE_ORIGIN"];
+ url += "/common/redirect-opt-in.py";
+ url += "?location=";
+ url += host_info["ORIGIN"];
+ url += end_page;
+ return url;
+ };
+ const redirect_chain_full_tao = () => {
+ let url = host_info["HTTP_REMOTE_ORIGIN"];
+ url += "/common/redirect-opt-in.py";
+ url += "?location=";
+ url += host_info["ORIGIN"];
+ url += end_page;
+ return url;
+ };
+ const redirect_chain_no_tao = () => {
+ let url = host_info["HTTP_REMOTE_ORIGIN"];
+ url += "/common/redirect.py";
+ url += "?location=";
+ url += host_info["ORIGIN"];
+ url += end_page;
+ return url;
+ };
+ const same_origin_redirect_chain = () => {
+ let url = host_info["ORIGIN"];
+ url += "/common/redirect.py";
+ url += "?location=";
+ url += host_info["ORIGIN"];
+ url += end_page;
+ return url;
+ };
+ const cross_origin_start = host_info["HTTP_REMOTE_ORIGIN"] + start_page;
+ const test_cases = [
+ { start_url : start_page, end_url: redirect_chain_partial_tao(), unload_exposed: false, redirects: 0, name: "Redirect chain with a partial TAO opt-in" },
+ { start_url : start_page, end_url: redirect_chain_full_tao(), unload_exposed: false, redirects: 0, name: "Redirect chain with full TAO opt-in" },
+ { start_url : start_page, end_url: redirect_chain_no_tao(), unload_exposed: false, redirects: 0, name: "Same-cross-same redirect chain with no TAO opt-in" },
+ { start_url : cross_origin_start, end_url: redirect_chain_no_tao(), unload_exposed: false, redirects: 0, name: "cross-cross-same Redirect chain with no TAO opt-in" },
+ { start_url : cross_origin_start, end_url: end_page, unload_exposed: false, redirects: 0, name: "Previous document cross origin" },
+ { start_url : start_page, end_url: end_page, unload_exposed: true, redirects: 0, name: "Previous document same origin" },
+ { start_url : start_page, end_url: null, unload_exposed: false, redirects: 0, name: "No previous document" },
+ { start_url : start_page, end_url: same_origin_redirect_chain(), unload_exposed: true, redirects: 1, name: "Same origin previous document with same origin redirect" },
+ { start_url : same_origin_redirect_chain(), end_url: null, unload_exposed: false, redirects: 1, name: "No previous document with same origin redirect" },
+ { start_url : redirect_chain_no_tao(), end_url: null, unload_exposed: false, redirects: 0, name: "No previous document with cross origin redirect" },
+ { start_url : redirect_chain_full_tao(), end_url: null, unload_exposed: false, redirects: 0, name: "No previous document with cross origin redirect with partial TAO" },
+ { start_url : redirect_chain_partial_tao(), end_url: null, unload_exposed: false, redirects: 0, name: "No previous document with cross origin redirect with TAO" },
+ ];
+
+ const frame_id = "frameContext";
+ const create_frame = (start_url, end_url) => {
+ return new Promise(resolve => {
+ let frame = document.getElementById("frameContext");
+ if (frame) {
+ document.body.removeChild(frame);
+ }
+ frame = document.createElement("iframe");
+ frame.onload = () => {
+ if (end_url) {
+ frame.onload = resolve;
+ step_timeout(() => {frame.contentWindow.location.href = end_url;}, 10);
+ } else {
+ resolve();
+ }
+ };
+ frame.id = "frameContext";
+ frame.src = start_url;
+ document.body.appendChild(frame);
+ });
+ };
+
+ const run_test = (unload_exposed, redirects) => {
+ const entry = document.getElementById("frameContext").contentWindow.performance.getEntriesByType("navigation")[0];
+ assert_equals(entry.type, "navigate", "Expected navigation type to be navigate.");
+ if (!unload_exposed) {
+ assert_equals(entry.unloadEventStart, 0, "Expected unloadEventStart to be 0.");
+ assert_equals(entry.unloadEventEnd, 0, "Expected unloadEventEnd to be 0.");
+ } else {
+ assert_greater_than(entry.unloadEventStart, 0, "Expected unloadEventStart to not be 0.");
+ assert_greater_than(entry.unloadEventEnd, 0, "Expected unloadEventEnd to not be 0.");
+ }
+ assert_equals(entry.redirectCount, redirects, "Expected redirectCount to be " + redirects);
+ };
+
+ const create_test = async test_case => {
+ return new Promise(async (resolve, reject) => {
+ await create_frame(test_case.start_url, test_case.end_url);
+ try {
+ run_test(test_case.unload_exposed, test_case.redirects);
+ resolve();
+ } catch (e) {
+ reject(e);
+ }
+ });
+ };
+
+ for (const test_case of test_cases) {
+ promise_test(() => { return create_test(test_case)}, test_case.name);
+ }
+
+
+ </script>
+ <h1>Description</h1>
+ <p>This test validates that the values of window.performance.getEntriesByType("navigation")[0].(type/unloadEventEnd/unloadEventStart) are only exposed when the same-origin test passes.</p>
+ </body>
+</html>