Bug 1147765 - Fix test failures caused by async initialization fixes. r=ejpbruel
authorSami Jaktholm <sjakthol@outlook.com>
Sat, 21 Mar 2015 14:12:58 +0200
changeset 266523 34fab46bd28ab9709ae68bc25af9690d0bd6da64
parent 266522 60a108e6feb8c5df2d908cc265cd702b9f390d35
child 266524 01a988be408b35ad13d57e277dc4ab2c995ccb15
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersejpbruel
bugs1147765
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1147765 - Fix test failures caused by async initialization fixes. r=ejpbruel
browser/devtools/styleeditor/test/browser_styleeditor_init.js
browser/devtools/styleeditor/test/browser_styleeditor_media_sidebar_sourcemaps.js
browser/devtools/styleeditor/test/browser_styleeditor_private_perwindowpb.js
browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_large.js
browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_watching.js
browser/devtools/styleeditor/test/browser_styleeditor_sourcemaps.js
browser/devtools/styleeditor/test/browser_styleeditor_xul.js
browser/devtools/styleeditor/test/head.js
--- a/browser/devtools/styleeditor/test/browser_styleeditor_init.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_init.js
@@ -1,91 +1,44 @@
+"use strict";
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-///////////////////
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: summary is undefined");
+// Checks that style editor contains correct stylesheets after initialization.
 
 const TESTCASE_URI = TEST_BASE_HTTP + "simple.html";
-
-let gUI;
-
-function test()
-{
-  waitForExplicitFinish();
-
-  addTabAndCheckOnStyleEditorAdded(panel => gUI = panel.UI, testEditorAdded);
-
-  content.location = TESTCASE_URI;
-}
-
-let gEditorAddedCount = 0;
-function testEditorAdded(aEditor)
-{
-  if (aEditor.styleSheet.styleSheetIndex == 0) {
-    gEditorAddedCount++;
-    gUI.editors[0].getSourceEditor().then(testFirstStyleSheetEditor);
+const EXPECTED_SHEETS = [
+  {
+    sheetIndex: 0,
+    name: /^simple.css$/,
+    rules: 1,
+    active: true
+  }, {
+    sheetIndex: 1,
+    name: /^<.*>$/,
+    rules: 3,
+    active: false
   }
-  if (aEditor.styleSheet.styleSheetIndex == 1) {
-    gEditorAddedCount++;
-    testSecondStyleSheetEditor(aEditor);
-  }
+];
 
-  if (gEditorAddedCount == 2) {
-    gUI = null;
-    finish();
-  }
-}
+add_task(function* () {
+  let { ui } = yield openStyleEditorForURL(TESTCASE_URI);
 
-function testFirstStyleSheetEditor(aEditor)
-{
-  // Note: the html <link> contains charset="UTF-8".
-  ok(aEditor._state.text.indexOf("\u263a") >= 0,
-     "stylesheet is unicode-aware.");
+  is(ui.editors.length, 2, "The UI contains two style sheets.");
+  checkSheet(ui.editors[0], EXPECTED_SHEETS[0]);
+  checkSheet(ui.editors[1], EXPECTED_SHEETS[1]);
+});
 
-  //testing TESTCASE's simple.css stylesheet
-  is(aEditor.styleSheet.styleSheetIndex, 0,
-     "first stylesheet is at index 0");
+function checkSheet(editor, expected) {
+  is(editor.styleSheet.styleSheetIndex, expected.sheetIndex,
+    "Style sheet has correct index.");
 
-  is(aEditor, gUI.editors[0],
-     "first stylesheet corresponds to StyleEditorChrome.editors[0]");
-
-  let summary = aEditor.summary;
-
+  let summary = editor.summary;
   let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
-  is(name, "simple.css",
-     "first stylesheet's name is `simple.css`");
+  ok(expected.name.test(name), "The name '" + name + "' is correct.");
 
   let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
-  is(parseInt(ruleCount), 1,
-     "first stylesheet UI shows rule count as 1");
-
-  ok(summary.classList.contains("splitview-active"),
-     "first stylesheet UI is focused/active");
-}
-
-function testSecondStyleSheetEditor(aEditor)
-{
-  //testing TESTCASE's inline stylesheet
-  is(aEditor.styleSheet.styleSheetIndex, 1,
-     "second stylesheet is at index 1");
+  is(parseInt(ruleCount), expected.rules, "the rule count is correct");
 
-  is(aEditor, gUI.editors[1],
-     "second stylesheet corresponds to StyleEditorChrome.editors[1]");
-
-  let summary = aEditor.summary;
-
-  let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
-  ok(/^<.*>$/.test(name),
-     "second stylesheet's name is surrounded by `<>`");
-
-  let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
-  is(parseInt(ruleCount), 3,
-     "second stylesheet UI shows rule count as 3");
-
-  ok(!summary.classList.contains("splitview-active"),
-     "second stylesheet UI is NOT focused/active");
+  is(summary.classList.contains("splitview-active"), expected.active,
+    "The active status for this sheet is correct.");
 }
--- a/browser/devtools/styleeditor/test/browser_styleeditor_media_sidebar_sourcemaps.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_media_sidebar_sourcemaps.js
@@ -10,24 +10,24 @@ const LABELS = ["screen and (max-width: 
                 "screen and (min-width: 1200px)"];
 const LINE_NOS = [5, 8];
 
 waitForExplicitFinish();
 
 add_task(function*() {
   Services.prefs.setBoolPref(MAP_PREF, true);
 
-  let {UI} = yield addTabAndOpenStyleEditors(2, null, TESTCASE_URI);
+  let { ui } = yield openStyleEditorForURL(TESTCASE_URI);
 
-  yield listenForMediaChange(UI);
+  yield listenForMediaChange(ui);
 
-  is(UI.editors.length, 1, "correct number of editors");
+  is(ui.editors.length, 1, "correct number of editors");
 
   // Test editor with @media rules
-  let mediaEditor = UI.editors[0];
+  let mediaEditor = ui.editors[0];
   yield openEditor(mediaEditor);
   testMediaEditor(mediaEditor);
 
   Services.prefs.clearUserPref(MAP_PREF);
 });
 
 function testMediaEditor(editor) {
   let sidebar = editor.details.querySelector(".stylesheet-sidebar");
--- a/browser/devtools/styleeditor/test/browser_styleeditor_private_perwindowpb.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_private_perwindowpb.js
@@ -1,52 +1,73 @@
 /* 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/. */
 
 // This test makes sure that the style editor does not store any
 // content CSS files in the permanent cache when opened from PB mode.
 
-function test() {
-  waitForExplicitFinish();
-  let gUI;
-  let testURI = 'http://' + TEST_HOST + '/browser/browser/devtools/styleeditor/test/test_private.html';
+const TEST_URL = 'http://' + TEST_HOST + '/browser/browser/devtools/styleeditor/test/test_private.html';
+const {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
+const cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
+                .getService(Ci.nsICacheStorageService);
 
+add_task(function* () {
   info("Opening a new private window");
   let win = OpenBrowserWindow({private: true});
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad, false);
-    executeSoon(startTest);
-  }, false);
+  yield waitForDelayedStartupFinished(win);
+
+  info("Clearing the browser cache");
+  cache.clear();
 
-  function startTest() {
-    win.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
-      win.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
+  let { ui } = yield openStyleEditorForURL(TEST_URL, win);
+
+  is(ui.editors.length, 1, "The style editor contains one sheet.");
+  let editor = ui.editors[0];
 
-      info("Clearing the browser cache");
-      cache.clear();
+  yield editor.getSourceEditor();
+  yield checkDiskCacheFor(TEST_HOST);
+  win.close();
 
-      info("Opening the style editor in the private window");
-      openStyleEditorInWindow(win, function(panel) {
-        gUI = panel.UI;
-        gUI.on("editor-added", onEditorAdded);
-      });
-    }, true);
+});
+
+function checkDiskCacheFor(host)
+{
+  let foundPrivateData = false;
+  let deferred = promise.defer();
 
-    info("Loading the test URL in the new private window");
-    win.content.location = testURI;
-  }
-
-  function onEditorAdded(aEvent, aEditor) {
-    info("The style editor is ready")
-    aEditor.getSourceEditor().then(checkCache);
-  }
+  Visitor.prototype = {
+    onCacheStorageInfo: function(num, consumption)
+    {
+      info("disk storage contains " + num + " entries");
+    },
+    onCacheEntryInfo: function(uri)
+    {
+      var urispec = uri.asciiSpec;
+      info(urispec);
+      foundPrivateData |= urispec.contains(host);
+    },
+    onCacheEntryVisitCompleted: function()
+    {
+      is(foundPrivateData, false, "web content present in disk cache");
+      deferred.resolve();
+    }
+  };
+  function Visitor() {}
 
-  function checkCache() {
-    checkDiskCacheFor(TEST_HOST, function() {
-      gUI.off("editor-added", onEditorAdded);
-      win.close();
-      win = null;
-      gUI = null;
-      finish();
-    });
-  }
+  var storage = cache.diskCacheStorage(LoadContextInfo.default, false);
+  storage.asyncVisitStorage(new Visitor(), true /* Do walk entries */);
+
+  return deferred.promise;
 }
+
+function waitForDelayedStartupFinished(aWindow)
+{
+  let deferred = promise.defer();
+  Services.obs.addObserver(function observer(aSubject, aTopic) {
+    if (aWindow == aSubject) {
+      Services.obs.removeObserver(observer, aTopic);
+      deferred.resolve();
+    }
+  }, "browser-delayed-startup-finished", false);
+
+  return deferred.promise;
+}
--- a/browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_large.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_large.js
@@ -5,27 +5,27 @@
 // Covers the case from Bug 1128747, where loading a sourcemapped
 // file prevents the correct editor from being selected on load,
 // and causes a second iframe to be appended when the user clicks
 // editor in the list.
 
 const TESTCASE_URI = TEST_BASE_HTTPS + "sourcemaps-large.html";
 
 add_task(function*() {
-  let {UI} = yield addTabAndOpenStyleEditors(2, null, TESTCASE_URI);
+  let { ui } = yield openStyleEditorForURL(TESTCASE_URI);
 
-  yield openEditor(UI.editors[0]);
-  let iframes = UI.selectedEditor.details.querySelectorAll("iframe");
+  yield openEditor(ui.editors[0]);
+  let iframes = ui.selectedEditor.details.querySelectorAll("iframe");
 
   is (iframes.length, 1, "There is only one editor iframe");
-  ok (UI.selectedEditor.summary.classList.contains("splitview-active"),
+  ok (ui.selectedEditor.summary.classList.contains("splitview-active"),
     "The editor is selected");
 });
 
 function openEditor(editor) {
   getLinkFor(editor).click();
 
   return editor.getSourceEditor();
 }
 
 function getLinkFor(editor) {
   return editor.summary.querySelector(".stylesheet-name");
-}
\ No newline at end of file
+}
--- a/browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_watching.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_sourcemap_watching.js
@@ -27,28 +27,40 @@ let FileUtils = tempScope.FileUtils;
 let NetUtil = tempScope.NetUtil;
 
 function test()
 {
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref(TRANSITIONS_PREF, false);
 
-  Task.spawn(function() {
+  Task.spawn(function*() {
     // copy all our files over so we don't screw them up for other tests
     let HTMLFile = yield copy(TESTCASE_URI_HTML, ["sourcemaps.html"]);
     let CSSFile = yield copy(TESTCASE_URI_CSS, ["sourcemap-css", "sourcemaps.css"]);
     yield copy(TESTCASE_URI_SCSS, ["sourcemap-sass", "sourcemaps.scss"]);
     yield copy(TESTCASE_URI_MAP, ["sourcemap-css", "sourcemaps.css.map"]);
     yield copy(TESTCASE_URI_REG_CSS, ["simple.css"]);
 
     let uri = Services.io.newFileURI(HTMLFile);
     let testcaseURI = uri.resolve("");
 
-    let editor = yield openEditor(testcaseURI);
+    let { ui } = yield openStyleEditorForURL(testcaseURI);
+
+    let editor = ui.editors[1];
+    if (getStylesheetNameFor(editor) != TESTCASE_SCSS_NAME) {
+      editor = ui.editors[2];
+    }
+
+    is(getStylesheetNameFor(editor), TESTCASE_SCSS_NAME, "found scss editor");
+
+    let link = getLinkFor(editor);
+    link.click();
+
+    yield editor.getSourceEditor();
 
     let element = content.document.querySelector("div");
     let style = content.getComputedStyle(element, null);
 
     is(style.color, "rgb(255, 0, 102)", "div is red before saving file");
 
     editor.styleSheet.relatedStyleSheet.once("style-applied", function() {
       is(style.color, "rgb(0, 0, 255)", "div is blue after saving file");
@@ -64,41 +76,16 @@ function test()
     // We can't run Sass or another compiler, so we fake it by just
     // directly changing the CSS file.
     yield editCSSFile(CSSFile);
 
     info("wrote to CSS file");
   })
 }
 
-function openEditor(testcaseURI) {
-  let deferred = promise.defer();
-
-  addTabAndOpenStyleEditors(3, panel => {
-    let UI = panel.UI;
-
-    // wait for 5 editors - 1 for first style sheet, 2 for the
-    // generated style sheets, and 2 for original source after it
-    // loads and replaces the generated style sheets.
-    let editor = UI.editors[1];
-    if (getStylesheetNameFor(editor) != TESTCASE_SCSS_NAME) {
-      editor = UI.editors[2];
-    }
-    is(getStylesheetNameFor(editor), TESTCASE_SCSS_NAME, "found scss editor");
-
-    let link = getLinkFor(editor);
-    link.click();
-
-    editor.getSourceEditor().then(deferred.resolve);
-  });
-  content.location = testcaseURI;
-
-  return deferred.promise;
-}
-
 function editSCSS(editor) {
   let deferred = promise.defer();
 
   let pos = {line: 0, ch: 0};
   editor.sourceEditor.replaceText(CSS_TEXT, pos, pos);
 
   editor.saveToFile(null, function (file) {
     ok(file, "Scss file should be saved");
--- a/browser/devtools/styleeditor/test/browser_styleeditor_sourcemaps.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_sourcemaps.js
@@ -64,38 +64,38 @@ const contents = {
 }
 
 const cssNames = ["sourcemaps.css", "contained.css", "test-stylus.css"];
 const origNames = ["sourcemaps.scss", "contained.scss", "test-stylus.styl"];
 
 waitForExplicitFinish();
 
 add_task(function*() {
-  let {UI} = yield addTabAndOpenStyleEditors(7, null, TESTCASE_URI);
+  let {ui} = yield openStyleEditorForURL(TESTCASE_URI);
 
-  is(UI.editors.length, 4,
+  is(ui.editors.length, 4,
     "correct number of editors with source maps enabled");
 
   // Test first plain css editor
-  testFirstEditor(UI.editors[0]);
+  testFirstEditor(ui.editors[0]);
 
   // Test Scss editors
-  yield testEditor(UI.editors[1], origNames);
-  yield testEditor(UI.editors[2], origNames);
-  yield testEditor(UI.editors[3], origNames);
+  yield testEditor(ui.editors[1], origNames);
+  yield testEditor(ui.editors[2], origNames);
+  yield testEditor(ui.editors[3], origNames);
 
   // Test disabling original sources
-  yield togglePref(UI);
+  yield togglePref(ui);
 
-  is(UI.editors.length, 4, "correct number of editors after pref toggled");
+  is(ui.editors.length, 4, "correct number of editors after pref toggled");
 
   // Test CSS editors
-  yield testEditor(UI.editors[1], cssNames);
-  yield testEditor(UI.editors[2], cssNames);
-  yield testEditor(UI.editors[3], cssNames);
+  yield testEditor(ui.editors[1], cssNames);
+  yield testEditor(ui.editors[2], cssNames);
+  yield testEditor(ui.editors[3], cssNames);
 
   Services.prefs.clearUserPref(PREF);
 });
 
 function testFirstEditor(editor) {
   let name = getStylesheetNameFor(editor);
   is(name, "simple.css", "First style sheet display name is correct");
 }
@@ -111,26 +111,17 @@ function testEditor(editor, possibleName
 
     is(text, expectedText, name + " editor contains expected text");
   });
 }
 
 /* Helpers */
 
 function togglePref(UI) {
-  let deferred = promise.defer();
-  let count = 0;
-
-  UI.on("editor-added", (event, editor) => {
-    if (++count == 3) {
-      deferred.resolve();
-    }
-  })
-  let editorsPromise = deferred.promise;
-
+  let editorsPromise = UI.once("stylesheets-reset");
   let selectedPromise = UI.once("editor-selected");
 
   Services.prefs.setBoolPref(PREF, false);
 
   return promise.all([editorsPromise, selectedPromise]);
 }
 
 function openEditor(editor) {
--- a/browser/devtools/styleeditor/test/browser_styleeditor_xul.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_xul.js
@@ -9,12 +9,11 @@ waitForExplicitFinish();
 const TEST_URL = TEST_BASE + "doc_xulpage.xul";
 
 add_task(function*() {
   let tab = yield addTab(TEST_URL);
   let target = TargetFactory.forTab(tab);
 
   let toolbox = yield gDevTools.showToolbox(target, "styleeditor");
   let panel = toolbox.getCurrentPanel();
-  yield panel.UI.once("editor-added");
 
   ok(panel, "The style-editor panel did initialize correctly for the XUL window");
 });
--- a/browser/devtools/styleeditor/test/head.js
+++ b/browser/devtools/styleeditor/test/head.js
@@ -3,50 +3,50 @@
 
 const TEST_BASE = "chrome://mochitests/content/browser/browser/devtools/styleeditor/test/";
 const TEST_BASE_HTTP = "http://example.com/browser/browser/devtools/styleeditor/test/";
 const TEST_BASE_HTTPS = "https://example.com/browser/browser/devtools/styleeditor/test/";
 const TEST_HOST = 'mochi.test:8888';
 
 let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
 let TargetFactory = devtools.TargetFactory;
-let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
 let {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 
 let gPanelWindow;
-let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
-              .getService(Ci.nsICacheStorageService);
 
 
 // Import the GCLI test helper
 let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
 gDevTools.testing = true;
 SimpleTest.registerCleanupFunction(() => {
   gDevTools.testing = false;
 });
 
 /**
  * Add a new test tab in the browser and load the given url.
  * @param {String} url The url to be loaded in the new tab
+ * @param {Window} win The window to add the tab to (default: current window).
  * @return a promise that resolves to the tab object when the url is loaded
  */
-function addTab(url) {
+function addTab(url, win) {
   info("Adding a new tab with URL: '" + url + "'");
   let def = promise.defer();
 
-  let tab = gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+  let targetWindow = win || window;
+  let targetBrowser = targetWindow.gBrowser;
+
+  let tab = targetBrowser.selectedTab = targetBrowser.addTab(url);
+  targetBrowser.selectedBrowser.addEventListener("load", function onload() {
+    targetBrowser.selectedBrowser.removeEventListener("load", onload, true);
     info("URL '" + url + "' loading complete");
     def.resolve(tab);
   }, true);
-  content.location = url;
 
   return def.promise;
 }
 
 /**
  * Navigate the currently selected tab to a new URL and wait for it to load.
  * @param {String} url The url to be loaded in the current tab.
  * @return a promise that resolves when the page has fully loaded.
@@ -67,16 +67,30 @@ function* cleanup()
   while (gBrowser.tabs.length > 1) {
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     yield gDevTools.closeToolbox(target);
 
     gBrowser.removeCurrentTab();
   }
 }
 
+/**
+ * Creates a new tab in specified window navigates it to the given URL and
+ * opens style editor in it.
+ */
+let openStyleEditorForURL = Task.async(function* (url, win) {
+  let tab = yield addTab(url, win);
+  let target = TargetFactory.forTab(tab);
+  let toolbox = yield gDevTools.showToolbox(target, "styleeditor");
+  let panel = toolbox.getPanel("styleeditor");
+  let ui = panel.UI;
+
+  return { tab, toolbox, panel, ui };
+});
+
 function addTabAndOpenStyleEditors(count, callback, uri) {
   let deferred = promise.defer();
   let currentCount = 0;
   let panel;
   addTabAndCheckOnStyleEditorAdded(p => panel = p, function (editor) {
     currentCount++;
     info(currentCount + " of " + count + " editors opened: "
          + editor.styleSheet.href);
@@ -117,36 +131,9 @@ function openStyleEditorInWindow(win, ca
     let panel = toolbox.getCurrentPanel();
     gPanelWindow = panel._panelWin;
 
     panel.UI._alwaysDisableAnimations = true;
     callback(panel);
   });
 }
 
-function checkDiskCacheFor(host, done)
-{
-  let foundPrivateData = false;
-
-  Visitor.prototype = {
-    onCacheStorageInfo: function(num, consumption)
-    {
-      info("disk storage contains " + num + " entries");
-    },
-    onCacheEntryInfo: function(uri)
-    {
-      var urispec = uri.asciiSpec;
-      info(urispec);
-      foundPrivateData |= urispec.contains(host);
-    },
-    onCacheEntryVisitCompleted: function()
-    {
-      is(foundPrivateData, false, "web content present in disk cache");
-      done();
-    }
-  };
-  function Visitor() {}
-
-  var storage = cache.diskCacheStorage(LoadContextInfo.default, false);
-  storage.asyncVisitStorage(new Visitor(), true /* Do walk entries */);
-}
-
 registerCleanupFunction(cleanup);