window-open-noopener.html (5085B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>window.open() with "noopener" tests</title> 4 5 <meta name="variant" content="?indexed"> 6 <meta name="variant" content="?_self"> 7 <meta name="variant" content="?_parent"> 8 <meta name="variant" content="?_top"> 9 <meta name=timeout content=long> 10 11 <script src=/resources/testharness.js></script> 12 <script src=/resources/testharnessreport.js></script> 13 <script> 14 var testData = [ 15 { testDescription: "window.open() with 'noopener' should reuse existing target", 16 secondWindowFeatureString: "noopener", 17 shouldReturnWindow: false }, 18 { testDescription: "noopener=1 means the same as noopener", 19 secondWindowFeatureString: "noopener=1", 20 shouldReturnWindow: false }, 21 { testDescription: "noopener=true means the same as noopener", 22 secondWindowFeatureString: "noopener=true", 23 shouldReturnWindow: false }, 24 { testDescription: "noopener=0 means lack of noopener", 25 secondWindowFeatureString: "noopener=0", 26 shouldReturnWindow: true }, 27 { testDescription: "noopener separated only by spaces should work", 28 secondWindowFeatureString: "make me noopener", 29 shouldReturnWindow: false }, 30 { testDescription: "Trailing noopener should work", 31 secondWindowFeatureString: "abc def, \n\r noopener", 32 shouldReturnWindow: false }, 33 { testDescription: "Leading noopener should work", 34 secondWindowFeatureString: "noopener \f\t , hey, there", 35 shouldReturnWindow: false }, 36 { testDescription: "Interior noopener should work", 37 secondWindowFeatureString: "and now, noopener , hey, there", 38 shouldReturnWindow: false }, 39 { testDescription: "noreferrer should also suppress opener when reusing existing target", 40 secondWindowFeatureString: "noreferrer", 41 shouldReturnWindow: false }, 42 ]; 43 44 /** 45 * Loop over our testData array and kick off an async test for each entry. Each 46 * async test opens a window using window.open() with some per-test unique name, 47 * then tries to do a second window.open() call with the same name and the 48 * test-specific feature string. It then checks whether that second 49 * window.open() call reuses the existing window, whether the return value of 50 * the second window.open() call is correct (it should be null in the noopener 51 * cases and non-null in the cases when the existing window gets reused) and so 52 * forth. 53 */ 54 function indexedTests() { 55 var tests = []; 56 for(var i = 0; i < testData.length; ++i) { 57 var test = testData[i]; 58 var t = async_test(test.testDescription); 59 tests.push(t); 60 t.secondWindowFeatureString = test.secondWindowFeatureString; 61 t.windowName = "someuniquename" + i; 62 63 if (test.shouldReturnWindow) { 64 t.step(function() { 65 var windowName = this.windowName; 66 67 var w1 = window.open("", windowName); 68 this.add_cleanup(function() { w1.close(); }); 69 70 assert_equals(w1.opener, window); 71 72 var w2 = window.open("", windowName, this.secondWindowFeatureString); 73 assert_equals(w2, w1); 74 assert_equals(w2.opener, w1.opener); 75 assert_equals(w2.opener, window); 76 this.done(); 77 }); 78 } else { 79 t.step(function() { 80 var w1; 81 this.add_cleanup(function() { 82 w1.close(); 83 channel.postMessage(null); 84 }); 85 86 var windowName = this.windowName; 87 var channel = new BroadcastChannel(windowName); 88 89 channel.onmessage = this.step_func_done(function(e) { 90 var data = e.data; 91 assert_equals(data.name, windowName, "Should have the right name"); 92 assert_equals(data.haveOpener, true, "Should still have opener"); 93 assert_equals(w1.opener, window); 94 assert_not_equals(w1.location.href, "about:blank", "Should have navigated"); 95 }); 96 97 w1 = window.open("", windowName); 98 assert_equals(w1.opener, window); 99 100 var w2 = window.open("support/noopener-target.html?" + windowName, 101 windowName, this.secondWindowFeatureString); 102 assert_equals(w2, null); 103 104 assert_equals(w1.opener, window); 105 }); 106 } 107 } 108 } 109 110 /** 111 * Loop over the special targets that ignore noopener and check that doing a 112 * window.open() with those targets correctly reuses the existing window. 113 */ 114 function specialTargetTest(target) { 115 if (["_self", "_parent", "_top"].includes(target)) { 116 var t = async_test("noopener window.open targeting " + target); 117 t.openedWindow = window.open(`javascript:var w2 = window.open("", "${target}", "noopener"); this.checkValues(w2); this.close(); void(0);`); 118 assert_equals(t.openedWindow.opener, window); 119 t.openedWindow.checkValues = t.step_func_done(function(win) { 120 assert_equals(win, this.openedWindow); 121 }); 122 } else { 123 throw 'testError: special target must be one of: _self, _parent, _top' 124 } 125 } 126 127 /** 128 * Parse the Query string, check if it matches keyword 'indexed' to run the indexed tests, 129 * otherwise test it as a special target 130 */ 131 var variant = window.location.href.split("?")[1] 132 if(variant == "indexed") { 133 indexedTests(); 134 } else { 135 specialTargetTest(variant); 136 } 137 </script>