resource-timing.sub.https.html (5431B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script src="resources/test-helpers.sub.js"></script> 5 <script> 6 function resourceUrl(path) { 7 return "https://{{host}}:{{ports[https][0]}}" + base_path() + path; 8 } 9 10 function crossOriginUrl(path) { 11 return "https://{{hosts[alt][]}}:{{ports[https][0]}}" + base_path() + path; 12 } 13 14 // Verify existance of a PerformanceEntry and the order between the timings. 15 // 16 // |options| has these properties: 17 // performance: Performance interface to verify existance of the entry. 18 // resource: the path to the resource. 19 // mode: 'cross-origin' to load the resource from third-party origin. 20 // description: the description passed to each assertion. 21 // should_no_performance_entry: no entry is expected to be recorded when it's 22 // true. 23 function verify(options) { 24 const url = options.mode === 'cross-origin' ? crossOriginUrl(options.resource) 25 : resourceUrl(options.resource); 26 const entryList = options.performance.getEntriesByName(url, 'resource'); 27 if (options.should_no_performance_entry) { 28 // The performance timeline may not have an entry for a resource 29 // which failed to load. 30 assert_equals(entryList.length, 0, options.description); 31 return; 32 } 33 34 assert_equals(entryList.length, 1, options.description); 35 const entry = entryList[0]; 36 assert_equals(entry.entryType, 'resource', options.description); 37 38 // workerStart is recorded between startTime and fetchStart. 39 assert_greater_than(entry.workerStart, 0, options.description); 40 assert_greater_than_equal(entry.workerStart, entry.startTime, options.description); 41 assert_less_than_equal(entry.workerStart, entry.fetchStart, options.description); 42 43 if (options.mode === 'cross-origin') { 44 assert_equals(entry.responseStart, 0, options.description); 45 assert_greater_than_equal(entry.responseEnd, entry.fetchStart, options.description); 46 } else { 47 assert_greater_than_equal(entry.responseStart, entry.fetchStart, options.description); 48 assert_greater_than_equal(entry.responseEnd, entry.responseStart, options.description); 49 } 50 51 // responseEnd follows fetchStart. 52 assert_greater_than(entry.responseEnd, entry.fetchStart, options.description); 53 // duration always has some value. 54 assert_greater_than(entry.duration, 0, options.description); 55 56 if (options.resource.indexOf('redirect.py') != -1) { 57 assert_less_than_equal(entry.workerStart, entry.redirectStart, 58 options.description); 59 } else { 60 assert_equals(entry.redirectStart, 0, options.description); 61 } 62 } 63 64 promise_test(async (t) => { 65 const worker_url = 'resources/resource-timing-worker.js'; 66 const scope = 'resources/resource-timing-iframe.sub.html'; 67 68 const registration = await service_worker_unregister_and_register(t, worker_url, scope); 69 t.add_cleanup(() => registration.unregister()); 70 await wait_for_state(t, registration.installing, 'activated'); 71 const frame = await with_iframe(scope); 72 t.add_cleanup(() => frame.remove()); 73 74 const performance = frame.contentWindow.performance; 75 verify({ 76 performance: performance, 77 resource: 'resources/sample.js', 78 mode: 'same-origin', 79 description: 'Generated response', 80 }); 81 verify({ 82 performance: performance, 83 resource: 'resources/empty.js', 84 mode: 'same-origin', 85 description: 'Network fallback', 86 }); 87 verify({ 88 performance: performance, 89 resource: 'resources/redirect.py?Redirect=empty.js', 90 mode: 'same-origin', 91 description: 'Redirect', 92 }); 93 verify({ 94 performance: performance, 95 resource: 'resources/square.png', 96 mode: 'same-origin', 97 description: 'Network fallback image', 98 }); 99 // Test that worker start is available on cross-origin no-cors 100 // subresources. 101 verify({ 102 performance: performance, 103 resource: 'resources/square.png', 104 mode: 'cross-origin', 105 description: 'Network fallback cross-origin image', 106 }); 107 108 // Tests for resouces which failed to load. 109 verify({ 110 performance: performance, 111 resource: 'resources/missing.jpg', 112 mode: 'same-origin', 113 description: 'Network fallback load failure', 114 }); 115 verify({ 116 performance: performance, 117 resource: 'resources/missing.asis', // ORB-compatible 404 response. 118 mode: 'cross-origin', 119 description: 'Network fallback cross-origin load failure (404 response)', 120 }); 121 // Tests for respondWith(fetch()). 122 verify({ 123 performance: performance, 124 resource: 'resources/missing.jpg?SWRespondsWithFetch', 125 mode: 'same-origin', 126 description: 'Resource in iframe, nonexistent but responded with fetch to another.', 127 }); 128 verify({ 129 performance: performance, 130 resource: 'resources/sample.txt?SWFetched', 131 mode: 'same-origin', 132 description: 'Resource fetched as response from missing.jpg?SWRespondsWithFetch.', 133 should_no_performance_entry: true, 134 }); 135 // Test for a normal resource that is unaffected by the Service Worker. 136 verify({ 137 performance: performance, 138 resource: 'resources/empty-worker.js', 139 mode: 'same-origin', 140 description: 'Resource untouched by the Service Worker.', 141 }); 142 }, 'Controlled resource loads'); 143 144 test(() => { 145 const url = resourceUrl('resources/test-helpers.sub.js'); 146 const entry = window.performance.getEntriesByName(url, 'resource')[0]; 147 assert_equals(entry.workerStart, 0, 'Non-controlled'); 148 }, 'Non-controlled resource loads'); 149 150 </script>