browser_storage_dfpi.js (5791B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // Basic test to assert that the storage tree and table corresponding to each 6 // item in the storage tree is correctly displayed 7 8 "use strict"; 9 10 const { SiteDataTestUtils } = ChromeUtils.importESModule( 11 "resource://testing-common/SiteDataTestUtils.sys.mjs" 12 ); 13 14 // Ensure iframe.src in storage-dfpi.html starts with PREFIX. 15 const PREFIX = "https://sub1.test1.example"; 16 const ORIGIN = `${PREFIX}.org`; 17 const ORIGIN_THIRD_PARTY = `${PREFIX}.com`; 18 const ORIGIN_PARTITIONED = `${PREFIX}.com^partitionKey=%28https%2Cexample.org%29`; 19 const TEST_URL = `${ORIGIN}/document-builder.sjs?html= 20 <iframe src="${PREFIX}.com/browser/devtools/client/storage/test/storage-blank.html"></iframe> 21 `; 22 23 function listOrigins() { 24 return new Promise(resolve => { 25 SpecialPowers.Services.qms.listOrigins().callback = req => { 26 resolve(req.result); 27 }; 28 }); 29 } 30 31 add_task(async function () { 32 await pushPref( 33 "network.cookie.cookieBehavior", 34 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN 35 ); 36 37 registerCleanupFunction(SiteDataTestUtils.clear); 38 39 const expectedOrigins = [ORIGIN, ORIGIN_PARTITIONED]; 40 41 // `Services.qms.listOrigins()` may or contain results created by other tests. 42 // And it's unsafe to clear existing origins by `Services.qms.clear()`. 43 // In order to obtain correct results, we need to compare the results before 44 // and after `openTabAndSetupStorage` is called. 45 // To ensure more accurate results, try choosing a uncommon origin for PREFIX. 46 const EXISTING_ORIGINS = await listOrigins(); 47 expectedOrigins.forEach(expected => { 48 ok(!EXISTING_ORIGINS.includes(expected), `${expected} doesn't exist`); 49 }); 50 51 await openTabAndSetupStorage(TEST_URL); 52 53 const origins = await listOrigins(); 54 for (const origin of origins) { 55 ok( 56 EXISTING_ORIGINS.includes(origin) || expectedOrigins.includes(origin), 57 `check origin: ${origin}` 58 ); 59 } 60 expectedOrigins.forEach(expected => { 61 ok(origins.includes(expected), `${expected} is added`); 62 }); 63 64 BrowserTestUtils.removeTab(gBrowser.selectedTab); 65 }); 66 67 async function setPartitionedStorage(browser, type, key) { 68 const handler = async (storageType, storageKey, storageValue) => { 69 if (storageType == "cookie") { 70 content.document.cookie = `${storageKey}=${storageValue}`; 71 return; 72 } 73 content.localStorage.setItem(storageKey, storageValue); 74 }; 75 76 const thirdPartyHandler = async (storageType, storageKey, storageValue) => { 77 if (storageType == "cookie") { 78 content.document.cookie = `${storageKey}=${storageValue}; SameSite=None; Secure; Partitioned;`; 79 return; 80 } 81 content.localStorage.setItem(storageKey, storageValue); 82 }; 83 84 // Set first party storage. 85 await SpecialPowers.spawn(browser, [type, key, "first"], handler); 86 // Set third-party (partitioned) storage in the iframe. 87 await SpecialPowers.spawn( 88 browser.browsingContext.children[0], 89 [type, key, "third"], 90 thirdPartyHandler 91 ); 92 } 93 94 async function checkData(storageType, key, value) { 95 if (storageType == "cookie") { 96 checkCookieData(key, value); 97 return; 98 } 99 await waitForStorageData(key, value); 100 } 101 102 async function testPartitionedStorage( 103 storageType, 104 treeItemLabel = storageType 105 ) { 106 await pushPref( 107 "network.cookie.cookieBehavior", 108 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN 109 ); 110 // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default" 111 await pushPref("network.cookie.sameSite.laxByDefault", false); 112 113 info( 114 "Open the test url in a new tab and add storage entries *before* opening the storage panel." 115 ); 116 await BrowserTestUtils.withNewTab(TEST_URL, async browser => { 117 await setPartitionedStorage(browser, storageType, "contextA"); 118 }); 119 120 await openTabAndSetupStorage(TEST_URL); 121 122 const doc = gPanelWindow.document; 123 124 info("check that both hosts appear in the storage tree"); 125 checkTree(doc, [treeItemLabel, ORIGIN]); 126 checkTree(doc, [treeItemLabel, ORIGIN_THIRD_PARTY]); 127 128 info( 129 "check that items for both first and third party host have the initial storage entries" 130 ); 131 132 await selectTreeItem([treeItemLabel, ORIGIN]); 133 await checkData(storageType, "contextA", "first"); 134 135 await selectTreeItem([treeItemLabel, ORIGIN_THIRD_PARTY]); 136 await checkData(storageType, "contextA", "third"); 137 138 info("Add more entries while the storage panel is open"); 139 const onUpdated = gUI.once("store-objects-edit"); 140 await setPartitionedStorage( 141 gBrowser.selectedBrowser, 142 storageType, 143 "contextB" 144 ); 145 await onUpdated; 146 147 info("check that both hosts appear in the storage tree"); 148 checkTree(doc, [treeItemLabel, ORIGIN]); 149 checkTree(doc, [treeItemLabel, ORIGIN_THIRD_PARTY]); 150 151 info( 152 "check that items for both first and third party host have the updated storage entries" 153 ); 154 155 await selectTreeItem([treeItemLabel, ORIGIN]); 156 await checkData(storageType, "contextA", "first"); 157 await checkData(storageType, "contextB", "first"); 158 159 await selectTreeItem([treeItemLabel, ORIGIN_THIRD_PARTY]); 160 await checkData(storageType, "contextA", "third"); 161 await checkData(storageType, "contextB", "third"); 162 163 BrowserTestUtils.removeTab(gBrowser.selectedTab); 164 } 165 166 // Tests that partitioned storage is shown in the storage panel. 167 168 add_task(async function test_partitioned_cookies() { 169 registerCleanupFunction(SiteDataTestUtils.clear); 170 await testPartitionedStorage("cookie", "cookies"); 171 }); 172 173 add_task(async function test_partitioned_localStorage() { 174 registerCleanupFunction(SiteDataTestUtils.clear); 175 await testPartitionedStorage("localStorage"); 176 });