summaryrefslogtreecommitdiffstats
path: root/docshell/test/navigation/browser_bug343515.js
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/navigation/browser_bug343515.js')
-rw-r--r--docshell/test/navigation/browser_bug343515.js262
1 files changed, 262 insertions, 0 deletions
diff --git a/docshell/test/navigation/browser_bug343515.js b/docshell/test/navigation/browser_bug343515.js
new file mode 100644
index 000000000..74152b493
--- /dev/null
+++ b/docshell/test/navigation/browser_bug343515.js
@@ -0,0 +1,262 @@
+// Test for bug 343515 - Need API for tabbrowsers to tell docshells they're visible/hidden
+
+// Globals
+var testPath = "http://mochi.test:8888/browser/docshell/test/navigation/";
+var ctx = {};
+
+// We need to wait until the page from each testcase is fully loaded,
+// including all of its descendant iframes. To do that we manually count
+// how many load events should happen on that page (one for the toplevel doc
+// and one for each subframe) and wait until we receive the expected number
+// of events.
+function nShotsListener(aElem, aType, aCallback, aCount) {
+ let count = aCount;
+ aElem.addEventListener(aType, function listenerCallback() {
+ if (--count == 0) {
+ aElem.removeEventListener(aType, listenerCallback, true);
+
+ // aCallback is executed asynchronously, which is handy because load
+ // events fire before mIsDocumentLoaded is actually set to true. :(
+ executeSoon(aCallback);
+ }
+ }, true);
+}
+
+function oneShotListener(aElem, aType, aCallback) {
+ nShotsListener(aElem, aType, aCallback, 1);
+}
+
+function waitForPageshow(aBrowser, callback) {
+ return ContentTask.spawn(aBrowser, null, function* () {
+ yield ContentTaskUtils.waitForEvent(this, "pageshow");
+ }).then(callback);
+}
+
+// Entry point from Mochikit
+function test() {
+
+ // Lots of callbacks going on here
+ waitForExplicitFinish();
+
+ // Begin the test
+ step1();
+}
+
+function step1() {
+
+ // Get a handle on the initial tab
+ ctx.tab0 = gBrowser.selectedTab;
+ ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0);
+
+ // Our current tab should be active
+ ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should be active at test start");
+
+ // Open a New Tab
+ ctx.tab1 = gBrowser.addTab(testPath + "bug343515_pg1.html");
+ ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1);
+ oneShotListener(ctx.tab1Browser, "load", step2);
+}
+
+function step2() {
+ is(testPath + "bug343515_pg1.html", ctx.tab1Browser.currentURI.spec,
+ "Got expected tab 1 url in step 2");
+
+ // Our current tab should still be active
+ ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should still be active");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should not be active");
+
+ // Switch to tab 1
+ BrowserTestUtils.switchTab(gBrowser, ctx.tab1).then(() => {
+ // Tab 1 should now be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Open another tab
+ ctx.tab2 = gBrowser.addTab(testPath + "bug343515_pg2.html");
+ ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2);
+
+ // bug343515_pg2.html consists of a page with two iframes,
+ // which will therefore generate 3 load events.
+ nShotsListener(ctx.tab2Browser, "load", step3, 3);
+ });
+}
+
+function step3() {
+ is(testPath + "bug343515_pg2.html", ctx.tab2Browser.currentURI.spec,
+ "Got expected tab 2 url in step 3");
+
+ // Tab 0 should be inactive, Tab 1 should be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Tab 2's window _and_ its iframes should be inactive
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes");
+ for (var i = 0; i < content.frames.length; i++) {
+ info("step 3, frame " + i + " info: " + content.frames[i].location);
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
+ }
+ }).then(() => {
+ // Navigate tab 2 to a different page
+ ctx.tab2Browser.loadURI(testPath + "bug343515_pg3.html");
+
+ // bug343515_pg3.html consists of a page with two iframes, one of which
+ // contains another iframe, so there'll be a total of 4 load events
+ nShotsListener(ctx.tab2Browser, "load", step4, 4);
+ });
+}
+
+function step4() {
+ function checkTab2Active(expected) {
+ return ContentTask.spawn(ctx.tab2Browser, expected, function* (expected) {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ let active = expected ? "active" : "inactive";
+ Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes");
+ for (var i = 0; i < content.frames.length; i++)
+ info("step 4, frame " + i + " info: " + content.frames[i].location);
+ Assert.equal(content.frames[0].frames.length, 1, "Tab 2 iframe 0 should have 1 iframes");
+ Assert.equal(isActive(content.frames[0]), expected, `Tab2 iframe 0 should be ${active}`);
+ Assert.equal(isActive(content.frames[0].frames[0]), expected,
+ `Tab2 iframe 0 subiframe 0 should be ${active}`);
+ Assert.equal(isActive(content.frames[1]), expected, `Tab2 iframe 1 should be ${active}`);
+ });
+ }
+
+ is(testPath + "bug343515_pg3.html", ctx.tab2Browser.currentURI.spec,
+ "Got expected tab 2 url in step 4");
+
+ // Tab 0 should be inactive, Tab 1 should be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Tab2 and all descendants should be inactive
+ checkTab2Active(false).then(() => {
+ // Switch to Tab 2
+ return BrowserTestUtils.switchTab(gBrowser, ctx.tab2);
+ }).then(() => {
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive");
+ ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active");
+
+ return checkTab2Active(true);
+ }).then(() => {
+ // Go back
+ waitForPageshow(ctx.tab2Browser, step5);
+ ctx.tab2Browser.goBack();
+ });
+}
+
+function step5() {
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive");
+ ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active");
+ ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ for (var i = 0; i < content.frames.length; i++) {
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`);
+ }
+ }).then(() => {
+ // Switch to tab 1
+ return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
+ }).then(() => {
+ // Navigate to page 3
+ ctx.tab1Browser.loadURI(testPath + "bug343515_pg3.html");
+
+ // bug343515_pg3.html consists of a page with two iframes, one of which
+ // contains another iframe, so there'll be a total of 4 load events
+ nShotsListener(ctx.tab1Browser, "load", step6, 4);
+ });
+}
+
+function step6() {
+
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+ ContentTask.spawn(ctx.tab1Browser, null, function* () {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ Assert.ok(isActive(content.frames[0]), "Tab1 iframe 0 should be active");
+ Assert.ok(isActive(content.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active");
+ Assert.ok(isActive(content.frames[1]), "Tab1 iframe 1 should be active");
+ }).then(() => {
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ return ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ for (var i = 0; i < content.frames.length; i++) {
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
+ }
+ });
+ }).then(() => {
+ // Go forward on tab 2
+ waitForPageshow(ctx.tab2Browser, step7);
+ ctx.tab2Browser.goForward();
+ });
+}
+
+function step7() {
+ function checkBrowser(browser, tabNum, active) {
+ return ContentTask.spawn(browser, { tabNum, active },
+ function* ({ tabNum, active }) {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ let activestr = active ? "active" : "inactive";
+ Assert.equal(isActive(content.frames[0]), active,
+ `Tab${tabNum} iframe 0 should be ${activestr}`);
+ Assert.equal(isActive(content.frames[0].frames[0]), active,
+ `Tab${tabNum} iframe 0 subiframe 0 should be ${activestr}`);
+ Assert.equal(isActive(content.frames[1]), active,
+ `Tab${tabNum} iframe 1 should be ${activestr}`);
+ });
+ }
+
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+ checkBrowser(ctx.tab1Browser, 1, true).then(() => {
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ return checkBrowser(ctx.tab2Browser, 2, false);
+ }).then(() => {
+ // That's probably enough
+ allDone();
+ });
+}
+
+function allDone() {
+
+ // Close the tabs we made
+ gBrowser.removeTab(ctx.tab1);
+ gBrowser.removeTab(ctx.tab2);
+
+ // Tell the framework we're done
+ finish();
+}