|  | <!DOCTYPE html> | 
|  | <meta charset=utf-8> | 
|  | <meta name="timeout" content="long"> | 
|  | <script src="/resources/testharness.js"></script> | 
|  | <script src="/resources/testharnessreport.js"></script> | 
|  | <script src="/common/get-host-info.sub.js"></script> | 
|  | <script src="/common/utils.js"></script> | 
|  | <script src="/common/dispatcher/dispatcher.js"></script> | 
|  | <!-- Pull in executor_path needed by newPopup / newIframe --> | 
|  | <script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script> | 
|  | <!-- Pull in importScript / newPopup / newIframe --> | 
|  | <script src="/html/anonymous-iframe/resources/common.js"></script> | 
|  | <body> | 
|  | <script> | 
|  |  | 
|  | const fetch_unsuccessful_response = "Fetch failed"; | 
|  | const fetch_successful_response = "Fetch succeeded"; | 
|  | const js_finished = "revoking blob_url js finished"; | 
|  |  | 
|  | // Fetches a previously revoked blob_url to see if the revoking was successful. | 
|  | async function fetch_contents_check(blob_url) { | 
|  | try { | 
|  | const blob = await fetch(blob_url).then(response => response.blob()); | 
|  | await blob.text(); | 
|  | } catch(e) { | 
|  | return fetch_unsuccessful_response; | 
|  | } | 
|  | return fetch_successful_response; | 
|  | } | 
|  |  | 
|  | const can_blob_url_be_revoked_js = (blob_url, response_queue_name) => ` | 
|  | async function test() { | 
|  | if (!('revokeObjectURL' in URL)) { | 
|  | return send("${response_queue_name}", "URL.revokeObjectURL is not exposed"); | 
|  | } | 
|  | try { | 
|  | URL.revokeObjectURL("${blob_url}"); | 
|  | } catch(e) { | 
|  | return send("${response_queue_name}", e.toString()); | 
|  | } | 
|  |  | 
|  | // Create, fetch, and revoke a separate blob URL to better ensure that the | 
|  | // revoke call above has had time to take effect before we return. | 
|  | const blob_1 = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url_1 = URL.createObjectURL(blob_1); | 
|  | await fetch(blob_url_1).then(response => response.blob()); | 
|  | URL.revokeObjectURL(blob_url_1); | 
|  |  | 
|  | return send("${response_queue_name}", "${js_finished}"); | 
|  | } | 
|  | await test(); | 
|  | `; | 
|  |  | 
|  | const can_blob_url_be_fetched_js = (blob_url, response_queue_name) => ` | 
|  | async function test() { | 
|  | try { | 
|  | const blob = await fetch("${blob_url}").then(response => response.blob()); | 
|  | await blob.text(); | 
|  | } catch(e) { | 
|  | return send("${response_queue_name}", "${fetch_unsuccessful_response}"); | 
|  | } | 
|  |  | 
|  | return send("${response_queue_name}", "${fetch_successful_response}"); | 
|  | } | 
|  | await test(); | 
|  | `; | 
|  |  | 
|  | const add_iframe_js = (iframe_origin, response_queue_uuid) => ` | 
|  | const importScript = ${importScript}; | 
|  | await importScript("/html/cross-origin-embedder-policy/credentialless" + | 
|  | "/resources/common.js"); | 
|  | await importScript("/html/anonymous-iframe/resources/common.js"); | 
|  | await importScript("/common/utils.js"); | 
|  |  | 
|  | // dispatcher.js has already been loaded by the popup this is running in. | 
|  | await send("${response_queue_uuid}", newIframe("${iframe_origin}")); | 
|  | `; | 
|  |  | 
|  | const same_site_origin = get_host_info().HTTPS_ORIGIN; | 
|  | const cross_site_origin = get_host_info().HTTPS_NOTSAMESITE_ORIGIN; | 
|  |  | 
|  | async function create_test_iframes(t, response_queue_uuid) { | 
|  | assert_equals("https://" + window.location.host, same_site_origin, | 
|  | "this test assumes that the page's window.location.host corresponds to " + | 
|  | "get_host_info().HTTPS_ORIGIN"); | 
|  |  | 
|  | // Create a same-origin iframe in a cross-site popup. | 
|  | const not_same_site_popup_uuid = newPopup(t, cross_site_origin); | 
|  | await send(not_same_site_popup_uuid, | 
|  | add_iframe_js(same_site_origin, response_queue_uuid)); | 
|  | const cross_site_iframe_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | // Create a same-origin iframe in a same-site popup. | 
|  | const same_origin_popup_uuid = newPopup(t, same_site_origin); | 
|  | await send(same_origin_popup_uuid, | 
|  | add_iframe_js(same_site_origin, response_queue_uuid)); | 
|  | const same_site_iframe_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | return [cross_site_iframe_uuid, same_site_iframe_uuid]; | 
|  | } | 
|  |  | 
|  | // Tests revoking blob URL for same and cross partition iframes. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | // Creates blob URL. | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  |  | 
|  | // Fetches blob URL to ensure that it's valid. | 
|  | const blob_fetch = await fetch_contents_check(blob_url); | 
|  | if (blob_fetch !== fetch_successful_response) { | 
|  | reject("Blob URL invalid"); | 
|  | } | 
|  |  | 
|  | // Creates same and cross partition iframes. | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Attempt to revoke blob URL in cross partition iframe. | 
|  | await send(cross_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== js_finished) { | 
|  | reject(response_1); | 
|  | } | 
|  | response_1 = await fetch_contents_check(blob_url); | 
|  | if (response_1 !== fetch_successful_response) { | 
|  | reject(`Blob URL was revoked in not-same-top-level-site iframe: ${response_1}`); | 
|  | } | 
|  |  | 
|  | // Attempt to revoke blob URL in same partition iframe. | 
|  | await send(same_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== js_finished) { | 
|  | reject(response_2); | 
|  | } | 
|  | response_2 = await fetch_contents_check(blob_url); | 
|  | if (response_2 !== fetch_unsuccessful_response) { | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  | reject(`Blob URL wasn't revoked in same-top-level-site iframe: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be revocable from a cross-partition iframe"); | 
|  |  | 
|  | const newWorker = (origin) => { | 
|  | const worker_token = token(); | 
|  | const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`; | 
|  | const worker = new Worker(worker_url); | 
|  | return worker_token; | 
|  | } | 
|  |  | 
|  | const create_dedicated_worker_js = (origin, response_queue_uuid) => ` | 
|  | const importScript = ${importScript}; | 
|  | await importScript("/html/cross-origin-embedder-policy/credentialless" + | 
|  | "/resources/common.js"); | 
|  | await importScript("/html/anonymous-iframe/resources/common.js"); | 
|  | await importScript("/common/utils.js"); | 
|  |  | 
|  | // dispatcher.js has already been loaded by the popup this is running in. | 
|  | const newWorker = ${newWorker}; | 
|  | await send("${response_queue_uuid}", newWorker("${origin}")); | 
|  | `; | 
|  |  | 
|  | // Tests revoking blob URL from same and cross partition dedicated worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_1_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_2_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  |  | 
|  | await send(worker_1_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== js_finished) { | 
|  | reject(response_1); | 
|  | } | 
|  | response_1 = await fetch_contents_check(blob_url); | 
|  | if (response_1 !== fetch_successful_response) { | 
|  | reject(`Blob URL was revoked in not-same-top-level-site dedicated worker: ${response_1}`); | 
|  | } | 
|  |  | 
|  | await send(worker_2_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== js_finished) { | 
|  | reject(response_2); | 
|  | } | 
|  | response_2 = await fetch_contents_check(blob_url); | 
|  | if (response_2 !== fetch_unsuccessful_response) { | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  | reject(`Blob URL wasn't revoked in same-top-level-site dedicated worker: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be revocable from a cross-partition dedicated worker"); | 
|  |  | 
|  | const newSharedWorker = (origin) => { | 
|  | const worker_token = token(); | 
|  | const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`; | 
|  | const worker = new SharedWorker(worker_url, worker_token); | 
|  | return worker_token; | 
|  | } | 
|  |  | 
|  | const create_shared_worker_js = (origin, response_queue_uuid) => ` | 
|  | const importScript = ${importScript}; | 
|  | await importScript("/html/cross-origin-embedder-policy/credentialless" + | 
|  | "/resources/common.js"); | 
|  | await importScript("/html/anonymous-iframe/resources/common.js"); | 
|  | await importScript("/common/utils.js"); | 
|  |  | 
|  | // dispatcher.js has already been loaded by the popup this is running in. | 
|  | const newSharedWorker = ${newSharedWorker}; | 
|  | await send("${response_queue_uuid}", newSharedWorker("${origin}")); | 
|  | `; | 
|  |  | 
|  | // Tests revoking blob URL from same and cross partition shared worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Create a shared worker in the cross-top-level-site iframe. | 
|  | await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_1_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | // Create a shared worker in the same-top-level-site iframe. | 
|  | await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_2_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  |  | 
|  | await send(worker_1_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== js_finished) { | 
|  | reject(response_1); | 
|  | } | 
|  | response_1 = await fetch_contents_check(blob_url); | 
|  | if (response_1 !== fetch_successful_response) { | 
|  | reject(`Blob URL was revoked in not-same-top-level-site shared worker: ${response_1}`); | 
|  | } | 
|  |  | 
|  | await send(worker_2_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== js_finished) { | 
|  | reject(response_2); | 
|  | } | 
|  | response_2 = await fetch_contents_check(blob_url); | 
|  | if (response_2 !== fetch_unsuccessful_response) { | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  | reject(`Blob URL wasn't revoked in same-top-level-site shared worker: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be revocable from a cross-partition shared worker"); | 
|  |  | 
|  | const newServiceWorker = async (origin) => { | 
|  | const worker_token = token(); | 
|  | const worker_url = origin + executor_service_worker_path + | 
|  | `&uuid=${worker_token}`; | 
|  | const worker_url_path = executor_service_worker_path.substring(0, | 
|  | executor_service_worker_path.lastIndexOf('/')); | 
|  | const scope = worker_url_path + "/not-used/"; | 
|  | const reg = await navigator.serviceWorker.register(worker_url, | 
|  | {'scope': scope}); | 
|  | return worker_token; | 
|  | } | 
|  |  | 
|  | const create_service_worker_js = (origin, response_queue_uuid) => ` | 
|  | const importScript = ${importScript}; | 
|  | await importScript("/html/cross-origin-embedder-policy/credentialless" + | 
|  | "/resources/common.js"); | 
|  | await importScript("/html/anonymous-iframe/resources/common.js"); | 
|  | await importScript("/common/utils.js"); | 
|  |  | 
|  | // dispatcher.js has already been loaded by the popup this is running in. | 
|  | const newServiceWorker = ${newServiceWorker}; | 
|  | await send("${response_queue_uuid}", await newServiceWorker("${origin}")); | 
|  | `; | 
|  |  | 
|  | // Tests revoking blob URL from a service worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Create a service worker in either iframe. | 
|  | await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid)); | 
|  | var worker_1_uuid = await receive(response_queue_uuid); | 
|  | t.add_cleanup(() => | 
|  | send(worker_1_uuid, "self.registration.unregister();")); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  |  | 
|  | await send(worker_1_uuid, | 
|  | can_blob_url_be_revoked_js(blob_url, response_queue_uuid)); | 
|  | const response = await receive(response_queue_uuid); | 
|  | if (response !== "URL.revokeObjectURL is not exposed") { | 
|  | reject(`URL.revokeObjectURL is exposed in a Service Worker context: ${response}`); | 
|  | } | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be revocable from a service worker"); | 
|  |  | 
|  | // Tests fetching blob URL for same and cross partition iframes. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | // Creates blob URL. | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  |  | 
|  | // Fetches blob URL to ensure that it's valid. | 
|  | const blob_fetch = await fetch_contents_check(blob_url); | 
|  | if (blob_fetch !== fetch_successful_response) { | 
|  | reject("Blob URL invalid"); | 
|  | } | 
|  |  | 
|  | // Creates same and cross partition iframes. | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Attempt to fetch blob URL in cross partition iframe. | 
|  | await send(cross_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== fetch_unsuccessful_response) { | 
|  | reject(`Blob URL was fetched in not-same-top-level-site iframe: ${response_1}`); | 
|  | } | 
|  |  | 
|  | // Attempt to fetch blob URL in same partition iframe. | 
|  | await send(same_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== fetch_successful_response) { | 
|  | reject(`Blob URL wasn't fetched in same-top-level-site iframe: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be fetched from a cross-partition iframe"); | 
|  |  | 
|  | // Tests fetching blob URL from same and cross partition dedicated worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | // Creates same and cross partition iframes. | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Creates a dedicated worker in the cross-top-level-site iframe. | 
|  | await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_1_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | // Creates a dedicated worker in the same-top-level-site iframe. | 
|  | await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_2_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  |  | 
|  | // Attempts to fetch in the cross-top-level-site dedicated worker. | 
|  | await send(worker_1_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== fetch_unsuccessful_response) { | 
|  | reject(`Blob URL was fetched in not-same-top-level-site dedicated worker: ${response_1}`); | 
|  | } | 
|  |  | 
|  | // Attempts to fetch in the same-top-level-site dedicated worker. | 
|  | await send(worker_2_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== fetch_successful_response) { | 
|  | reject(`Blob URL wasn't fetched in same-top-level-site dedicated worker: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be fetched from a cross-partition dedicated worker"); | 
|  |  | 
|  | // Tests fetching blob URL from same and cross partition shared worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | // Create a shared worker in the cross-top-level-site iframe. | 
|  | await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_1_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | // Create a shared worker in the same-top-level-site iframe. | 
|  | await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid)); | 
|  | const worker_2_uuid = await receive(response_queue_uuid); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  |  | 
|  | // Attempts to fetch in the cross-top-level-site shared worker. | 
|  | await send(worker_1_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== fetch_unsuccessful_response) { | 
|  | reject(`Blob URL was fetched in not-same-top-level-site shared worker: ${response_1}`); | 
|  | } | 
|  |  | 
|  | // Attempts to fetch in the same-top-level-site shared worker. | 
|  | await send(worker_2_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | var response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== fetch_successful_response) { | 
|  | reject(`Blob URL wasn't fetched in same-top-level-site shared worker: ${response_2}`); | 
|  | } | 
|  |  | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be fetched from a cross-partition shared worker"); | 
|  |  | 
|  | // Tests fetching blob URL from a cross partition service worker. | 
|  | promise_test(t => { | 
|  | return new Promise(async (resolve, reject) => { | 
|  | try { | 
|  | const response_queue_uuid = token(); | 
|  |  | 
|  | const [cross_site_iframe_uuid, same_site_iframe_uuid] = | 
|  | await create_test_iframes(t, response_queue_uuid); | 
|  |  | 
|  | const blob = new Blob(["blob data"], {type : "text/plain"}); | 
|  | const blob_url = window.URL.createObjectURL(blob); | 
|  | t.add_cleanup(() => window.URL.revokeObjectURL(blob_url)); | 
|  |  | 
|  | // Create a service worker in cross-top-level-site iframe. | 
|  | await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid)); | 
|  | var worker_1_uuid = await receive(response_queue_uuid); | 
|  | t.add_cleanup(() => | 
|  | send(worker_1_uuid, "self.registration.unregister();")); | 
|  |  | 
|  | await send(worker_1_uuid, | 
|  | can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | const response_1 = await receive(response_queue_uuid); | 
|  | if (response_1 !== fetch_unsuccessful_response) { | 
|  | reject(`Blob URL was fetched in not-same-top-level-site service worker: ${response_1}`); | 
|  | } | 
|  |  | 
|  | // Create a service worker in same-top-level-site iframe. | 
|  | await send(same_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid)); | 
|  | var worker_2_uuid = await receive(response_queue_uuid); | 
|  | t.add_cleanup(() => | 
|  | send(worker_2_uuid, "self.registration.unregister();")); | 
|  |  | 
|  | await send(worker_2_uuid, | 
|  | can_blob_url_be_fetched_js(blob_url, response_queue_uuid)); | 
|  | const response_2 = await receive(response_queue_uuid); | 
|  | if (response_2 !== fetch_successful_response) { | 
|  | reject(`Blob URL wasn't fetched in same-top-level-site service worker: ${response_2}`); | 
|  | } | 
|  | resolve(); | 
|  | } catch (e) { | 
|  | reject(e); | 
|  | } | 
|  | }); | 
|  | }, "Blob URL shouldn't be fetched from a cross-partition service worker"); | 
|  |  | 
|  | </script> | 
|  | </body> |