executor.sub.html (3998B)
1 <!DOCTYPE html> 2 <script src="/common/dispatcher/dispatcher.js" nonce="abc"></script> 3 <script src="/resources/testdriver.js"></script> 4 <script src="/resources/testdriver-vendor.js"></script> 5 <script src="/resources/testdriver-actions.js"></script> 6 <script src="utils.sub.js" nonce="abc"></script> 7 <script nonce="abc"> 8 // For a given string `str` that is escaped by WPT's `.sub.html` or 9 // `pipe=sub(html)` functionality, return the original unescaped string. 10 // 11 // Concretely, for `str` as the result of `html.escape(x, quote=True)`, 12 // return the original unescaped string `x`. 13 // See `/tools/wptserve/wptserve/pipes.py` and 14 // https://docs.python.org/3/library/html.html#html.escape. 15 // 16 // See https://crbug.com/404573971 for fixing the escaping issue. 17 function reverse_html_escape(str) { 18 str = str.replaceAll('<', '<'); 19 str = str.replaceAll('>', '>'); 20 str = str.replaceAll('"', '"'); 21 str = str.replaceAll(''', "'"); 22 str = str.replaceAll('&', '&'); 23 return str; 24 } 25 26 // To be consistent with https://fetch.spec.whatwg.org/#headers-class 27 // (accessed via iterable), 28 // - The keys are lower-cased header names, and 29 // - The entries are removed when the corresponding headers are non-existent. 30 window.requestHeaders = { 31 "purpose": "{{header_or_default(Purpose, NONEXISTENT)}}", 32 "sec-purpose": "{{header_or_default(Sec-Purpose, NONEXISTENT)}}", 33 "referer": "{{header_or_default(Referer, NONEXISTENT)}}", 34 "sec-fetch-dest": "{{header_or_default(Sec-Fetch-Dest, NONEXISTENT)}}", 35 "sec-fetch-mode": "{{header_or_default(Sec-Fetch-Mode, NONEXISTENT)}}", 36 "service-worker-navigation-preload": 37 "{{header_or_default(Service-Worker-Navigation-Preload, NONEXISTENT)}}", 38 // Convert to the raw string to avoid backslashes from being processed as 39 // escape sequences. 40 // TODO(crbug.com/404573971): Remove `header_or_default` to reflect 41 // `__no_tags__` properly. 42 sec_speculation_tags: 43 String.raw`{{header_or_default(Sec-Speculation-Tags, __no_tags__)}}`, 44 }; 45 Object.keys(requestHeaders).forEach(key => { 46 if (requestHeaders[key] === "NONEXISTENT") { 47 delete requestHeaders[key]; 48 } else { 49 requestHeaders[key] = reverse_html_escape(requestHeaders[key]); 50 } 51 }); 52 53 // Add a link to the page in order to use during the test 54 function add_link(id, url) { 55 const link_element = document.createElement("a"); 56 const link_text = document.createTextNode(url); 57 link_element.setAttribute("href", url); 58 link_element.setAttribute("id", id); 59 link_element.appendChild(link_text); 60 document.body.appendChild(link_element); 61 } 62 63 // "id" is the id of the link that we need to hover on in order 64 // to start the prefetch 65 async function start_non_immediate_prefetch_on_hover(id) { 66 let target = document.getElementById(id); 67 68 test_driver.set_test_context(window.opener); 69 // Inject the inputs to run this test. 70 await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0, {origin: target}).send(); 71 } 72 73 // "id" is the id of the link that we need to press on in order 74 // to start the prefetch 75 async function start_non_immediate_prefetch_on_pointerdown(id) { 76 let target = document.getElementById(id); 77 78 test_driver.set_test_context(window.opener); 79 // Inject the inputs to run this test. 80 // Move mouse pointer outside of the anchor so that we don't start the 81 // navigation before making sure the prefetch request started server-side. 82 await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0, {origin: target}).pointerDown().pointerMove(0, 0).pointerUp().send(); 83 } 84 85 async function navigate_by_form_generated_post(url) { 86 let form = document.createElement('form'); 87 form.method = 'POST'; 88 form.action = url; 89 document.body.appendChild(form); 90 form.submit(); 91 } 92 93 // The fetch request's URL sent to the server. 94 window.requestUrl = reverse_html_escape( 95 "{{location[server]}}{{location[path]}}{{location[query]}}"); 96 97 const uuid = new URLSearchParams(location.search).get('uuid'); 98 window.executor = new Executor(uuid); 99 </script>