1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/docshell/test/navigation/browser_bug343515.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 +// Test for bug 343515 - Need API for tabbrowsers to tell docshells they're visible/hidden 1.5 + 1.6 +// Globals 1.7 +var testPath = "http://mochi.test:8888/browser/docshell/test/navigation/"; 1.8 +var ctx = {}; 1.9 + 1.10 +// Helper function to check if a window is active 1.11 +function isActive(aWindow) { 1.12 + var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) 1.13 + .getInterface(Ci.nsIWebNavigation) 1.14 + .QueryInterface(Ci.nsIDocShell); 1.15 + return docshell.isActive; 1.16 +} 1.17 + 1.18 +// We need to wait until the page from each testcase is fully loaded, 1.19 +// including all of its descendant iframes. To do that we manually count 1.20 +// how many load events should happen on that page (one for the toplevel doc 1.21 +// and one for each subframe) and wait until we receive the expected number 1.22 +// of events. 1.23 +function nShotsListener(aElem, aType, aCallback, aCount) { 1.24 + let count = aCount; 1.25 + aElem.addEventListener(aType, function listenerCallback() { 1.26 + if (--count == 0) { 1.27 + aElem.removeEventListener(aType, listenerCallback, true); 1.28 + 1.29 + // aCallback is executed asynchronously, which is handy because load 1.30 + // events fire before mIsDocumentLoaded is actually set to true. :( 1.31 + executeSoon(aCallback); 1.32 + } 1.33 + }, true); 1.34 +} 1.35 + 1.36 +function oneShotListener(aElem, aType, aCallback) { 1.37 + nShotsListener(aElem, aType, aCallback, 1); 1.38 +} 1.39 + 1.40 +// Entry point from Mochikit 1.41 +function test() { 1.42 + 1.43 + // Lots of callbacks going on here 1.44 + waitForExplicitFinish(); 1.45 + 1.46 + // Begin the test 1.47 + step1(); 1.48 +} 1.49 + 1.50 +function step1() { 1.51 + 1.52 + // Get a handle on the initial tab 1.53 + ctx.tab0 = gBrowser.selectedTab; 1.54 + ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0); 1.55 + ctx.tab0Window = ctx.tab0Browser.contentWindow; 1.56 + 1.57 + // Our current tab should be active 1.58 + ok(isActive(ctx.tab0Window), "Tab 0 should be active at test start"); 1.59 + 1.60 + // Open a New Tab 1.61 + ctx.tab1 = gBrowser.addTab(testPath + "bug343515_pg1.html"); 1.62 + ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1); 1.63 + ctx.tab1Window = ctx.tab1Browser.contentWindow; 1.64 + oneShotListener(ctx.tab1Browser, "load", step2); 1.65 +} 1.66 + 1.67 +function step2() { 1.68 + is(testPath + "bug343515_pg1.html", ctx.tab1Browser.currentURI.spec, 1.69 + "Got expected tab 1 url in step 2"); 1.70 + 1.71 + // Our current tab should still be active 1.72 + ok(isActive(ctx.tab0Window), "Tab 0 should still be active"); 1.73 + ok(!isActive(ctx.tab1Window), "Tab 1 should not be active"); 1.74 + 1.75 + // Switch to tab 1 1.76 + gBrowser.selectedTab = ctx.tab1; 1.77 + 1.78 + // Tab 1 should now be active 1.79 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.80 + ok(isActive(ctx.tab1Window), "Tab 1 should be active"); 1.81 + 1.82 + // Open another tab 1.83 + ctx.tab2 = gBrowser.addTab(testPath + "bug343515_pg2.html"); 1.84 + ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2); 1.85 + ctx.tab2Window = ctx.tab2Browser.contentWindow; 1.86 + 1.87 + // bug343515_pg2.html consists of a page with two iframes, 1.88 + // which will therefore generate 3 load events. 1.89 + nShotsListener(ctx.tab2Browser, "load", step3, 3); 1.90 +} 1.91 + 1.92 +function step3() { 1.93 + is(testPath + "bug343515_pg2.html", ctx.tab2Browser.currentURI.spec, 1.94 + "Got expected tab 2 url in step 3"); 1.95 + 1.96 + // Tab 0 should be inactive, Tab 1 should be active 1.97 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.98 + ok(isActive(ctx.tab1Window), "Tab 1 should be active"); 1.99 + 1.100 + // Tab 2's window _and_ its iframes should be inactive 1.101 + ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive"); 1.102 + is(ctx.tab2Window.frames.length, 2, "Tab 2 should have 2 iframes"); 1.103 + for (var i = 0; i < ctx.tab2Window.frames.length; i++) 1.104 + info("step 3, frame " + i + " info: " + ctx.tab2Window.frames[i].location); 1.105 + ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive"); 1.106 + ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive"); 1.107 + 1.108 + // Navigate tab 2 to a different page 1.109 + ctx.tab2Window.location = testPath + "bug343515_pg3.html"; 1.110 + 1.111 + // bug343515_pg3.html consists of a page with two iframes, one of which 1.112 + // contains another iframe, so there'll be a total of 4 load events 1.113 + nShotsListener(ctx.tab2Browser, "load", step4, 4); 1.114 +} 1.115 + 1.116 +function step4() { 1.117 + is(testPath + "bug343515_pg3.html", ctx.tab2Browser.currentURI.spec, 1.118 + "Got expected tab 2 url in step 4"); 1.119 + 1.120 + // Tab 0 should be inactive, Tab 1 should be active 1.121 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.122 + ok(isActive(ctx.tab1Window), "Tab 1 should be active"); 1.123 + 1.124 + // Tab2 and all descendants should be inactive 1.125 + ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive"); 1.126 + is(ctx.tab2Window.frames.length, 2, "Tab 2 should have 2 iframes"); 1.127 + for (var i = 0; i < ctx.tab2Window.frames.length; i++) 1.128 + info("step 4, frame " + i + " info: " + ctx.tab2Window.frames[i].location); 1.129 + is(ctx.tab2Window.frames[0].frames.length, 1, "Tab 2 iframe 0 should have 1 iframes"); 1.130 + ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive"); 1.131 + ok(!isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be inactive"); 1.132 + ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive"); 1.133 + 1.134 + // Switch to Tab 2 1.135 + gBrowser.selectedTab = ctx.tab2; 1.136 + 1.137 + // Check everything 1.138 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.139 + ok(!isActive(ctx.tab1Window), "Tab 1 should be inactive"); 1.140 + ok(isActive(ctx.tab2Window), "Tab 2 should be active"); 1.141 + ok(isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be active"); 1.142 + ok(isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be active"); 1.143 + ok(isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be active"); 1.144 + 1.145 + // Go back 1.146 + oneShotListener(ctx.tab2Browser, "pageshow", step5); 1.147 + ctx.tab2Browser.goBack(); 1.148 + 1.149 +} 1.150 + 1.151 +function step5() { 1.152 + // Check everything 1.153 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.154 + ok(!isActive(ctx.tab1Window), "Tab 1 should be inactive"); 1.155 + ok(isActive(ctx.tab2Window), "Tab 2 should be active"); 1.156 + ok(isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be active"); 1.157 + ok(isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be active"); 1.158 + 1.159 + // Switch to tab 1 1.160 + gBrowser.selectedTab = ctx.tab1; 1.161 + 1.162 + // Navigate to page 3 1.163 + ctx.tab1Window.location = testPath + "bug343515_pg3.html"; 1.164 + 1.165 + // bug343515_pg3.html consists of a page with two iframes, one of which 1.166 + // contains another iframe, so there'll be a total of 4 load events 1.167 + nShotsListener(ctx.tab1Browser, "load", step6, 4); 1.168 +} 1.169 + 1.170 +function step6() { 1.171 + 1.172 + // Check everything 1.173 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.174 + ok(isActive(ctx.tab1Window), "Tab 1 should be active"); 1.175 + ok(isActive(ctx.tab1Window.frames[0]), "Tab1 iframe 0 should be active"); 1.176 + ok(isActive(ctx.tab1Window.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active"); 1.177 + ok(isActive(ctx.tab1Window.frames[1]), "Tab1 iframe 1 should be active"); 1.178 + ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive"); 1.179 + ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive"); 1.180 + ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive"); 1.181 + 1.182 + // Go forward on tab 2 1.183 + oneShotListener(ctx.tab2Browser, "pageshow", step7); 1.184 + var tab2docshell = ctx.tab2Window.QueryInterface(Ci.nsIInterfaceRequestor) 1.185 + .getInterface(Ci.nsIWebNavigation); 1.186 + tab2docshell.goForward(); 1.187 +} 1.188 + 1.189 +function step7() { 1.190 + 1.191 + ctx.tab2Window = ctx.tab2Browser.contentWindow; 1.192 + 1.193 + // Check everything 1.194 + ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive"); 1.195 + ok(isActive(ctx.tab1Window), "Tab 1 should be active"); 1.196 + ok(isActive(ctx.tab1Window.frames[0]), "Tab1 iframe 0 should be active"); 1.197 + ok(isActive(ctx.tab1Window.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active"); 1.198 + ok(isActive(ctx.tab1Window.frames[1]), "Tab1 iframe 1 should be active"); 1.199 + ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive"); 1.200 + ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive"); 1.201 + ok(!isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be inactive"); 1.202 + ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive"); 1.203 + 1.204 + // That's probably enough 1.205 + allDone(); 1.206 +} 1.207 + 1.208 +function allDone() { 1.209 + 1.210 + // Close the tabs we made 1.211 + gBrowser.removeTab(ctx.tab1); 1.212 + gBrowser.removeTab(ctx.tab2); 1.213 + 1.214 + // Tell the framework we're done 1.215 + finish(); 1.216 +}