1 async
function clearAllCache() {
2 await
new Promise(function (resolve
) {
3 Services
.clearData
.deleteData(
4 Ci
.nsIClearDataService
.CLEAR_ALL_CACHES
,
10 const URL_BASE
= "https://example.com/browser/dom/tests/browser/";
11 const URL_BASE2
= "https://example.net/browser/dom/tests/browser/";
15 { hasBodyAccess
, hasTimingAccess
, isCacheOf
},
18 Assert
.equal(entry
.entryType
, "resource", "entryType should be available");
22 "initiatorType should be available"
25 if (hasTimingAccess
) {
27 entry
.nextHopProtocol
,
29 `nextHopProtocol should be available for ${desc}`
33 entry
.nextHopProtocol
,
35 `nextHopProtocol should be hidden for ${desc}`
43 `responseStatus should be available for ${desc}`
49 `responseStatus should be hidden for ${desc}`
57 `contentType should be available for ${desc}`
63 `contentType should be hidden for ${desc}`
70 `startTime should be non-zero for ${desc}`
75 `responseEnd should be non-zero for ${desc}`
80 `startTime <= responseEnd for ${desc}`
83 if (hasTimingAccess
) {
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}`
97 `serverTiming should be hidden for ${desc}`
103 entry
.encodedBodySize
,
105 `encodedBodySize should be available for ${desc}`
109 entry
.encodedBodySize
,
111 `encodedBodySize should be hidden for ${desc}`
117 entry
.encodedBodySize
,
118 isCacheOf
.encodedBodySize
,
119 `encodedBodySize should equal to non-cache case for ${desc}`
125 entry
.decodedBodySize
,
127 `decodedBodySize should be available for ${desc}`
131 entry
.decodedBodySize
,
133 `decodedBodySize should be hidden for ${desc}`
139 entry
.decodedBodySize
,
140 isCacheOf
.decodedBodySize
,
141 `decodedBodySize should equal to non-cache case for ${desc}`
145 if (hasTimingAccess
) {
150 `transferSize should be zero for ${desc}`
152 } else if (hasBodyAccess
) {
156 `transferSize should be non-zero +300 for ${desc}`
162 `transferSize should be zero +300 for ${desc}`
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(
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");
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
);
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
);
227 hasTimingAccess
: true,
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(
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
=> {
254 // * The first load is not cache
255 // * The second load is complete cache
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");
263 script
.addEventListener("load", () => {
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
);
287 hasTimingAccess
: true,
289 "same origin (non-cached)"
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
);
310 hasTimingAccess
: true,
311 isCacheOf
: entries
[0],
313 "same origin (cached)"
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(
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");
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
);
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
);
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(
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");
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
);
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
);
441 hasBodyAccess
: false,
442 hasTimingAccess
: false,
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(
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");
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
);
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
);
502 hasBodyAccess
: false,
503 hasTimingAccess
: true,
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(
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");
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
);
552 hasTimingAccess
: false,
557 await BrowserTestUtils
.reloadTab(gBrowser
.selectedTab
);
559 const cacheEntry
= await SpecialPowers
.spawn(browser
, [JS_URL
], task
);
560 Assert
.equal(cacheEntry
.name
, JS_URL
);
565 hasTimingAccess
: false,
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(
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");
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
);
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
);
627 hasTimingAccess
: true,
630 "CORS with Timing-Allow-Origin (cached)"