Bug 1413418 - Test case introducing lifecycle callbacks on <deck> to trigger leaks
Run with ./mach mochitest toolkit/content/tests/chrome/test_bug263683.xul
MozReview-Commit-ID: 98xpjQ5boz9
--- a/toolkit/content/tests/chrome/bug263683_window.xul
+++ b/toolkit/content/tests/chrome/bug263683_window.xul
@@ -8,204 +8,18 @@
<?xml-stylesheet
href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window id="263683test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
- onload="SimpleTest.executeSoon(startTest);"
+ onload="window.opener.SimpleTest.executeSoon(startTest);"
title="263683 test">
<script type="application/javascript"><![CDATA[
- ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
- ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
- ChromeUtils.import("resource://testing-common/ContentTask.jsm");
- ContentTask.setTestScope(window.opener.wrappedJSObject);
-
- var gPrefsvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
- var gFindBar = null;
- var gBrowser;
-
- var imports = ["SimpleTest", "ok", "info", "is"];
- for (var name of imports) {
- window[name] = window.opener.wrappedJSObject[name];
- }
-
function startTest() {
- (async function() {
- gFindBar = document.getElementById("FindToolbar");
- // Testing on a remote browser has been disabled due to frequent
- // intermittent failures.
- for (let browserId of ["content"/*, "content-remote"*/]) {
- await startTestWithBrowser(browserId);
- }
- })().then(() => {
- window.close();
- SimpleTest.finish();
- });
- }
-
- async function startTestWithBrowser(browserId) {
- // We're bailing out when testing a remote browser on OSX 10.6, because it
- // fails permanently.
- if (browserId.endsWith("remote") && AppConstants.isPlatformAndVersionAtMost("macosx", 11)) {
- return;
- }
-
- info("Starting test with browser '" + browserId + "'");
- gBrowser = document.getElementById(browserId);
- gFindBar.browser = gBrowser;
- let promise = BrowserTestUtils.browserLoaded(gBrowser);
- gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><input id="inp" type="text" />');
- await promise;
- await onDocumentLoaded();
- }
-
- function toggleHighlightAndWait(highlight) {
- return new Promise(resolve => {
- let listener = {
- onHighlightFinished: function() {
- gFindBar.browser.finder.removeResultListener(listener);
- resolve();
- }
- };
- gFindBar.browser.finder.addResultListener(listener);
- gFindBar.toggleHighlight(highlight);
- });
- }
-
- async function onDocumentLoaded() {
- gFindBar.open();
- var search = "mozilla";
- gFindBar._findField.focus();
- gFindBar._findField.value = search;
- var matchCase = gFindBar.getElement("find-case-sensitive");
- if (matchCase.checked) {
- matchCase.doCommand();
- }
-
- let promise = toggleHighlightAndWait(true);
- gFindBar._find();
- await promise;
-
- await ContentTask.spawn(gBrowser, { search }, async function(args) {
- let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISelectionDisplay)
- .QueryInterface(Ci.nsISelectionController);
- Assert.ok("SELECTION_FIND" in controller, "Correctly detects new selection type");
- let selection = controller.getSelection(controller.SELECTION_FIND);
-
- Assert.equal(selection.rangeCount, 1,
- "Correctly added a match to the selection type");
- Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
- args.search, "Added the correct match");
- });
-
- await toggleHighlightAndWait(false);
-
- await ContentTask.spawn(gBrowser, { search }, async function(args) {
- let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISelectionDisplay)
- .QueryInterface(Ci.nsISelectionController);
- let selection = controller.getSelection(controller.SELECTION_FIND);
- Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
-
- let input = content.document.getElementById("inp");
- input.value = args.search;
- });
-
- await toggleHighlightAndWait(true);
-
- await ContentTask.spawn(gBrowser, { search }, async function(args) {
- let input = content.document.getElementById("inp");
- let inputController = input.editor.selectionController;
- let inputSelection = inputController.getSelection(inputController.SELECTION_FIND);
-
- Assert.equal(inputSelection.rangeCount, 1,
- "Correctly added a match from input to the selection type");
- Assert.equal(inputSelection.getRangeAt(0).toString().toLowerCase(),
- args.search, "Added the correct match");
- });
-
- await toggleHighlightAndWait(false);
-
- await ContentTask.spawn(gBrowser, null, async function() {
- let input = content.document.getElementById("inp");
- let inputController = input.editor.selectionController;
- let inputSelection = inputController.getSelection(inputController.SELECTION_FIND);
-
- Assert.equal(inputSelection.rangeCount, 0, "Correctly removed the range");
- });
-
- // For posterity, test iframes too.
-
- promise = BrowserTestUtils.browserLoaded(gBrowser);
- gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><iframe id="leframe" ' +
- 'src="data:text/html,Text mozilla"></iframe>');
- await promise;
-
- await toggleHighlightAndWait(true);
-
- await ContentTask.spawn(gBrowser, { search }, async function(args) {
- function getSelection(docShell) {
- let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISelectionDisplay)
- .QueryInterface(Ci.nsISelectionController);
- return controller.getSelection(controller.SELECTION_FIND);
- }
-
- let selection = getSelection(docShell);
- Assert.equal(selection.rangeCount, 1,
- "Correctly added a match to the selection type");
- Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
- args.search, "Added the correct match");
-
- // Check the iframe too:
- let frame = content.document.getElementById("leframe");
- // Hoops! Get the docShell first, then the selection.
- selection = getSelection(frame.contentWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell));
- Assert.equal(selection.rangeCount, 1,
- "Correctly added a match to the selection type");
- Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
- args.search, "Added the correct match");
- });
-
- await toggleHighlightAndWait(false);
-
- let matches = gFindBar._foundMatches.value.match(/([\d]*)\sof\s([\d]*)/);
- is(matches[1], "2", "Found correct amount of matches")
-
- await ContentTask.spawn(gBrowser, null, async function(args) {
- function getSelection(docShell) {
- let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISelectionDisplay)
- .QueryInterface(Ci.nsISelectionController);
- return controller.getSelection(controller.SELECTION_FIND);
- }
-
- let selection = getSelection(docShell);
- Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
-
- // Check the iframe too:
- let frame = content.document.getElementById("leframe");
- // Hoops! Get the docShell first, then the selection.
- selection = getSelection(frame.contentWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell));
- Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
-
- content.document.documentElement.focus();
- });
-
- gFindBar.close(true);
+ window.opener.SimpleTest.ok(true);
+ window.opener.SimpleTest.finish();
}
]]></script>
-
- <browser type="content" primary="true" flex="1" id="content" src="about:blank"/>
- <browser type="content" primary="true" flex="1" id="content-remote" remote="true" src="about:blank"/>
- <findbar id="FindToolbar" browserid="content"/>
</window>
--- a/toolkit/content/widgets/general.js
+++ b/toolkit/content/widgets/general.js
@@ -1,17 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
{
+ let windowID = Math.random();
+ let unloaded = false;
+ console.log("general.js: loaded", windowID, window.location.toString())
+window.addEventListener("unload", () => {
+ unloaded = true;
+ console.log("general.js: window unload fired", windowID);
+}, { once: true });
+
+let i = 0;
class MozDeck extends MozXULElement {
+ constructor() {
+ super();
+ this.i = i++;
+ console.log("general.js: MozDeck constructor", this.i, windowID);
+ }
+ connectedCallback() {
+ console.log("general.js: MozDeck connectedCallback", this.i, windowID, unloaded);
+ if (unloaded) {
+ console.log("general.js: MozDeck running script after unload", this.parentNode.outerHTML);
+ }
+ }
+ disconnectedCallback() {
+ console.log("general.js: MozDeck disconnectedCallback", this.i, windowID);
+ }
+
set selectedIndex(val) {
if (this.selectedIndex == val) return val;
this.setAttribute("selectedIndex", val);
var event = document.createEvent("Events");
event.initEvent("select", true, true);
this.dispatchEvent(event);
return val;
}