Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / tests / browser / browser_scriptCache_perf_timeline.js
blobf6dfa0e76574a854daf77a67e042350f22e3887a
1 async function clearAllCache() {
2 await new Promise(function (resolve) {
3 Services.clearData.deleteData(
4 Ci.nsIClearDataService.CLEAR_ALL_CACHES,
5 resolve
6 );
7 });
10 const URL_BASE = "https://example.com/browser/dom/tests/browser/";
11 const URL_BASE2 = "https://example.net/browser/dom/tests/browser/";
13 function testFields(
14 entry,
15 { hasBodyAccess, hasTimingAccess, isCacheOf },
16 desc
17 ) {
18 Assert.equal(entry.entryType, "resource", "entryType should be available");
19 Assert.equal(
20 entry.initiatorType,
21 "script",
22 "initiatorType should be available"
25 if (hasTimingAccess) {
26 Assert.equal(
27 entry.nextHopProtocol,
28 "http/1.1",
29 `nextHopProtocol should be available for ${desc}`
31 } else {
32 Assert.equal(
33 entry.nextHopProtocol,
34 "",
35 `nextHopProtocol should be hidden for ${desc}`
39 if (hasBodyAccess) {
40 Assert.equal(
41 entry.responseStatus,
42 200,
43 `responseStatus should be available for ${desc}`
45 } else {
46 Assert.equal(
47 entry.responseStatus,
49 `responseStatus should be hidden for ${desc}`
53 if (hasBodyAccess) {
54 Assert.equal(
55 entry.contentType,
56 "text/javascript",
57 `contentType should be available for ${desc}`
59 } else {
60 Assert.equal(
61 entry.contentType,
62 "",
63 `contentType should be hidden for ${desc}`
67 Assert.greater(
68 entry.startTime,
70 `startTime should be non-zero for ${desc}`
72 Assert.greater(
73 entry.responseEnd,
75 `responseEnd should be non-zero for ${desc}`
77 Assert.lessOrEqual(
78 entry.startTime,
79 entry.responseEnd,
80 `startTime <= responseEnd for ${desc}`
83 if (hasTimingAccess) {
84 Assert.deepEqual(
85 entry.serverTiming,
87 { name: "name1", duration: 0, description: "" },
88 { name: "name2", duration: 20, description: "" },
89 { name: "name3", duration: 30, description: "desc3" },
91 `serverTiming should be available for ${desc}`
93 } else {
94 Assert.deepEqual(
95 entry.serverTiming,
96 [],
97 `serverTiming should be hidden for ${desc}`
101 if (hasBodyAccess) {
102 Assert.greater(
103 entry.encodedBodySize,
105 `encodedBodySize should be available for ${desc}`
107 } else {
108 Assert.equal(
109 entry.encodedBodySize,
111 `encodedBodySize should be hidden for ${desc}`
115 if (isCacheOf) {
116 Assert.equal(
117 entry.encodedBodySize,
118 isCacheOf.encodedBodySize,
119 `encodedBodySize should equal to non-cache case for ${desc}`
123 if (hasBodyAccess) {
124 Assert.greater(
125 entry.decodedBodySize,
127 `decodedBodySize should be available for ${desc}`
129 } else {
130 Assert.equal(
131 entry.decodedBodySize,
133 `decodedBodySize should be hidden for ${desc}`
137 if (isCacheOf) {
138 Assert.equal(
139 entry.decodedBodySize,
140 isCacheOf.decodedBodySize,
141 `decodedBodySize should equal to non-cache case for ${desc}`
145 if (hasTimingAccess) {
146 if (isCacheOf) {
147 Assert.equal(
148 entry.transferSize,
150 `transferSize should be zero for ${desc}`
152 } else if (hasBodyAccess) {
153 Assert.greater(
154 entry.transferSize,
155 300,
156 `transferSize should be non-zero +300 for ${desc}`
158 } else {
159 Assert.equal(
160 entry.transferSize,
161 300,
162 `transferSize should be zero +300 for ${desc}`
165 } else {
166 Assert.equal(
167 entry.transferSize,
169 `transferSize should be hidden for ${desc}`
174 add_task(async function testCompleteCacheAfterReload() {
175 await SpecialPowers.pushPrefEnv({
176 set: [["dom.script_loader.navigation_cache", true]],
178 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
180 await clearAllCache();
182 await BrowserTestUtils.withNewTab(
184 gBrowser,
185 url: URL_BASE + "dummy.html",
187 async function (browser) {
188 const JS_URL = URL_BASE + "perf_server.sjs?cacheable";
190 const task = async url => {
191 await new Promise(resolve => {
192 const script = content.document.createElement("script");
193 script.src = url;
194 script.addEventListener("load", resolve);
195 content.document.head.append(script);
198 const entries = content.performance
199 .getEntriesByType("resource")
200 .filter(entry => entry.name.includes("perf_server.sjs"));
201 if (entries.length != 1) {
202 throw new Error(`Expect one entry, got ${entries.length} entries`);
204 // NOTE: entries[0].toJSON() doesn't convert serverTiming items.
205 return JSON.parse(JSON.stringify(entries[0]));
208 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
209 Assert.equal(entry.name, JS_URL);
210 testFields(
211 entry,
213 hasBodyAccess: true,
214 hasTimingAccess: true,
216 "same origin (non-cached)"
219 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
221 const cacheEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
222 Assert.equal(cacheEntry.name, JS_URL);
223 testFields(
224 cacheEntry,
226 hasBodyAccess: true,
227 hasTimingAccess: true,
228 isCacheOf: entry,
230 "same origin (cached)"
236 add_task(async function testCompleteCacheInSameDocument() {
237 await SpecialPowers.pushPrefEnv({
238 set: [["dom.script_loader.navigation_cache", true]],
240 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
242 await clearAllCache();
244 await BrowserTestUtils.withNewTab(
246 gBrowser,
247 url: URL_BASE + "dummy.html",
249 async function (browser) {
250 const JS_URL = URL_BASE + "perf_server.sjs?cacheable";
252 const task = async url => {
253 // Before reload:
254 // * The first load is not cache
255 // * The second load is complete cache
256 // After reload:
257 // * Both loads are complete cache
259 for (let i = 0; i < 2; i++) {
260 await new Promise(resolve => {
261 const script = content.document.createElement("script");
262 script.src = url;
263 script.addEventListener("load", () => {
264 resolve();
266 content.document.head.append(script);
270 const entries = content.performance
271 .getEntriesByType("resource")
272 .filter(entry => entry.name.includes("perf_server.sjs"));
273 // In contrast to CSS, JS performs "fetch" for both.
274 if (entries.length != 2) {
275 throw new Error(`Expect two entries, got ${entries.length} entries`);
277 return JSON.parse(JSON.stringify(entries));
280 const entries = await SpecialPowers.spawn(browser, [JS_URL], task);
281 Assert.equal(entries[0].name, JS_URL);
282 Assert.equal(entries[1].name, JS_URL);
283 testFields(
284 entries[0],
286 hasBodyAccess: true,
287 hasTimingAccess: true,
289 "same origin (non-cached)"
291 testFields(
292 entries[1],
294 hasBodyAccess: true,
295 hasTimingAccess: true,
296 isCacheOf: entries[0],
298 "same origin (cached)"
301 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
303 const cacheEntries = await SpecialPowers.spawn(browser, [JS_URL], task);
304 Assert.equal(cacheEntries[0].name, JS_URL);
305 Assert.equal(cacheEntries[1].name, JS_URL);
306 testFields(
307 cacheEntries[0],
309 hasBodyAccess: true,
310 hasTimingAccess: true,
311 isCacheOf: entries[0],
313 "same origin (cached)"
315 testFields(
316 cacheEntries[1],
318 hasBodyAccess: true,
319 hasTimingAccess: true,
320 isCacheOf: entries[0],
322 "same origin (cached)"
328 add_task(async function testNoCacheReload() {
329 await SpecialPowers.pushPrefEnv({
330 set: [["dom.script_loader.navigation_cache", true]],
332 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
334 await clearAllCache();
336 await BrowserTestUtils.withNewTab(
338 gBrowser,
339 url: URL_BASE + "dummy.html",
341 async function (browser) {
342 const JS_URL = URL_BASE + "perf_server.sjs?";
344 const task = async url => {
345 await new Promise(resolve => {
346 const script = content.document.createElement("script");
347 script.src = url;
348 script.addEventListener("load", resolve);
349 content.document.head.append(script);
352 const entries = content.performance
353 .getEntriesByType("resource")
354 .filter(entry => entry.name.includes("perf_server.sjs"));
355 if (entries.length != 1) {
356 throw new Error(`Expect one entry, got ${entries.length} entries`);
358 return JSON.parse(JSON.stringify(entries[0]));
361 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
362 Assert.equal(entry.name, JS_URL);
363 testFields(
364 entry,
366 hasBodyAccess: true,
367 hasTimingAccess: true,
369 "same origin (non-cached)"
372 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
374 // Reloading the JS shouldn't hit any cache.
376 const reloadEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
377 Assert.equal(reloadEntry.name, JS_URL);
378 testFields(
379 reloadEntry,
381 hasBodyAccess: true,
382 hasTimingAccess: true,
384 "same origin (non-cached)"
390 add_task(async function test_NoCORS() {
391 await SpecialPowers.pushPrefEnv({
392 set: [["dom.script_loader.navigation_cache", true]],
394 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
396 await clearAllCache();
398 await BrowserTestUtils.withNewTab(
400 gBrowser,
401 url: URL_BASE + "dummy.html",
403 async function (browser) {
404 const JS_URL = URL_BASE2 + "perf_server.sjs?cacheable";
406 const task = async url => {
407 await new Promise(resolve => {
408 const script = content.document.createElement("script");
409 script.src = url;
410 script.addEventListener("load", resolve);
411 content.document.head.append(script);
414 const entries = content.performance
415 .getEntriesByType("resource")
416 .filter(entry => entry.name.includes("perf_server.sjs"));
417 if (entries.length != 1) {
418 throw new Error(`Expect one entry, got ${entries.length} entries`);
420 return JSON.parse(JSON.stringify(entries[0]));
423 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
424 Assert.equal(entry.name, JS_URL);
425 testFields(
426 entry,
428 hasBodyAccess: false,
429 hasTimingAccess: false,
431 "cross origin (non-cached)"
434 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
436 const cacheEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
437 Assert.equal(cacheEntry.name, JS_URL);
438 testFields(
439 cacheEntry,
441 hasBodyAccess: false,
442 hasTimingAccess: false,
443 isCacheOf: entry,
445 "cross origin (cached)"
451 add_task(async function test_NoCORS_TAO() {
452 await SpecialPowers.pushPrefEnv({
453 set: [["dom.script_loader.navigation_cache", true]],
455 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
457 await clearAllCache();
459 await BrowserTestUtils.withNewTab(
461 gBrowser,
462 url: URL_BASE + "dummy.html",
464 async function (browser) {
465 const JS_URL = URL_BASE2 + "perf_server.sjs?cacheable,tao";
467 const task = async url => {
468 await new Promise(resolve => {
469 const script = content.document.createElement("script");
470 script.src = url;
471 script.addEventListener("load", resolve);
472 content.document.head.append(script);
475 const entries = content.performance
476 .getEntriesByType("resource")
477 .filter(entry => entry.name.includes("perf_server.sjs"));
478 if (entries.length != 1) {
479 throw new Error(`Expect one entry, got ${entries.length} entries`);
481 return JSON.parse(JSON.stringify(entries[0]));
484 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
485 Assert.equal(entry.name, JS_URL);
486 testFields(
487 entry,
489 hasBodyAccess: false,
490 hasTimingAccess: true,
492 "cross origin with Timing-Allow-Origin (non-cached)"
495 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
497 const cacheEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
498 Assert.equal(cacheEntry.name, JS_URL);
499 testFields(
500 cacheEntry,
502 hasBodyAccess: false,
503 hasTimingAccess: true,
504 isCacheOf: entry,
506 "cross origin with Timing-Allow-Origin (cached)"
512 add_task(async function test_CORS() {
513 await SpecialPowers.pushPrefEnv({
514 set: [["dom.script_loader.navigation_cache", true]],
516 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
518 await clearAllCache();
520 await BrowserTestUtils.withNewTab(
522 gBrowser,
523 url: URL_BASE + "dummy.html",
525 async function (browser) {
526 const JS_URL = URL_BASE2 + "perf_server.sjs?cacheable,cors";
528 const task = async url => {
529 await new Promise(resolve => {
530 const script = content.document.createElement("script");
531 script.setAttribute("crossorigin", "anonymous");
532 script.src = url;
533 script.addEventListener("load", resolve);
534 content.document.head.append(script);
537 const entries = content.performance
538 .getEntriesByType("resource")
539 .filter(entry => entry.name.includes("perf_server.sjs"));
540 if (entries.length != 1) {
541 throw new Error(`Expect one entry, got ${entries.length} entries`);
543 return JSON.parse(JSON.stringify(entries[0]));
546 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
547 Assert.equal(entry.name, JS_URL);
548 testFields(
549 entry,
551 hasBodyAccess: true,
552 hasTimingAccess: false,
554 "CORS (non-cached)"
557 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
559 const cacheEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
560 Assert.equal(cacheEntry.name, JS_URL);
561 testFields(
562 cacheEntry,
564 hasBodyAccess: true,
565 hasTimingAccess: false,
566 isCacheOf: entry,
568 "CORS (cached)"
574 add_task(async function test_CORS_TAO() {
575 await SpecialPowers.pushPrefEnv({
576 set: [["dom.script_loader.navigation_cache", true]],
578 registerCleanupFunction(() => SpecialPowers.popPrefEnv());
580 await clearAllCache();
582 await BrowserTestUtils.withNewTab(
584 gBrowser,
585 url: URL_BASE + "dummy.html",
587 async function (browser) {
588 const JS_URL = URL_BASE2 + "perf_server.sjs?cacheable,cors,tao";
590 const task = async url => {
591 await new Promise(resolve => {
592 const script = content.document.createElement("script");
593 script.setAttribute("crossorigin", "anonymous");
594 script.src = url;
595 script.addEventListener("load", resolve);
596 content.document.head.append(script);
599 const entries = content.performance
600 .getEntriesByType("resource")
601 .filter(entry => entry.name.includes("perf_server.sjs"));
602 if (entries.length != 1) {
603 throw new Error(`Expect one entry, got ${entries.length} entries`);
605 return JSON.parse(JSON.stringify(entries[0]));
608 const entry = await SpecialPowers.spawn(browser, [JS_URL], task);
609 Assert.equal(entry.name, JS_URL);
610 testFields(
611 entry,
613 hasBodyAccess: true,
614 hasTimingAccess: true,
616 "CORS with Timing-Allow-Origin (non-cached)"
619 await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
621 const cacheEntry = await SpecialPowers.spawn(browser, [JS_URL], task);
622 Assert.equal(cacheEntry.name, JS_URL);
623 testFields(
624 cacheEntry,
626 hasBodyAccess: true,
627 hasTimingAccess: true,
628 isCacheOf: entry,
630 "CORS with Timing-Allow-Origin (cached)"