michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: /** michael@0: * Make sure the root actor's live tab list implementation works as specified. michael@0: */ michael@0: michael@0: let gTestPage = "data:text/html;charset=utf-8," + encodeURIComponent( michael@0: "JS Debugger BrowserTabList test pageYo."); michael@0: michael@0: // The tablist object whose behavior we observe. michael@0: let gTabList; michael@0: let gFirstActor, gActorA; michael@0: let gTabA, gTabB, gTabC; michael@0: let gNewWindow; michael@0: michael@0: // Stock onListChanged handler. michael@0: let onListChangedCount = 0; michael@0: function onListChangedHandler() { michael@0: onListChangedCount++; michael@0: } michael@0: michael@0: function test() { michael@0: if (!DebuggerServer.initialized) { michael@0: DebuggerServer.init(() => true); michael@0: DebuggerServer.addBrowserActors(); michael@0: } michael@0: michael@0: gTabList = new DebuggerServer.BrowserTabList("fake DebuggerServerConnection"); michael@0: gTabList._testing = true; michael@0: gTabList.onListChanged = onListChangedHandler; michael@0: michael@0: checkSingleTab() michael@0: .then(addTabA) michael@0: .then(testTabA) michael@0: .then(addTabB) michael@0: .then(testTabB) michael@0: .then(removeTabA) michael@0: .then(testTabClosed) michael@0: .then(addTabC) michael@0: .then(testTabC) michael@0: .then(removeTabC) michael@0: .then(testNewWindow) michael@0: .then(removeNewWindow) michael@0: .then(testWindowClosed) michael@0: .then(removeTabB) michael@0: .then(checkSingleTab) michael@0: .then(finishUp); michael@0: } michael@0: michael@0: function checkSingleTab() { michael@0: return gTabList.getList().then(aTabActors => { michael@0: is(aTabActors.length, 1, "initial tab list: contains initial tab"); michael@0: gFirstActor = aTabActors[0]; michael@0: is(gFirstActor.url, "about:blank", "initial tab list: initial tab URL is 'about:blank'"); michael@0: is(gFirstActor.title, "New Tab", "initial tab list: initial tab title is 'New Tab'"); michael@0: }); michael@0: } michael@0: michael@0: function addTabA() { michael@0: return addTab(gTestPage).then(aTab => { michael@0: gTabA = aTab; michael@0: }); michael@0: } michael@0: michael@0: function testTabA() { michael@0: is(onListChangedCount, 1, "onListChanged handler call count"); michael@0: michael@0: return gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 2, "gTabA opened: two tabs in list"); michael@0: ok(tabActors.has(gFirstActor), "gTabA opened: initial tab present"); michael@0: michael@0: info("actors: " + [a.url for (a of tabActors)]); michael@0: gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0]; michael@0: ok(gActorA.url.match(/^data:text\/html;/), "gTabA opened: new tab URL"); michael@0: is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabA opened: new tab title"); michael@0: }); michael@0: } michael@0: michael@0: function addTabB() { michael@0: return addTab(gTestPage).then(aTab => { michael@0: gTabB = aTab; michael@0: }); michael@0: } michael@0: michael@0: function testTabB() { michael@0: is(onListChangedCount, 2, "onListChanged handler call count"); michael@0: michael@0: return gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 3, "gTabB opened: three tabs in list"); michael@0: }); michael@0: } michael@0: michael@0: function removeTabA() { michael@0: let deferred = promise.defer(); michael@0: michael@0: once(gBrowser.tabContainer, "TabClose").then(aEvent => { michael@0: ok(!aEvent.detail, "This was a normal tab close"); michael@0: michael@0: // Let the actor's TabClose handler finish first. michael@0: executeSoon(deferred.resolve); michael@0: }, false); michael@0: michael@0: removeTab(gTabA); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function testTabClosed() { michael@0: is(onListChangedCount, 3, "onListChanged handler call count"); michael@0: michael@0: gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 2, "gTabA closed: two tabs in list"); michael@0: ok(tabActors.has(gFirstActor), "gTabA closed: initial tab present"); michael@0: michael@0: info("actors: " + [a.url for (a of tabActors)]); michael@0: gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0]; michael@0: ok(gActorA.url.match(/^data:text\/html;/), "gTabA closed: new tab URL"); michael@0: is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabA closed: new tab title"); michael@0: }); michael@0: } michael@0: michael@0: function addTabC() { michael@0: return addTab(gTestPage).then(aTab => { michael@0: gTabC = aTab; michael@0: }); michael@0: } michael@0: michael@0: function testTabC() { michael@0: is(onListChangedCount, 4, "onListChanged handler call count"); michael@0: michael@0: gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 3, "gTabC opened: three tabs in list"); michael@0: }); michael@0: } michael@0: michael@0: function removeTabC() { michael@0: let deferred = promise.defer(); michael@0: michael@0: once(gBrowser.tabContainer, "TabClose").then(aEvent => { michael@0: ok(aEvent.detail, "This was a tab closed by moving"); michael@0: michael@0: // Let the actor's TabClose handler finish first. michael@0: executeSoon(deferred.resolve); michael@0: }, false); michael@0: michael@0: gNewWindow = gBrowser.replaceTabWithWindow(gTabC); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function testNewWindow() { michael@0: is(onListChangedCount, 5, "onListChanged handler call count"); michael@0: michael@0: return gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 3, "gTabC closed: three tabs in list"); michael@0: ok(tabActors.has(gFirstActor), "gTabC closed: initial tab present"); michael@0: michael@0: info("actors: " + [a.url for (a of tabActors)]); michael@0: gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0]; michael@0: ok(gActorA.url.match(/^data:text\/html;/), "gTabC closed: new tab URL"); michael@0: is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabC closed: new tab title"); michael@0: }); michael@0: } michael@0: michael@0: function removeNewWindow() { michael@0: let deferred = promise.defer(); michael@0: michael@0: once(gNewWindow, "unload").then(aEvent => { michael@0: ok(!aEvent.detail, "This was a normal window close"); michael@0: michael@0: // Let the actor's TabClose handler finish first. michael@0: executeSoon(deferred.resolve); michael@0: }, false); michael@0: michael@0: gNewWindow.close(); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function testWindowClosed() { michael@0: is(onListChangedCount, 6, "onListChanged handler call count"); michael@0: michael@0: return gTabList.getList().then(aTabActors => { michael@0: let tabActors = new Set(aTabActors); michael@0: is(tabActors.size, 2, "gNewWindow closed: two tabs in list"); michael@0: ok(tabActors.has(gFirstActor), "gNewWindow closed: initial tab present"); michael@0: michael@0: info("actors: " + [a.url for (a of tabActors)]); michael@0: gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0]; michael@0: ok(gActorA.url.match(/^data:text\/html;/), "gNewWindow closed: new tab URL"); michael@0: is(gActorA.title, "JS Debugger BrowserTabList test page", "gNewWindow closed: new tab title"); michael@0: }); michael@0: } michael@0: michael@0: function removeTabB() { michael@0: let deferred = promise.defer(); michael@0: michael@0: once(gBrowser.tabContainer, "TabClose").then(aEvent => { michael@0: ok(!aEvent.detail, "This was a normal tab close"); michael@0: michael@0: // Let the actor's TabClose handler finish first. michael@0: executeSoon(deferred.resolve); michael@0: }, false); michael@0: michael@0: removeTab(gTabB); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function finishUp() { michael@0: gTabList = gFirstActor = gActorA = gTabA = gTabB = gTabC = gNewWindow = null; michael@0: finish(); michael@0: }