util.js (6574B)
1 // META: script=/common/utils.js 2 // META: script=/fenced-frame/resources/utils.js 3 'use strict'; 4 5 async function IsSharedStorageSelectUrlAllowed() { 6 let allowed = true; 7 try { 8 await sharedStorage.selectURL("operation", [{url: "1.html"}]); 9 } catch (e) { 10 allowed = false; 11 } 12 13 return allowed; 14 } 15 16 // Execute all shared storage methods (excluding createWorklet). 17 // and capture their errors. Return true if all methods succeed. 18 async function AreRegularSharedStorageMethodsAllowed() { 19 let deniedCount = 0; 20 21 try { 22 await window.sharedStorage.worklet.addModule('/shared-storage/resources/simple-module.js'); 23 } catch (e) { 24 ++deniedCount; 25 } 26 27 try { 28 await window.sharedStorage.run('operation', {keepAlive: true}); 29 } catch (e) { 30 ++deniedCount; 31 } 32 33 try { 34 await sharedStorage.selectURL("operation", [{url: "1.html"}], {keepAlive: true}); 35 } catch (e) { 36 ++deniedCount; 37 } 38 39 try { 40 await window.sharedStorage.set('a', 'b'); 41 } catch (e) { 42 ++deniedCount; 43 } 44 45 try { 46 await window.sharedStorage.append('a', 'b'); 47 } catch (e) { 48 ++deniedCount; 49 } 50 51 try { 52 await window.sharedStorage.clear(); 53 } catch (e) { 54 ++deniedCount; 55 } 56 57 try { 58 await window.sharedStorage.delete('a'); 59 } catch (e) { 60 ++deniedCount; 61 } 62 63 if (deniedCount === 0) 64 return true; 65 66 return false; 67 } 68 69 // Run sharedStorage.worklet.addModule once. 70 // @param {string} module - The URL to the module. 71 async function addModuleOnce(module) { 72 try { 73 await sharedStorage.worklet.addModule(module); 74 } catch (e) { 75 // Shared Storage needs to have a module added before we can operate on it. 76 // It is generated on the fly with this call, and since there's no way to 77 // tell through the API if a module already exists, wrap the addModule call 78 // in a try/catch so that if it runs a second time in a test, it will 79 // gracefully fail rather than bring the whole test down. 80 } 81 } 82 83 // Validate the type of the result of sharedStorage.worklet.selectURL. 84 // @param result - The result of sharedStorage.worklet.selectURL. 85 // @param {boolean} - Whether sharedStorage.worklet.selectURL is resolved to 86 // a fenced frame config (true) or an urn:uuid (false). 87 // @return {boolean} Whether sharedStorage.worklet.selectURL returns an expected 88 // result type or not. 89 function validateSelectURLResult(result, resolve_to_config) { 90 if (resolve_to_config) { 91 return result instanceof FencedFrameConfig; 92 } 93 94 return result.startsWith('urn:uuid:'); 95 } 96 97 function updateUrlToUseNewOrigin(url, newOriginString) { 98 const origin = url.origin; 99 return new URL(url.toString().replace(origin, newOriginString)); 100 } 101 102 function appendExpectedKeyAndValue(url, expectedKey, expectedValue) { 103 url.searchParams.append('expectedKey', expectedKey); 104 url.searchParams.append('expectedValue', expectedValue); 105 return url; 106 } 107 108 function parseExpectedKeyAndValueData() { 109 const url = new URL(location.href); 110 const key = url.searchParams.get('expectedKey'); 111 const value = url.searchParams.get('expectedValue'); 112 return {'expectedKey': key, 'expectedValue': value}; 113 } 114 115 function appendExpectedKey(url, expectedKey) { 116 url.searchParams.append('expectedKey', expectedKey); 117 return url; 118 } 119 120 function parseExpectedKeyData() { 121 const url = new URL(location.href); 122 const key = url.searchParams.get('expectedKey'); 123 return {'expectedKey': key}; 124 } 125 126 async function verifyKeyValueForOrigin(key, value, origin) { 127 const outerKey = token(); 128 const innerKey = token(); 129 let iframeUrl = generateURL( 130 '/shared-storage/resources/verify-key-value.https.html', 131 [outerKey, innerKey]); 132 iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin); 133 iframeUrl = appendExpectedKeyAndValue(iframeUrl, key, value); 134 135 attachIFrame(iframeUrl); 136 const result = await nextValueFromServer(outerKey); 137 assert_equals(result, 'verify_key_value_loaded'); 138 } 139 140 async function verifyKeyNotFoundForOrigin(key, origin) { 141 const outerKey = token(); 142 const innerKey = token(); 143 let iframeUrl = generateURL( 144 '/shared-storage/resources/verify-key-not-found.https.html', 145 [outerKey, innerKey]); 146 iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin); 147 iframeUrl = appendExpectedKey(iframeUrl, key); 148 149 attachIFrame(iframeUrl); 150 const result = await nextValueFromServer(outerKey); 151 assert_equals(result, 'verify_key_not_found_loaded'); 152 } 153 154 async function setKeyValueForOrigin(key, value, origin) { 155 const outerKey = token(); 156 let setIframeUrl = generateURL( 157 '/shared-storage/resources/set-key-value.https.html', [outerKey]); 158 setIframeUrl = updateUrlToUseNewOrigin(setIframeUrl, origin); 159 setIframeUrl = appendExpectedKeyAndValue(setIframeUrl, key, value); 160 161 attachIFrame(setIframeUrl); 162 const result = await nextValueFromServer(outerKey); 163 assert_equals(result, 'set_key_value_loaded'); 164 } 165 166 async function deleteKeyForOrigin(key, origin) { 167 const outerKey = token(); 168 let deleteIframeUrl = generateURL( 169 '/shared-storage/resources/delete-key.https.html', [outerKey]); 170 deleteIframeUrl = updateUrlToUseNewOrigin(deleteIframeUrl, origin); 171 deleteIframeUrl = appendExpectedKey(deleteIframeUrl, key); 172 173 attachIFrame(deleteIframeUrl); 174 const result = await nextValueFromServer(outerKey); 175 assert_equals(result, 'delete_key_loaded'); 176 } 177 178 function getFetchedUrls(worker) { 179 return new Promise(function(resolve) { 180 var channel = new MessageChannel(); 181 channel.port1.onmessage = function(msg) { 182 resolve(msg); 183 }; 184 worker.postMessage({port: channel.port2}, [channel.port2]); 185 }); 186 } 187 188 function checkInterceptedUrls(worker, expectedRequests) { 189 return getFetchedUrls(worker).then(function(msg) { 190 let actualRequests = msg.data.requests; 191 assert_equals(actualRequests.length, expectedRequests.length); 192 assert_equals( 193 JSON.stringify(actualRequests), JSON.stringify(expectedRequests)); 194 }); 195 } 196 197 function attachIFrameWithEventListenerForSelectURLStatus(url) { 198 const frame = document.createElement('iframe'); 199 frame.src = url; 200 201 const promise = new Promise((resolve, reject) => { 202 window.addEventListener('message', async function handler(evt) { 203 if (evt.source === frame.contentWindow && evt.data.selectURLStatus) { 204 document.body.removeChild(frame); 205 window.removeEventListener('message', handler); 206 if (evt.data.selectURLStatus === 'success') { 207 resolve(evt.data); 208 } else { 209 reject(new Error(JSON.stringify(evt.data))); 210 } 211 } 212 }); 213 }); 214 215 document.body.appendChild(frame); 216 return promise; 217 }