browser_dbg_listtabs-02.js (6632B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Make sure the root actor's live tab list implementation works as specified. 8 */ 9 10 var { 11 BrowserTabList, 12 } = require("resource://devtools/server/actors/webbrowser.js"); 13 var { 14 DevToolsServer, 15 } = require("resource://devtools/server/devtools-server.js"); 16 17 var gTestPage = 18 "data:text/html;charset=utf-8," + 19 encodeURIComponent( 20 "<title>JS Debugger BrowserTabList test page</title><body>Yo.</body>" 21 ); 22 23 // The tablist object whose behavior we observe. 24 var gTabList; 25 var gFirstActor, gActorA; 26 var gTabA, gTabB, gTabC; 27 var gNewWindow; 28 29 // Stock onListChanged handler. 30 var onListChangedCount = 0; 31 function onListChangedHandler() { 32 onListChangedCount++; 33 } 34 35 function test() { 36 DevToolsServer.init(); 37 DevToolsServer.registerAllActors(); 38 39 gTabList = new BrowserTabList("fake DevToolsServerConnection"); 40 gTabList._testing = true; 41 gTabList.onListChanged = onListChangedHandler; 42 43 checkSingleTab() 44 .then(addTabA) 45 .then(testTabA) 46 .then(addTabB) 47 .then(testTabB) 48 .then(removeTabA) 49 .then(testTabClosed) 50 .then(addTabC) 51 .then(testTabC) 52 .then(removeTabC) 53 .then(testNewWindow) 54 .then(removeNewWindow) 55 .then(testWindowClosed) 56 .then(removeTabB) 57 .then(checkSingleTab) 58 .then(finishUp); 59 } 60 61 function checkSingleTab() { 62 return gTabList.getList().then(targetActors => { 63 is(targetActors.length, 1, "initial tab list: contains initial tab"); 64 gFirstActor = targetActors[0]; 65 is( 66 gFirstActor.url, 67 "about:blank", 68 "initial tab list: initial tab URL is 'about:blank'" 69 ); 70 is( 71 gFirstActor.title, 72 "New Tab", 73 "initial tab list: initial tab title is 'New Tab'" 74 ); 75 }); 76 } 77 78 function addTabA() { 79 return addTab(gTestPage).then(tab => { 80 gTabA = tab; 81 }); 82 } 83 84 function testTabA() { 85 is(onListChangedCount, 1, "onListChanged handler call count"); 86 87 return gTabList.getList().then(targetActors => { 88 targetActors = new Set(targetActors); 89 is(targetActors.size, 2, "gTabA opened: two tabs in list"); 90 ok(targetActors.has(gFirstActor), "gTabA opened: initial tab present"); 91 92 info("actors: " + [...targetActors].map(a => a.url)); 93 gActorA = [...targetActors].filter(a => a !== gFirstActor)[0]; 94 ok(gActorA.url.match(/^data:text\/html;/), "gTabA opened: new tab URL"); 95 is( 96 gActorA.title, 97 "JS Debugger BrowserTabList test page", 98 "gTabA opened: new tab title" 99 ); 100 }); 101 } 102 103 function addTabB() { 104 return addTab(gTestPage).then(tab => { 105 gTabB = tab; 106 }); 107 } 108 109 function testTabB() { 110 is(onListChangedCount, 2, "onListChanged handler call count"); 111 112 return gTabList.getList().then(targetActors => { 113 targetActors = new Set(targetActors); 114 is(targetActors.size, 3, "gTabB opened: three tabs in list"); 115 }); 116 } 117 118 function removeTabA() { 119 return new Promise(resolve => { 120 once(gBrowser.tabContainer, "TabClose").then(event => { 121 ok(!event.detail.adoptedBy, "This was a normal tab close"); 122 123 // Let the actor's TabClose handler finish first. 124 executeSoon(resolve); 125 }, false); 126 127 removeTab(gTabA); 128 }); 129 } 130 131 function testTabClosed() { 132 is(onListChangedCount, 3, "onListChanged handler call count"); 133 134 gTabList.getList().then(targetActors => { 135 targetActors = new Set(targetActors); 136 is(targetActors.size, 2, "gTabA closed: two tabs in list"); 137 ok(targetActors.has(gFirstActor), "gTabA closed: initial tab present"); 138 139 info("actors: " + [...targetActors].map(a => a.url)); 140 gActorA = [...targetActors].filter(a => a !== gFirstActor)[0]; 141 ok(gActorA.url.match(/^data:text\/html;/), "gTabA closed: new tab URL"); 142 is( 143 gActorA.title, 144 "JS Debugger BrowserTabList test page", 145 "gTabA closed: new tab title" 146 ); 147 }); 148 } 149 150 function addTabC() { 151 return addTab(gTestPage).then(tab => { 152 gTabC = tab; 153 }); 154 } 155 156 function testTabC() { 157 is(onListChangedCount, 4, "onListChanged handler call count"); 158 159 gTabList.getList().then(targetActors => { 160 targetActors = new Set(targetActors); 161 is(targetActors.size, 3, "gTabC opened: three tabs in list"); 162 }); 163 } 164 165 function removeTabC() { 166 return new Promise(resolve => { 167 once(gBrowser.tabContainer, "TabClose").then(event => { 168 ok(event.detail.adoptedBy, "This was a tab closed by moving"); 169 170 // Let the actor's TabClose handler finish first. 171 executeSoon(resolve); 172 }, false); 173 174 gNewWindow = gBrowser.replaceTabWithWindow(gTabC); 175 }); 176 } 177 178 function testNewWindow() { 179 is(onListChangedCount, 5, "onListChanged handler call count"); 180 181 return gTabList.getList().then(targetActors => { 182 targetActors = new Set(targetActors); 183 is(targetActors.size, 3, "gTabC closed: three tabs in list"); 184 ok(targetActors.has(gFirstActor), "gTabC closed: initial tab present"); 185 186 info("actors: " + [...targetActors].map(a => a.url)); 187 gActorA = [...targetActors].filter(a => a !== gFirstActor)[0]; 188 ok(gActorA.url.match(/^data:text\/html;/), "gTabC closed: new tab URL"); 189 is( 190 gActorA.title, 191 "JS Debugger BrowserTabList test page", 192 "gTabC closed: new tab title" 193 ); 194 }); 195 } 196 197 function removeNewWindow() { 198 return new Promise(resolve => { 199 once(gNewWindow, "unload").then(event => { 200 ok(!event.detail, "This was a normal window close"); 201 202 // Let the actor's TabClose handler finish first. 203 executeSoon(resolve); 204 }, false); 205 206 gNewWindow.close(); 207 }); 208 } 209 210 function testWindowClosed() { 211 is(onListChangedCount, 6, "onListChanged handler call count"); 212 213 return gTabList.getList().then(targetActors => { 214 targetActors = new Set(targetActors); 215 is(targetActors.size, 2, "gNewWindow closed: two tabs in list"); 216 ok(targetActors.has(gFirstActor), "gNewWindow closed: initial tab present"); 217 218 info("actors: " + [...targetActors].map(a => a.url)); 219 gActorA = [...targetActors].filter(a => a !== gFirstActor)[0]; 220 ok( 221 gActorA.url.match(/^data:text\/html;/), 222 "gNewWindow closed: new tab URL" 223 ); 224 is( 225 gActorA.title, 226 "JS Debugger BrowserTabList test page", 227 "gNewWindow closed: new tab title" 228 ); 229 }); 230 } 231 232 function removeTabB() { 233 return new Promise(resolve => { 234 once(gBrowser.tabContainer, "TabClose").then(event => { 235 ok(!event.detail.adoptedBy, "This was a normal tab close"); 236 237 // Let the actor's TabClose handler finish first. 238 executeSoon(resolve); 239 }, false); 240 241 removeTab(gTabB); 242 }); 243 } 244 245 function finishUp() { 246 gTabList = gFirstActor = gActorA = gTabA = gTabB = gTabC = gNewWindow = null; 247 finish(); 248 }