Bug 1340987 - (Part 3) Fix browser-chrome-mochitest for gSubDialog. r=MattN
authorScott Wu <scottcwwu@gmail.com>
Thu, 13 Apr 2017 15:15:08 +0800
changeset 412963 7860182ed49d0cfeb73ad00063663904262ea824
parent 412962 2eca7036eb36289051ca5847b45bad7df07c5a4f
child 412964 fb8ec9403cd5b0b957937aea130afe1019bf6025
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1340987
milestone55.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 1340987 - (Part 3) Fix browser-chrome-mochitest for gSubDialog. r=MattN MozReview-Commit-ID: 1bqlA4i6dki
browser/components/preferences/in-content-new/tests/browser_subdialogs.js
--- a/browser/components/preferences/in-content-new/tests/browser_subdialogs.js
+++ b/browser/components/preferences/in-content-new/tests/browser_subdialogs.js
@@ -12,29 +12,29 @@ const gDialogURL2 = getRootDirectory(gTe
 
 function open_subdialog_and_test_generic_start_state(browser, domcontentloadedFn, url = gDialogURL) {
   let domcontentloadedFnStr = domcontentloadedFn ?
     "(" + domcontentloadedFn.toString() + ")()" :
     "";
   return ContentTask.spawn(browser, {url, domcontentloadedFnStr}, async function(args) {
     let rv = { acceptCount: 0 };
     let win = content.window;
-    let subdialog = win.gSubDialog;
-    subdialog.open(args.url, null, rv);
+    content.gSubDialog.open(args.url, null, rv);
+    let subdialog = content.gSubDialog._topDialog;
 
     info("waiting for subdialog DOMFrameContentLoaded");
     await ContentTaskUtils.waitForEvent(win, "DOMFrameContentLoaded", true);
     let result;
     if (args.domcontentloadedFnStr) {
       // eslint-disable-next-line no-eval
       result = eval(args.domcontentloadedFnStr);
     }
 
     info("waiting for subdialog load");
-    await ContentTaskUtils.waitForEvent(subdialog._frame, "load");
+    await ContentTaskUtils.waitForEvent(subdialog._overlay, "dialogopen");
     info("subdialog window is loaded");
 
     let expectedStyleSheetURLs = subdialog._injectedStyleSheets.slice(0);
     for (let styleSheet of subdialog._frame.contentDocument.styleSheets) {
       let index = expectedStyleSheetURLs.indexOf(styleSheet.href);
       if (index >= 0) {
         expectedStyleSheetURLs.splice(index, 1);
       }
@@ -47,19 +47,27 @@ function open_subdialog_and_test_generic
       "Overlay should be visible");
     Assert.equal(expectedStyleSheetURLs.length, 0,
       "No stylesheets that were expected are missing");
     return result;
   });
 }
 
 async function close_subdialog_and_test_generic_end_state(browser, closingFn, closingButton, acceptCount, options) {
+  let getDialogsCount = () => {
+    return ContentTask.spawn(browser, null, () =>
+      content.window.gSubDialog._dialogs.length);
+  };
+  let getStackChildrenCount = () => {
+    return ContentTask.spawn(browser, null, () =>
+      content.window.gSubDialog._dialogStack.children.length);
+  };
   let dialogclosingPromise = ContentTask.spawn(browser, {closingButton, acceptCount}, async function(expectations) {
     let win = content.window;
-    let subdialog = win.gSubDialog;
+    let subdialog = win.gSubDialog._topDialog;
     let frame = subdialog._frame;
     info("waiting for dialogclosing");
     let closingEvent =
       await ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
     let contentClosingButton = closingEvent.detail.button;
     let actualAcceptCount = frame.contentWindow.arguments &&
                             frame.contentWindow.arguments[0].acceptCount;
 
@@ -71,134 +79,162 @@ async function close_subdialog_and_test_
     Assert.equal(frame.getAttribute("style"), "", "inline styles should be cleared");
     Assert.equal(frame.contentWindow.location.href.toString(), "about:blank",
       "sub-dialog should be unloaded");
     Assert.equal(contentClosingButton, expectations.closingButton,
       "closing event should indicate button was '" + expectations.closingButton + "'");
     Assert.equal(actualAcceptCount, expectations.acceptCount,
       "should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
   });
-
+  let initialDialogsCount = await getDialogsCount();
+  let initialStackChildrenCount = await getStackChildrenCount();
   if (options && options.runClosingFnOutsideOfContentTask) {
     await closingFn();
   } else {
     ContentTask.spawn(browser, null, closingFn);
   }
 
   await dialogclosingPromise;
+  let endDialogsCount = await getDialogsCount();
+  let endStackChildrenCount = await getStackChildrenCount();
+  Assert.equal(initialDialogsCount - 1, endDialogsCount,
+    "dialog count should decrease by 1");
+  Assert.equal(initialStackChildrenCount - 1, endStackChildrenCount,
+    "stack children count should decrease by 1");
 }
 
 let tab;
 
 add_task(async function test_initialize() {
   tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
 });
 
 add_task(async function check_titlebar_focus_returnval_titlechanges_accepting() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   let domtitlechangedPromise = BrowserTestUtils.waitForEvent(tab.linkedBrowser, "DOMTitleChanged");
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
-    let dialog = content.window.gSubDialog._frame.contentWindow;
-    let dialogTitleElement = content.document.getElementById("dialogTitle");
+    let dialog = content.window.gSubDialog._topDialog;
+    let dialogWin = dialog._frame.contentWindow;
+    let dialogTitleElement = dialog._titleElement;
     Assert.equal(dialogTitleElement.textContent, "Sample sub-dialog",
        "Title should be correct initially");
-    Assert.equal(dialog.document.activeElement.value, "Default text",
+    Assert.equal(dialogWin.document.activeElement.value, "Default text",
        "Textbox with correct text is focused");
-    dialog.document.title = "Updated title";
+    dialogWin.document.title = "Updated title";
   });
 
   info("waiting for DOMTitleChanged event");
   await domtitlechangedPromise;
 
   ContentTask.spawn(tab.linkedBrowser, null, async function() {
-    let dialogTitleElement = content.document.getElementById("dialogTitle");
+    let dialogTitleElement = content.window.gSubDialog._topDialog._titleElement;
     Assert.equal(dialogTitleElement.textContent, "Updated title",
       "subdialog should have updated title");
   });
 
   // Accept the dialog
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentDocument.documentElement.acceptDialog(); },
     "accept", 1);
 });
 
 add_task(async function check_canceling_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   info("canceling the dialog");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentDocument.documentElement.cancelDialog(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentDocument.documentElement.cancelDialog(); },
     "cancel", 0);
 });
 
 add_task(async function check_reopening_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
   info("opening another dialog which will close the first");
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser, "", gDialogURL2);
-  info("closing as normal");
+
+  ContentTask.spawn(tab.linkedBrowser, null, async function() {
+    let win = content.window;
+    let dialogs = win.gSubDialog._dialogs;
+    let lowerDialog = dialogs[0];
+    let topDialog = dialogs[1];
+    Assert.equal(dialogs.length, 2, "There should be two visible dialogs");
+    Assert.equal(win.getComputedStyle(topDialog._overlay).visibility, "visible",
+      "The top dialog should be visible");
+    Assert.equal(win.getComputedStyle(lowerDialog._overlay).visibility, "visible",
+      "The lower dialog should be visible");
+    Assert.equal(win.getComputedStyle(topDialog._overlay).backgroundColor, "rgba(0, 0, 0, 0.5)",
+      "The top dialog should have a semi-transparent overlay");
+    Assert.equal(win.getComputedStyle(lowerDialog._overlay).backgroundColor, "rgba(0, 0, 0, 0)",
+      "The lower dialog should not have an overlay");
+  });
+
+  info("closing two dialogs");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentDocument.documentElement.acceptDialog(); },
+    "accept", 1);
+  await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
+    function() { content.window.gSubDialog._topDialog._frame.contentDocument.documentElement.acceptDialog(); },
     "accept", 1);
 });
 
 add_task(async function check_opening_while_closing() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
   info("closing");
-  content.window.gSubDialog.close();
+  content.window.gSubDialog._topDialog.close();
   info("reopening immediately after calling .close()");
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentDocument.documentElement.acceptDialog(); },
     "accept", 1);
 
 });
 
 add_task(async function window_close_on_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   info("canceling the dialog");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentWindow.window.close(); },
     null, 0);
 });
 
 add_task(async function click_close_button_on_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   info("canceling the dialog");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { return BrowserTestUtils.synthesizeMouseAtCenter("#dialogClose", {}, tab.linkedBrowser); },
+    function() { return BrowserTestUtils.synthesizeMouseAtCenter(".dialogClose", {}, tab.linkedBrowser); },
     null, 0, {runClosingFnOutsideOfContentTask: true});
 });
 
 add_task(async function background_click_should_close_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   // Clicking on an inactive part of dialog itself should not close the dialog.
   // Click the dialog title bar here to make sure nothing happens.
   info("clicking the dialog title bar");
-  BrowserTestUtils.synthesizeMouseAtCenter("#dialogTitle", {}, tab.linkedBrowser);
+  BrowserTestUtils.synthesizeMouseAtCenter(".dialogTitle", {}, tab.linkedBrowser);
 
   // Close the dialog by clicking on the overlay background. Simulate a click
   // at point (2,2) instead of (0,0) so we are sure we're clicking on the
   // overlay background instead of some boundary condition that a real user
   // would never click.
   info("clicking the overlay background");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
     function() { return BrowserTestUtils.synthesizeMouseAtPoint(2, 2, {}, tab.linkedBrowser); },
     null, 0, {runClosingFnOutsideOfContentTask: true});
 });
 
 add_task(async function back_navigation_on_subdialog_should_close_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   info("canceling the dialog");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.goBack(); },
+    function() { content.window.gSubDialog._topDialog._frame.goBack(); },
     null, undefined);
 });
 
 add_task(async function back_navigation_on_browser_tab_should_close_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   info("canceling the dialog");
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
@@ -214,31 +250,31 @@ add_task(async function escape_should_cl
     function() { return BrowserTestUtils.synthesizeKey("VK_ESCAPE", {}, tab.linkedBrowser); },
     "cancel", 0, {runClosingFnOutsideOfContentTask: true});
 });
 
 add_task(async function correct_width_and_height_should_be_used_for_dialog() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
 
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
-    let frameStyle = content.window.gSubDialog._frame.style;
+    let frameStyle = content.window.gSubDialog._topDialog._frame.style;
     Assert.equal(frameStyle.width, "32em",
       "Width should be set on the frame from the dialog");
     Assert.equal(frameStyle.height, "5em",
       "Height should be set on the frame from the dialog");
   });
 
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentWindow.window.close(); },
     null, 0);
 });
 
 add_task(async function wrapped_text_in_dialog_should_have_expected_scrollHeight() {
   let oldHeight = await open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     let doc = frame.contentDocument;
     let scrollHeight = doc.documentElement.scrollHeight;
     doc.documentElement.style.removeProperty("height");
     doc.getElementById("desc").textContent = `
       Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
       laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
       architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
       sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
@@ -248,64 +284,64 @@ add_task(async function wrapped_text_in_
       laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
       architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
       sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
       voluptatem sequi nesciunt.`
     return scrollHeight;
   });
 
   await ContentTask.spawn(tab.linkedBrowser, oldHeight, async function(contentOldHeight) {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     let docEl = frame.contentDocument.documentElement;
     Assert.equal(frame.style.width, "32em",
       "Width should be set on the frame from the dialog");
     Assert.ok(docEl.scrollHeight > contentOldHeight,
       "Content height increased (from " + contentOldHeight + " to " + docEl.scrollHeight + ").");
     Assert.equal(frame.style.height, docEl.scrollHeight + "px",
       "Height on the frame should be higher now");
   });
 
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentWindow.window.close(); },
     null, 0);
 });
 
 add_task(async function dialog_too_tall_should_get_reduced_in_height() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     frame.contentDocument.documentElement.style.height = "100000px";
   });
 
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     Assert.equal(frame.style.width, "32em", "Width should be set on the frame from the dialog");
     Assert.ok(parseInt(frame.style.height, 10) < content.window.innerHeight,
        "Height on the frame should be smaller than window's innerHeight");
   });
 
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentWindow.window.close(); },
     null, 0);
 });
 
 add_task(async function scrollWidth_and_scrollHeight_from_subdialog_should_size_the_browser() {
   await open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     frame.contentDocument.documentElement.style.removeProperty("height");
     frame.contentDocument.documentElement.style.removeProperty("width");
   });
 
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
-    let frame = content.window.gSubDialog._frame;
+    let frame = content.window.gSubDialog._topDialog._frame;
     Assert.ok(frame.style.width.endsWith("px"),
        "Width (" + frame.style.width + ") should be set to a px value of the scrollWidth from the dialog");
     Assert.ok(frame.style.height.endsWith("px"),
        "Height (" + frame.style.height + ") should be set to a px value of the scrollHeight from the dialog");
   });
 
   await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
-    function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
+    function() { content.window.gSubDialog._topDialog._frame.contentWindow.window.close(); },
     null, 0);
 });
 
 add_task(async function test_shutdown() {
   gBrowser.removeTab(tab);
 });