| // META: script=/common/utils.js |
| // META: script=/fenced-frame/resources/utils.js |
| 'use strict'; |
| |
| async function IsSharedStorageSelectUrlAllowed() { |
| let allowed = true; |
| try { |
| await sharedStorage.selectURL("operation", [{url: "1.html"}]); |
| } catch (e) { |
| allowed = false; |
| } |
| |
| return allowed; |
| } |
| |
| // Execute all shared storage methods (excluding createWorklet). |
| // and capture their errors. Return true if all methods succeed. |
| async function AreRegularSharedStorageMethodsAllowed() { |
| let deniedCount = 0; |
| |
| try { |
| await window.sharedStorage.worklet.addModule('/shared-storage/resources/simple-module.js'); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await window.sharedStorage.run('operation', {keepAlive: true}); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await sharedStorage.selectURL("operation", [{url: "1.html"}], {keepAlive: true}); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await window.sharedStorage.set('a', 'b'); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await window.sharedStorage.append('a', 'b'); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await window.sharedStorage.clear(); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| try { |
| await window.sharedStorage.delete('a'); |
| } catch (e) { |
| ++deniedCount; |
| } |
| |
| if (deniedCount === 0) |
| return true; |
| |
| return false; |
| } |
| |
| // Run sharedStorage.worklet.addModule once. |
| // @param {string} module - The URL to the module. |
| async function addModuleOnce(module) { |
| try { |
| await sharedStorage.worklet.addModule(module); |
| } catch (e) { |
| // Shared Storage needs to have a module added before we can operate on it. |
| // It is generated on the fly with this call, and since there's no way to |
| // tell through the API if a module already exists, wrap the addModule call |
| // in a try/catch so that if it runs a second time in a test, it will |
| // gracefully fail rather than bring the whole test down. |
| } |
| } |
| |
| // Validate the type of the result of sharedStorage.worklet.selectURL. |
| // @param result - The result of sharedStorage.worklet.selectURL. |
| // @param {boolean} - Whether sharedStorage.worklet.selectURL is resolved to |
| // a fenced frame config (true) or an urn:uuid (false). |
| // @return {boolean} Whether sharedStorage.worklet.selectURL returns an expected |
| // result type or not. |
| function validateSelectURLResult(result, resolve_to_config) { |
| if (resolve_to_config) { |
| return result instanceof FencedFrameConfig; |
| } |
| |
| return result.startsWith('urn:uuid:'); |
| } |
| |
| function updateUrlToUseNewOrigin(url, newOriginString) { |
| const origin = url.origin; |
| return new URL(url.toString().replace(origin, newOriginString)); |
| } |
| |
| function appendExpectedKeyAndValue(url, expectedKey, expectedValue) { |
| url.searchParams.append('expectedKey', expectedKey); |
| url.searchParams.append('expectedValue', expectedValue); |
| return url; |
| } |
| |
| function parseExpectedKeyAndValueData() { |
| const url = new URL(location.href); |
| const key = url.searchParams.get('expectedKey'); |
| const value = url.searchParams.get('expectedValue'); |
| return {'expectedKey': key, 'expectedValue': value}; |
| } |
| |
| function appendExpectedKey(url, expectedKey) { |
| url.searchParams.append('expectedKey', expectedKey); |
| return url; |
| } |
| |
| function parseExpectedKeyData() { |
| const url = new URL(location.href); |
| const key = url.searchParams.get('expectedKey'); |
| return {'expectedKey': key}; |
| } |
| |
| async function verifyKeyValueForOrigin(key, value, origin) { |
| const outerKey = token(); |
| const innerKey = token(); |
| let iframeUrl = generateURL( |
| '/shared-storage/resources/verify-key-value.https.html', |
| [outerKey, innerKey]); |
| iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin); |
| iframeUrl = appendExpectedKeyAndValue(iframeUrl, key, value); |
| |
| attachIFrame(iframeUrl); |
| const result = await nextValueFromServer(outerKey); |
| assert_equals(result, 'verify_key_value_loaded'); |
| } |
| |
| async function verifyKeyNotFoundForOrigin(key, origin) { |
| const outerKey = token(); |
| const innerKey = token(); |
| let iframeUrl = generateURL( |
| '/shared-storage/resources/verify-key-not-found.https.html', |
| [outerKey, innerKey]); |
| iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin); |
| iframeUrl = appendExpectedKey(iframeUrl, key); |
| |
| attachIFrame(iframeUrl); |
| const result = await nextValueFromServer(outerKey); |
| assert_equals(result, 'verify_key_not_found_loaded'); |
| } |
| |
| async function setKeyValueForOrigin(key, value, origin) { |
| const outerKey = token(); |
| let setIframeUrl = generateURL( |
| '/shared-storage/resources/set-key-value.https.html', [outerKey]); |
| setIframeUrl = updateUrlToUseNewOrigin(setIframeUrl, origin); |
| setIframeUrl = appendExpectedKeyAndValue(setIframeUrl, key, value); |
| |
| attachIFrame(setIframeUrl); |
| const result = await nextValueFromServer(outerKey); |
| assert_equals(result, 'set_key_value_loaded'); |
| } |
| |
| async function deleteKeyForOrigin(key, origin) { |
| const outerKey = token(); |
| let deleteIframeUrl = generateURL( |
| '/shared-storage/resources/delete-key.https.html', [outerKey]); |
| deleteIframeUrl = updateUrlToUseNewOrigin(deleteIframeUrl, origin); |
| deleteIframeUrl = appendExpectedKey(deleteIframeUrl, key); |
| |
| attachIFrame(deleteIframeUrl); |
| const result = await nextValueFromServer(outerKey); |
| assert_equals(result, 'delete_key_loaded'); |
| } |
| |
| function getFetchedUrls(worker) { |
| return new Promise(function(resolve) { |
| var channel = new MessageChannel(); |
| channel.port1.onmessage = function(msg) { |
| resolve(msg); |
| }; |
| worker.postMessage({port: channel.port2}, [channel.port2]); |
| }); |
| } |
| |
| function checkInterceptedUrls(worker, expectedRequests) { |
| return getFetchedUrls(worker).then(function(msg) { |
| let actualRequests = msg.data.requests; |
| assert_equals(actualRequests.length, expectedRequests.length); |
| assert_equals( |
| JSON.stringify(actualRequests), JSON.stringify(expectedRequests)); |
| }); |
| } |
| |
| function attachIFrameWithEventListenerForSelectURLStatus(url) { |
| const frame = document.createElement('iframe'); |
| frame.src = url; |
| |
| const promise = new Promise((resolve, reject) => { |
| window.addEventListener('message', async function handler(evt) { |
| if (evt.source === frame.contentWindow && evt.data.selectURLStatus) { |
| document.body.removeChild(frame); |
| window.removeEventListener('message', handler); |
| if (evt.data.selectURLStatus === 'success') { |
| resolve(evt.data); |
| } else { |
| reject(new Error(JSON.stringify(evt.data))); |
| } |
| } |
| }); |
| }); |
| |
| document.body.appendChild(frame); |
| return promise; |
| } |