browser_newWindowDrop.js (6259B)
1 const { SearchTestUtils } = ChromeUtils.importESModule( 2 "resource://testing-common/SearchTestUtils.sys.mjs" 3 ); 4 5 SearchTestUtils.init(this); 6 7 add_task(async function test_setup() { 8 // Opening multiple windows on debug build takes too long time. 9 requestLongerTimeout(10); 10 11 // Stop search-engine loads from hitting the network 12 await SearchTestUtils.installSearchExtension( 13 { 14 name: "MozSearch", 15 search_url: "https://example.com/", 16 search_url_get_params: "q={searchTerms}", 17 }, 18 { setAsDefault: true } 19 ); 20 21 // Move New Window button to nav bar, to make it possible to drag and drop. 22 let { CustomizableUI } = ChromeUtils.importESModule( 23 "moz-src:///browser/components/customizableui/CustomizableUI.sys.mjs" 24 ); 25 let origPlacement = CustomizableUI.getPlacementOfWidget("new-window-button"); 26 if (!origPlacement || origPlacement.area != CustomizableUI.AREA_NAVBAR) { 27 CustomizableUI.addWidgetToArea( 28 "new-window-button", 29 CustomizableUI.AREA_NAVBAR, 30 0 31 ); 32 CustomizableUI.ensureWidgetPlacedInWindow("new-window-button", window); 33 registerCleanupFunction(function () { 34 CustomizableUI.removeWidgetFromArea("new-window-button"); 35 }); 36 } 37 38 CustomizableUI.addWidgetToArea("sidebar-button", "nav-bar"); 39 registerCleanupFunction(() => 40 CustomizableUI.removeWidgetFromArea("sidebar-button") 41 ); 42 }); 43 44 // New Window Button opens any link. 45 add_task(async function single_url() { 46 await dropText("mochi.test/first", ["http://mochi.test/first"]); 47 }); 48 add_task(async function single_javascript() { 49 await dropText("javascript:'bad'", ["about:blank"]); 50 }); 51 add_task(async function single_javascript_capital() { 52 await dropText("jAvascript:'bad'", ["about:blank"]); 53 }); 54 add_task(async function single_url2() { 55 await dropText("mochi.test/second", ["http://mochi.test/second"]); 56 }); 57 add_task(async function single_data_url() { 58 await dropText("data:text/html,bad", ["data:text/html,bad"]); 59 }); 60 add_task(async function single_url3() { 61 await dropText("mochi.test/third", ["http://mochi.test/third"]); 62 }); 63 64 // Single text/plain item, with multiple links. 65 add_task(async function multiple_urls() { 66 await dropText("mochi.test/1\nmochi.test/2", [ 67 "http://mochi.test/1", 68 "http://mochi.test/2", 69 ]); 70 }); 71 add_task(async function multiple_urls_javascript() { 72 await dropText("javascript:'bad1'\nmochi.test/3", [ 73 "about:blank", 74 "http://mochi.test/3", 75 ]); 76 }); 77 add_task(async function multiple_urls_data() { 78 await dropText("mochi.test/4\ndata:text/html,bad1", [ 79 "http://mochi.test/4", 80 "data:text/html,bad1", 81 ]); 82 }); 83 84 // Multiple text/plain items, with single and multiple links. 85 add_task(async function multiple_items_single_and_multiple_links() { 86 await drop( 87 [ 88 [{ type: "text/plain", data: "mochi.test/5" }], 89 [{ type: "text/plain", data: "mochi.test/6\nmochi.test/7" }], 90 ], 91 ["http://mochi.test/5", "http://mochi.test/6", "http://mochi.test/7"] 92 ); 93 }); 94 95 // Single text/x-moz-url item, with multiple links. 96 // "text/x-moz-url" has titles in even-numbered lines. 97 add_task(async function single_moz_url_multiple_links() { 98 await drop( 99 [ 100 [ 101 { 102 type: "text/x-moz-url", 103 data: "mochi.test/8\nTITLE8\nmochi.test/9\nTITLE9", 104 }, 105 ], 106 ], 107 ["http://mochi.test/8", "http://mochi.test/9"] 108 ); 109 }); 110 111 // Single item with multiple types. 112 add_task(async function single_item_multiple_types() { 113 await drop( 114 [ 115 [ 116 { type: "text/plain", data: "mochi.test/10" }, 117 { type: "text/x-moz-url", data: "mochi.test/11\nTITLE11" }, 118 ], 119 ], 120 ["http://mochi.test/11"] 121 ); 122 }); 123 124 // Warn when too many URLs are dropped. 125 add_task(async function multiple_tabs_under_max() { 126 let urls = []; 127 for (let i = 0; i < 5; i++) { 128 urls.push("mochi.test/multi" + i); 129 } 130 await dropText(urls.join("\n"), [ 131 "http://mochi.test/multi0", 132 "http://mochi.test/multi1", 133 "http://mochi.test/multi2", 134 "http://mochi.test/multi3", 135 "http://mochi.test/multi4", 136 ]); 137 }); 138 add_task(async function multiple_tabs_over_max_accept() { 139 await pushPrefs(["browser.tabs.maxOpenBeforeWarn", 4]); 140 141 let confirmPromise = BrowserTestUtils.promiseAlertDialog("accept"); 142 143 let urls = []; 144 for (let i = 0; i < 5; i++) { 145 urls.push("mochi.test/accept" + i); 146 } 147 await dropText( 148 urls.join("\n"), 149 [ 150 "http://mochi.test/accept0", 151 "http://mochi.test/accept1", 152 "http://mochi.test/accept2", 153 "http://mochi.test/accept3", 154 "http://mochi.test/accept4", 155 ], 156 true 157 ); 158 159 await confirmPromise; 160 161 await popPrefs(); 162 }); 163 add_task(async function multiple_tabs_over_max_cancel() { 164 await pushPrefs(["browser.tabs.maxOpenBeforeWarn", 4]); 165 166 let confirmPromise = BrowserTestUtils.promiseAlertDialog("cancel"); 167 168 let urls = []; 169 for (let i = 0; i < 5; i++) { 170 urls.push("mochi.test/cancel" + i); 171 } 172 await dropText(urls.join("\n"), [], true); 173 174 await confirmPromise; 175 176 await popPrefs(); 177 }); 178 179 function dropText(text, expectedURLs, ignoreFirstWindow = false) { 180 return drop( 181 [[{ type: "text/plain", data: text }]], 182 expectedURLs, 183 ignoreFirstWindow 184 ); 185 } 186 187 async function drop(dragData, expectedURLs) { 188 let dragDataString = JSON.stringify(dragData); 189 info( 190 `Starting test for dragData:${dragDataString}; expectedURLs.length:${expectedURLs.length}` 191 ); 192 193 // Since synthesizeDrop triggers the srcElement, need to use another button 194 // that should be visible. 195 let dragSrcElement = document.getElementById("sidebar-button"); 196 ok(dragSrcElement, "Sidebar button exists"); 197 let newWindowButton = document.getElementById("new-window-button"); 198 ok(newWindowButton, "New Window button exists"); 199 200 let awaitDrop = BrowserTestUtils.waitForEvent(newWindowButton, "drop"); 201 202 let loadedPromises = expectedURLs.map(url => 203 BrowserTestUtils.waitForNewWindow({ 204 url, 205 anyWindow: true, 206 maybeErrorPage: true, 207 }) 208 ); 209 210 EventUtils.synthesizeDrop( 211 dragSrcElement, 212 newWindowButton, 213 dragData, 214 "link", 215 window 216 ); 217 218 let windows = await Promise.all(loadedPromises); 219 for (let window of windows) { 220 await BrowserTestUtils.closeWindow(window); 221 } 222 223 await awaitDrop; 224 ok(true, "Got drop event"); 225 }