redirects.html (4786B)
1 <!doctype html> 2 <title>TextFragment invoked on redirects</title> 3 <meta charset=utf-8> 4 <meta name="timeout" content="long"> 5 <link rel="help" href="https://wicg.github.io/ScrollToTextFragment/"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/resources/testdriver.js"></script> 9 <script src="/resources/testdriver-vendor.js"></script> 10 <script src="/common/get-host-info.sub.js"></script> 11 <script src="/common/utils.js"></script> 12 <script src="stash.js"></script> 13 14 <!--See comment in scroll-to-text-fragment.html for why these tests have the 15 structure they do. --> 16 <script> 17 // This test ensure correct operation of text-fragments through both HTTP and 18 // client side redirects in various scenarios. 19 20 // Constructs a URL to either redirect.py or the local client-redirect.html; 21 // which will cause an HTTP or client based redirect, respectively, to 22 // |to_url|. |type| provides a numeric 30x code to specify an HTTP redirect, 23 // "location" for a write to window.location, or "meta" for a <meta> refresh. 24 function buildRedirectUrl(to_url, type) { 25 let dest = ""; 26 to_url = encodeURIComponent(to_url); 27 28 if (typeof type == "number") { 29 // If the type is a number, it's an HTTP response code, use redirect.py to 30 // respond with an HTTP redirect. 31 const code = type; 32 dest = `${get_host_info().ORIGIN}/common/redirect.py?status=${code}&location=${to_url}`; 33 } else if (type == 'meta' || type == 'location') { 34 // Otherwise we're requesting a client-side redirect, either a <meta> tag 35 // or window.location. Use the client-redirect file to bounce to the 36 // destination. 37 dest = `client-redirect.html?${type}&${to_url}`; 38 } 39 return dest; 40 } 41 42 // Turns |path| from a relative-to-this-file path into a full URL. 43 function relativePathToFull(path) { 44 const pathname = window.location.toString(); 45 const base_path = pathname.substring(0, pathname.lastIndexOf('/') + 1); 46 return base_path + path; 47 } 48 49 const status_codes = [301, 302, 303, 307, 308]; 50 51 // Test that an HTTP redirect to a URL with a text fragment invokes the 52 // fragment. 53 for (let code of status_codes) { 54 promise_test(t => new Promise((resolve, reject) => { 55 let key = token(); 56 57 const abs_url = relativePathToFull(`redirects-target.html?key=${key}#:~:text=target`); 58 const url = buildRedirectUrl(abs_url, code); 59 60 test_driver.bless('Open a URL with a text fragment directive', () => { 61 window.open(url, '_blank', 'noopener'); 62 }); 63 64 fetchResults(key, resolve, reject); 65 }).then(data => { 66 assert_equals(data.scrolled, true); 67 }), `Text fragment works from HTTP ${code} redirect.`); 68 } 69 70 // Test that a URL with a text fragment that causes an HTTP redirect preserves 71 // the fragment and invokes it on the destination page. 72 for (let code of status_codes) { 73 promise_test(t => new Promise((resolve, reject) => { 74 let key = token(); 75 76 const abs_url = relativePathToFull(`redirects-target.html?key=${key}`); 77 const url = buildRedirectUrl(abs_url, code) + "#:~:text=target"; 78 79 test_driver.bless('Open a URL with a text fragment directive', () => { 80 window.open(url, '_blank', 'noopener'); 81 }); 82 83 fetchResults(key, resolve, reject); 84 }).then(data => { 85 assert_equals(data.scrolled, true); 86 }), `Text fragment propagated through HTTP ${code} redirect.`); 87 } 88 89 // Test that client-side redirects (using script) to a URL with a text fragment 90 // cause the text fragment to be invoked. 91 for (let type of ['location', 'meta']) { 92 promise_test(t => new Promise((resolve, reject) => { 93 let key = token(); 94 95 const to_url = `redirects-target.html?key=${key}#:~:text=target` 96 const url = buildRedirectUrl(to_url, type); 97 98 test_driver.bless('Open a URL with a text fragment directive', () => { 99 window.open(url, '_blank', 'noopener'); 100 }); 101 102 fetchResults(key, resolve, reject); 103 }).then(data => { 104 assert_equals(data.scrolled, true); 105 }), `Text fragment works on client-side ${type} redirect.`); 106 } 107 108 // Test that client-side redirects (using script) to a URL with a text fragment 109 // cause the text fragment to be invoked only the first time. A further 110 // redirect without a user gesture is blocked. 111 for (let type of ['location', 'meta']) { 112 promise_test(t => new Promise((resolve, reject) => { 113 let key = token(); 114 115 const to_url = `redirects-target.html?twice&key=${key}#:~:text=target` 116 const url = buildRedirectUrl(to_url, type); 117 118 test_driver.bless('Open a URL with a text fragment directive', () => { 119 window.open(url, '_blank', 'noopener'); 120 }); 121 122 fetchResults(key, resolve, reject); 123 }).then(data => { 124 assert_equals(data.scrolled, false); 125 }), `One text fragment per user gesture allowed in client-side ${type} redirect.`); 126 } 127 </script>