Backed out 2 changesets (bug 1435871) for multiple browser-chrome failures on payments. CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Fri, 19 Oct 2018 12:36:13 +0300
changeset 500540 ad81b437f8604c61701ae3a3112b8490577308eb
parent 500539 462a889b96ca175b528d6d5a00966dd68ae66fae
child 500541 1030155f208e08a4a4673655c8b6b343c1b920a1
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1435871
milestone64.0a1
backs out0f7592b662e27238b8ebc442fa755e5e891cdef9
039f6d65036e99c6ba885de5506a89e722c4e348
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
Backed out 2 changesets (bug 1435871) for multiple browser-chrome failures on payments. CLOSED TREE Backed out changeset 0f7592b662e2 (bug 1435871) Backed out changeset 039f6d65036e (bug 1435871)
browser/base/content/tabbrowser.js
browser/components/payments/content/paymentDialogWrapper.js
browser/components/payments/paymentUIService.js
browser/components/payments/res/containers/payment-dialog.js
browser/components/payments/res/paymentRequest.js
browser/components/payments/test/PaymentTestUtils.jsm
browser/components/payments/test/browser/browser_dropdowns.js
browser/components/payments/test/browser/browser_openPreferences.js
browser/components/payments/test/browser/browser_show_dialog.js
browser/components/payments/test/browser/head.js
toolkit/components/prompts/content/tabprompts.css
toolkit/themes/osx/global/tabprompts.css
toolkit/themes/windows/global/tabprompts.css
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -1089,23 +1089,18 @@ window._gBrowser = {
       return;
 
     let newBrowser = this.getBrowserForTab(newTab);
 
     // If there's a tabmodal prompt showing, focus it.
     if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
       let prompts = newBrowser.parentNode.getElementsByTagNameNS(this._XUL_NS, "tabmodalprompt");
       let prompt = prompts[prompts.length - 1];
-      // @tabmodalPromptShowing is also set for other tab modal prompts
-      // (e.g. the Payment Request dialog) so there may not be a <tabmodalprompt>.
-      // Bug 1492814 will implement this for the Payment Request dialog.
-      if (prompt) {
-        prompt.Dialog.setDefaultFocus();
-        return;
-      }
+      prompt.Dialog.setDefaultFocus();
+      return;
     }
 
     // Focus the location bar if it was previously focused for that tab.
     // In full screen mode, only bother making the location bar visible
     // if the tab is a blank one.
     if (newBrowser._urlbarFocused && gURLBar) {
       // Explicitly close the popup if the URL bar retains focus
       gURLBar.closePopup();
--- a/browser/components/payments/content/paymentDialogWrapper.js
+++ b/browser/components/payments/content/paymentDialogWrapper.js
@@ -7,25 +7,20 @@
  * own scope.
  */
 
 "use strict";
 
 const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"]
                      .getService(Ci.nsIPaymentRequestService);
 
-const paymentUISrv = Cc["@mozilla.org/dom/payments/payment-ui-service;1"]
-                     .getService(Ci.nsIPaymentUIService);
-
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
-                               "resource:///modules/BrowserWindowTracker.jsm");
 ChromeUtils.defineModuleGetter(this, "MasterPassword",
                                "resource://formautofill/MasterPassword.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
                                "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "formAutofillStorage", () => {
   let storage;
   try {
@@ -216,17 +211,17 @@ var paymentDialogWrapper = {
     this.mm.addMessageListener("paymentContentToChrome", this);
     this.mm.loadFrameScript("chrome://payments/content/paymentDialogFrameScript.js", true);
     // Until we have bug 1446164 and bug 1407418 we use form autofill's temporary
     // shim for data-localization* attributes.
     this.mm.loadFrameScript("chrome://formautofill/content/l10n.js", true);
     if (AppConstants.platform == "win") {
       this.frame.setAttribute("selectmenulist", "ContentSelectDropdown-windows");
     }
-    this.frame.setAttribute("src", "resource://payments/paymentRequest.xhtml");
+    this.frame.loadURI("resource://payments/paymentRequest.xhtml");
 
     this.temporaryStore = {
       addresses: new TempCollection("addresses"),
       creditCards: new TempCollection("creditCards"),
     };
   },
 
   createShowResponse({
@@ -452,17 +447,17 @@ var paymentDialogWrapper = {
     }
     return obj;
   },
 
   async initializeFrame() {
     Services.obs.addObserver(this, "formautofill-storage-changed", true);
 
     let requestSerialized = this._serializeRequest(this.request);
-    let chromeWindow = window.frameElement.ownerGlobal;
+    let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
     let isPrivate = PrivateBrowsingUtils.isWindowPrivate(chromeWindow);
 
     let [savedAddresses, savedBasicCards] =
       await Promise.all([this.fetchSavedAddresses(), this.fetchSavedPaymentCards()]);
 
     this.sendMessageToContent("showPaymentRequest", {
       request: requestSerialized,
       savedAddresses,
@@ -474,35 +469,38 @@ var paymentDialogWrapper = {
   },
 
   debugFrame() {
     // To avoid self-XSS-type attacks, ensure that Browser Chrome debugging is enabled.
     if (!Services.prefs.getBoolPref("devtools.chrome.enabled", false)) {
       Cu.reportError("devtools.chrome.enabled must be enabled to debug the frame");
       return;
     }
+    let chromeWindow = Services.wm.getMostRecentWindow(null);
     let {
       gDevToolsBrowser,
     } = ChromeUtils.import("resource://devtools/client/framework/gDevTools.jsm", {});
     gDevToolsBrowser.openContentProcessToolbox({
-      selectedBrowser: document.getElementById("paymentRequestFrame").frameLoader,
+      selectedBrowser: chromeWindow.document.getElementById("paymentRequestFrame").frameLoader,
     });
   },
 
   onOpenPreferences() {
-    BrowserWindowTracker.getTopWindow().openPreferences("privacy-form-autofill");
+    let prefsURL = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+    prefsURL.data = "about:preferences#privacy-form-autofill";
+    Services.ww.openWindow(null, AppConstants.BROWSER_CHROME_URL, "_blank", "chrome,all,dialog=no",
+                           prefsURL);
   },
 
   onPaymentCancel() {
     const showResponse = this.createShowResponse({
       acceptStatus: Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
     });
-
     paymentSrv.respondPayment(showResponse);
-    paymentUISrv.closePayment(this.request.requestId);
+    window.close();
   },
 
   async onPay({
     selectedPayerAddressGUID: payerGUID,
     selectedPaymentCardGUID: paymentCardGUID,
     selectedPaymentCardSecurityCode: cardSecurityCode,
   }) {
     let methodData = await this._convertProfileBasicCardToPaymentMethodData(paymentCardGUID,
@@ -564,17 +562,17 @@ var paymentDialogWrapper = {
     // the dialog before the onChangeShippingOption is called, thus
     // deleting the request and making the requestId invalid. Unclear
     // why we aren't seeing the same issue with onChangeShippingAddress.
     paymentSrv.changeShippingOption(this.request.requestId, optionID);
   },
 
   onCloseDialogMessage() {
     // The PR is complete(), just close the dialog
-    paymentUISrv.closePayment(this.request.requestId);
+    window.close();
   },
 
   async onUpdateAutofillRecord(collectionName, record, guid, messageID) {
     let responseMessage = {
       guid,
       messageID,
       stateChange: {},
     };
@@ -674,33 +672,24 @@ var paymentDialogWrapper = {
       case "openPreferences": {
         this.onOpenPreferences();
         break;
       }
       case "paymentCancel": {
         this.onPaymentCancel();
         break;
       }
-      case "paymentDialogReady": {
-        window.dispatchEvent(new Event("tabmodaldialogready", {
-          bubbles: true,
-        }));
-        break;
-      }
       case "pay": {
         this.onPay(data);
         break;
       }
       case "updateAutofillRecord": {
         this.onUpdateAutofillRecord(data.collectionName, data.record, data.guid, data.messageID);
         break;
       }
-      default: {
-        throw new Error(`paymentDialogWrapper: Unexpected messageType: ${messageType}`);
-      }
     }
   },
 };
 
 if ("document" in this) {
   // Running in a browser, not a unit test
   let frame = document.getElementById("paymentRequestFrame");
   let requestId = (new URLSearchParams(window.location.search)).get("requestId");
--- a/browser/components/payments/paymentUIService.js
+++ b/browser/components/payments/paymentUIService.js
@@ -10,22 +10,18 @@
  * PaymentUIService is started by the DOM code lazily.
  *
  * For now the UI is shown in a native dialog but that is likely to change.
  * Tests should try to avoid relying on that implementation detail.
  */
 
 "use strict";
 
-const XHTML_NS = "http://www.w3.org/1999/xhtml";
-
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
-                               "resource:///modules/BrowserWindowTracker.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this,
                                    "paymentSrv",
                                    "@mozilla.org/dom/payments/payment-request-service;1",
                                    "nsIPaymentRequestService");
 
 function PaymentUIService() {
   this.wrappedJSObject = this;
@@ -44,54 +40,20 @@ PaymentUIService.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
   DIALOG_URL: "chrome://payments/content/paymentDialogWrapper.xul",
   REQUEST_ID_PREFIX: "paymentRequest-",
 
   // nsIPaymentUIService implementation:
 
   showPayment(requestId) {
     this.log.debug("showPayment:", requestId);
-    let request = paymentSrv.getPaymentRequestById(requestId);
-    let merchantBrowser = this.findBrowserByTabId(request.tabId);
-    let chromeWindow = merchantBrowser.ownerGlobal;
-    let {gBrowser} = chromeWindow;
-    let browserContainer = gBrowser.getBrowserContainer(merchantBrowser);
-    let container = chromeWindow.document.createElementNS(XHTML_NS, "div");
-    container.dataset.requestId = requestId;
-    container.classList.add("paymentDialogContainer");
-    container.hidden = true;
-    let paymentsBrowser = chromeWindow.document.createElementNS(XHTML_NS, "iframe");
-    paymentsBrowser.classList.add("paymentDialogContainerFrame");
-    paymentsBrowser.setAttribute("type", "content");
-    paymentsBrowser.setAttribute("remote", "true");
-    paymentsBrowser.setAttribute("src", `${this.DIALOG_URL}?requestId=${requestId}`);
-    // append the frame to start the loading
-    container.appendChild(paymentsBrowser);
-    browserContainer.prepend(container);
-
-    // Only show the frame and change the UI when the dialog is ready to show.
-    paymentsBrowser.addEventListener("tabmodaldialogready", function readyToShow() {
-      if (!container) {
-        // The dialog was closed by the DOM code before it was ready to be shown.
-        return;
-      }
-      container.hidden = false;
-
-      // Prevent focusing or interacting with the <browser>.
-      merchantBrowser.setAttribute("tabmodalPromptShowing", "true");
-
-      // Darken the merchant content area.
-      let tabModalBackground = chromeWindow.document.createElement("box");
-      tabModalBackground.classList.add("tabModalBackground", "paymentDialogBackground");
-      // Insert the same way as <tabmodalprompt>.
-      merchantBrowser.parentNode.insertBefore(tabModalBackground,
-                                              merchantBrowser.nextElementSibling);
-    }, {
-      once: true,
-    });
+    let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
+    chromeWindow.openDialog(`${this.DIALOG_URL}?requestId=${requestId}`,
+                            `${this.REQUEST_ID_PREFIX}${requestId}`,
+                            "modal,dialog,centerscreen,resizable=no");
   },
 
   abortPayment(requestId) {
     this.log.debug("abortPayment:", requestId);
     let abortResponse = Cc["@mozilla.org/dom/payments/payment-abort-action-response;1"]
                           .createInstance(Ci.nsIPaymentAbortActionResponse);
     let found = this.closeDialog(requestId);
 
@@ -114,107 +76,76 @@ PaymentUIService.prototype = {
     switch (completeStatus) {
       case "fail":
       case "timeout":
         break;
       default:
         closed = this.closeDialog(requestId);
         break;
     }
-
-    let dialogContainer;
-    if (!closed) {
-      // We need to call findDialog before we respond below as getPaymentRequestById
-      // may fail due to the request being removed upon completion.
-      dialogContainer = this.findDialog(requestId).dialogContainer;
-      if (!dialogContainer) {
-        this.log.error("completePayment: no dialog found");
-        return;
-      }
-    }
-
     let responseCode = closed ?
         Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED :
         Ci.nsIPaymentActionResponse.COMPLETE_FAILED;
     let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"]
                              .createInstance(Ci.nsIPaymentCompleteActionResponse);
     completeResponse.init(requestId, responseCode);
     paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
 
     if (!closed) {
-      dialogContainer.querySelector("iframe").contentWindow.paymentDialogWrapper.updateRequest();
+      let dialog = this.findDialog(requestId);
+      if (!dialog) {
+        this.log.error("completePayment: no dialog found");
+        return;
+      }
+      dialog.paymentDialogWrapper.updateRequest();
     }
   },
 
   updatePayment(requestId) {
-    let {dialogContainer} = this.findDialog(requestId);
+    let dialog = this.findDialog(requestId);
     this.log.debug("updatePayment:", requestId);
-    if (!dialogContainer) {
+    if (!dialog) {
       this.log.error("updatePayment: no dialog found");
       return;
     }
-    dialogContainer.querySelector("iframe").contentWindow.paymentDialogWrapper.updateRequest();
+    dialog.paymentDialogWrapper.updateRequest();
   },
 
   closePayment(requestId) {
     this.closeDialog(requestId);
   },
 
   // other helper methods
 
   /**
    * @param {string} requestId - Payment Request ID of the dialog to close.
    * @returns {boolean} whether the specified dialog was closed.
    */
   closeDialog(requestId) {
-    let {
-      browser,
-      dialogContainer,
-    } = this.findDialog(requestId);
-    if (!dialogContainer) {
+    let win = this.findDialog(requestId);
+    if (!win) {
       return false;
     }
-    this.log.debug(`closing: ${requestId}`);
-    dialogContainer.remove();
-    if (!dialogContainer.hidden) {
-      // If the container is no longer hidden then the background was added after
-      // `tabmodaldialogready` so remove it.
-      browser.parentElement.querySelector(".paymentDialogBackground").remove();
-
-      if (!browser.tabModalPromptBox || browser.tabModalPromptBox.listPrompts().length == 0) {
-        browser.removeAttribute("tabmodalPromptShowing");
-      }
-    }
+    this.log.debug(`closing: ${win.name}`);
+    win.close();
     return true;
   },
 
   findDialog(requestId) {
-    for (let win of BrowserWindowTracker.orderedWindows) {
-      for (let dialogContainer of win.document.querySelectorAll(".paymentDialogContainer")) {
-        if (dialogContainer.dataset.requestId == requestId) {
-          return {
-            dialogContainer,
-            browser: dialogContainer.parentElement.querySelector("browser"),
-          };
-        }
-      }
-    }
-    return {};
-  },
-
-  findBrowserByTabId(tabId) {
-    for (let win of BrowserWindowTracker.orderedWindows) {
-      for (let browser of win.gBrowser.browsers) {
-        if (!browser.frameLoader || !browser.frameLoader.tabParent) {
-          continue;
-        }
-        if (browser.frameLoader.tabParent.tabId == tabId) {
-          return browser;
-        }
+    for (let win of Services.wm.getEnumerator(null)) {
+      if (win.name == `${this.REQUEST_ID_PREFIX}${requestId}`) {
+        return win;
       }
     }
 
-    this.log.error("findBrowserByTabId: No browser found for tabId:", tabId);
     return null;
   },
+
+  requestIdForWindow(window) {
+    let windowName = window.name;
+
+    return windowName.startsWith(this.REQUEST_ID_PREFIX) ?
+      windowName.replace(this.REQUEST_ID_PREFIX, "") : // returns suffix, which is the requestId
+      null;
+  },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUIService]);
--- a/browser/components/payments/res/containers/payment-dialog.js
+++ b/browser/components/payments/res/containers/payment-dialog.js
@@ -380,17 +380,17 @@ export default class PaymentDialog exten
     this._renderPayerFields(state);
 
     let isMac = /mac/i.test(navigator.platform);
     for (let manageTextEl of this._manageText.children) {
       manageTextEl.hidden = manageTextEl.dataset.os == "mac" ? !isMac : isMac;
       let link = manageTextEl.querySelector("a");
       // The href is only set to be exposed to accessibility tools so users know what will open.
       // The actual opening happens from the click event listener.
-      link.href = "about:preferences#privacy-form-autofill";
+      link.href = "about:preferences#privacy-address-autofill";
     }
 
     this._renderPayButton(state);
 
     for (let page of this._mainContainer.querySelectorAll(":scope > .page")) {
       page.hidden = state.page.id != page.id;
     }
 
--- a/browser/components/payments/res/paymentRequest.js
+++ b/browser/components/payments/res/paymentRequest.js
@@ -104,16 +104,17 @@ var paymentRequest = {
         break;
       }
     }
   },
 
   onPaymentRequestLoad() {
     log.debug("onPaymentRequestLoad");
     window.addEventListener("unload", this, {once: true});
+    this.sendMessageToChrome("paymentDialogReady");
 
     // Automatically show the debugging console if loaded with a truthy `debug` query parameter.
     if (new URLSearchParams(location.search).get("debug")) {
       this.toggleDebuggingConsole();
     }
   },
 
   async onShowPaymentRequest(detail) {
@@ -164,18 +165,16 @@ var paymentRequest = {
     } else if (!hasSavedCards) {
       state.page = {
         id: "basic-card-page",
         onboardingWizard: true,
       };
     }
 
     paymentDialog.setStateFromParent(state);
-
-    this.sendMessageToChrome("paymentDialogReady");
   },
 
   openPreferences() {
     this.sendMessageToChrome("openPreferences");
   },
 
   cancel() {
     this.sendMessageToChrome("paymentCancel");
--- a/browser/components/payments/test/PaymentTestUtils.jsm
+++ b/browser/components/payments/test/PaymentTestUtils.jsm
@@ -107,29 +107,25 @@ var PaymentTestUtils = {
 
     /**
      * Create a new payment request cached as `rq` and then show it.
      *
      * @param {Object} args
      * @param {PaymentMethodData[]} methodData
      * @param {PaymentDetailsInit} details
      * @param {PaymentOptions} options
-     * @returns {Object}
      */
     createAndShowRequest: ({methodData, details, options}) => {
       const rq = new content.PaymentRequest(Cu.cloneInto(methodData, content), details, options);
       content.rq = rq; // assign it so we can retrieve it later
 
       const handle = content.windowUtils.setHandlingUserInput(true);
       content.showPromise = rq.show();
 
       handle.destruct();
-      return {
-        requestId: rq.id,
-      };
     },
   },
 
   DialogContentTasks: {
     getShippingOptions: () => {
       let picker = content.document.querySelector("shipping-option-picker");
       let popupBox = Cu.waiveXrays(picker).dropdown.popupBox;
       let selectedOptionIndex = popupBox.selectedIndex;
--- a/browser/components/payments/test/browser/browser_dropdowns.js
+++ b/browser/components/payments/test/browser/browser_dropdowns.js
@@ -40,16 +40,14 @@ add_task(async function test_dropdown() 
 
     let event = await popupshownPromise;
     let expectedPopupID = "ContentSelectDropdown";
     if (AppConstants.platform == "win") {
       expectedPopupID = "ContentSelectDropdown-windows";
     }
     is(event.target.parentElement.id, expectedPopupID, "Checked menulist of opened popup");
 
-    event.target.hidePopup(true);
-
     info("clicking cancel");
     spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
 
     await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
   });
 });
--- a/browser/components/payments/test/browser/browser_openPreferences.js
+++ b/browser/components/payments/test/browser/browser_openPreferences.js
@@ -15,18 +15,19 @@ add_task(async function test_openPrefere
     url: BLANK_PAGE_URL,
   }, async browser => {
     let {win, frame} = await setupPaymentDialog(browser, {
       methodData,
       details,
       merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
     });
 
-    let prefsTabPromise = BrowserTestUtils.waitForNewTab(gBrowser,
-                                                         "about:preferences#privacy-form-autofill");
+    let prefsWindowPromise = BrowserTestUtils.waitForNewWindow({
+      url: "about:preferences#privacy",
+    });
 
     let prefsLoadedPromise = TestUtils.topicObserved("sync-pane-loaded");
 
     await spawnPaymentDialogTask(frame, function verifyPrefsLink({isMac}) {
       let manageTextEl = content.document.querySelector(".manage-text");
 
       let expectedVisibleEl;
       if (isMac) {
@@ -43,18 +44,18 @@ add_task(async function test_openPrefere
       let prefsLink = expectedVisibleEl.querySelector("a");
       ok(prefsLink, "Preferences link should exist");
       prefsLink.scrollIntoView();
       EventUtils.synthesizeMouseAtCenter(prefsLink, {}, content);
     }, {
       isMac: AppConstants.platform == "macosx",
     });
 
-    let prefsTab = await prefsTabPromise;
-    ok(prefsTab, "Ensure a tab was opened");
+    let browserWin = await prefsWindowPromise;
+    ok(browserWin, "Ensure a window was opened");
     await prefsLoadedPromise;
 
-    await BrowserTestUtils.removeTab(prefsTab);
+    await BrowserTestUtils.closeWindow(browserWin);
 
     spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
     await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
   });
 });
--- a/browser/components/payments/test/browser/browser_show_dialog.js
+++ b/browser/components/payments/test/browser/browser_show_dialog.js
@@ -246,80 +246,8 @@ add_task(async function test_supportedNe
     await spawnPaymentDialogTask(frame, async () => {
       ok(!content.document.getElementById("pay").disabled, "pay button should not be disabled");
     });
 
     spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
     await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
   });
 });
-
-add_task(async function test_tab_modal() {
-  await BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: BLANK_PAGE_URL,
-  }, async browser => {
-    let {win, frame} = await setupPaymentDialog(browser, {
-      methodData,
-      details,
-      merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
-    });
-
-    await TestUtils.waitForCondition(() => {
-      return !document.querySelector(".paymentDialogContainer").hidden;
-    }, "Waiting for container to be visible after the dialog's ready");
-
-    ok(!EventUtils.isHidden(win.frameElement), "Frame should be visible");
-
-    let {
-      bottom: toolboxBottom,
-    } = document.getElementById("navigator-toolbox").getBoundingClientRect();
-
-    let {x, y} = win.frameElement.getBoundingClientRect();
-    ok(y > 0, "Frame should have y > 0");
-    // Inset by 10px since the corner point doesn't return the frame due to the
-    // border-radius.
-    is(document.elementFromPoint(x + 10, y + 10), win.frameElement,
-       "Check .paymentDialogContainerFrame is visible");
-
-    info("Click to the left of the dialog over the content area");
-    isnot(document.elementFromPoint(x - 10, y + 50), browser,
-          "Check clicks on the merchant content area don't go to the browser");
-    is(document.elementFromPoint(x - 10, y + 50),
-       document.querySelector(".paymentDialogBackground"),
-       "Check clicks on the merchant content area go to the payment dialog background");
-
-    ok(y < toolboxBottom - 2, "Dialog should overlap the toolbox by at least 2px");
-
-    ok(browser.hasAttribute("tabmodalPromptShowing"), "Check browser has @tabmodalPromptShowing");
-
-    await BrowserTestUtils.withNewTab({
-      gBrowser,
-      url: BLANK_PAGE_URL,
-    }, async newBrowser => {
-      let {
-        x: x2,
-        y: y2,
-      } = win.frameElement.getBoundingClientRect();
-      is(x2, x, "Check x-coordinate is the same");
-      is(y2, y, "Check y-coordinate is the same");
-      isnot(document.elementFromPoint(x + 10, y + 10), win.frameElement,
-            "Check .paymentDialogContainerFrame is hidden");
-      ok(!newBrowser.hasAttribute("tabmodalPromptShowing"),
-         "Check second browser doesn't have @tabmodalPromptShowing");
-    });
-
-    let {
-      x: x3,
-      y: y3,
-    } = win.frameElement.getBoundingClientRect();
-    is(x3, x, "Check x-coordinate is the same again");
-    is(y3, y, "Check y-coordinate is the same again");
-    is(document.elementFromPoint(x + 10, y + 10), win.frameElement,
-       "Check .paymentDialogContainerFrame is visible again");
-
-    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
-    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
-
-    await BrowserTestUtils.waitForCondition(() => !browser.hasAttribute("tabmodalPromptShowing"),
-                                            "Check @tabmodalPromptShowing was removed");
-  });
-});
--- a/browser/components/payments/test/browser/head.js
+++ b/browser/components/payments/test/browser/head.js
@@ -12,48 +12,43 @@ const BLANK_PAGE_PATH = "/browser/browse
 const BLANK_PAGE_URL = "https://example.com" + BLANK_PAGE_PATH;
 const RESPONSE_TIMEOUT_PREF = "dom.payments.response.timeout";
 const SAVE_CREDITCARD_DEFAULT_PREF = "dom.payments.defaults.saveCreditCard";
 const SAVE_ADDRESS_DEFAULT_PREF = "dom.payments.defaults.saveAddress";
 
 const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"]
                      .getService(Ci.nsIPaymentRequestService);
 const paymentUISrv = Cc["@mozilla.org/dom/payments/payment-ui-service;1"]
-                     .getService(Ci.nsIPaymentUIService).wrappedJSObject;
+                     .getService().wrappedJSObject;
 const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
 const {formAutofillStorage} = ChromeUtils.import(
   "resource://formautofill/FormAutofillStorage.jsm", {});
 const {PaymentTestUtils: PTU} = ChromeUtils.import(
   "resource://testing-common/PaymentTestUtils.jsm", {});
-ChromeUtils.import("resource:///modules/BrowserWindowTracker.jsm");
 ChromeUtils.import("resource://gre/modules/CreditCard.jsm");
 
 function getPaymentRequests() {
   return Array.from(paymentSrv.enumerate());
 }
 
 /**
  * Return the container (e.g. dialog or overlay) that the payment request contents are shown in.
- * This abstracts away the details of the widget used so that this can more easily transition to
- * another kind of dialog/overlay.
- * @param {string} requestId
+ * This abstracts away the details of the widget used so that this can more earily transition from a
+ * dialog to another kind of overlay.
+ * Consumers shouldn't rely on a dialog window being returned.
  * @returns {Promise}
  */
-async function getPaymentWidget(requestId) {
-  return BrowserTestUtils.waitForCondition(() => {
-    let {dialogContainer} = paymentUISrv.findDialog(requestId);
-    if (!dialogContainer) {
-      return false;
-    }
-    let browserIFrame = dialogContainer.querySelector("iframe");
-    if (!browserIFrame) {
-      return false;
-    }
-    return browserIFrame.contentWindow;
-  }, "payment dialog should be opened");
+async function getPaymentWidget() {
+  let win;
+  await BrowserTestUtils.waitForCondition(() => {
+    win = Services.wm.getMostRecentWindow(null);
+    return win.name.startsWith(paymentUISrv.REQUEST_ID_PREFIX);
+  }, "payment dialog should be the most recent");
+
+  return win;
 }
 
 async function getPaymentFrame(widget) {
   return widget.document.getElementById("paymentRequestFrame");
 }
 
 function waitForMessageFromWidget(messageType, widget = null) {
   info("waitForMessageFromWidget: " + messageType);
@@ -237,28 +232,29 @@ function checkPaymentMethodDetailsMatche
  * @param {Object} options.methodData
  * @param {Object} options.details
  * @param {Object} options.options
  * @param {Function} options.merchantTaskFn
  * @returns {Object} References to the window, requestId, and frame
  */
 async function setupPaymentDialog(browser, {methodData, details, options, merchantTaskFn}) {
   let dialogReadyPromise = waitForWidgetReady();
-  let {requestId} = await ContentTask.spawn(browser,
-                                            {
-                                              methodData,
-                                              details,
-                                              options,
-                                            },
-                                            merchantTaskFn);
-  ok(requestId, "requestId should be defined");
+  await ContentTask.spawn(browser,
+                          {
+                            methodData,
+                            details,
+                            options,
+                          },
+                          merchantTaskFn);
 
   // get a reference to the UI dialog and the requestId
-  let [win] = await Promise.all([getPaymentWidget(requestId), dialogReadyPromise]);
+  let [win] = await Promise.all([getPaymentWidget(), dialogReadyPromise]);
   ok(win, "Got payment widget");
+  let requestId = paymentUISrv.requestIdForWindow(win);
+  ok(requestId, "requestId should be defined");
   is(win.closed, false, "dialog should not be closed");
 
   let frame = await getPaymentFrame(win);
   ok(frame, "Got payment frame");
 
   await dialogReadyPromise;
   info("dialog ready");
 
--- a/toolkit/components/prompts/content/tabprompts.css
+++ b/toolkit/components/prompts/content/tabprompts.css
@@ -1,14 +1,13 @@
 /* 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/. */
 
 /* Tab Modal Prompt boxes */
-.tabModalBackground,
 tabmodalprompt {
   width: 100%;
   height: 100%;
   -moz-box-pack: center;
   -moz-box-orient: vertical;
 }
 
 .tabmodalprompt-mainContainer {
@@ -29,24 +28,8 @@ tabmodalprompt {
   cursor: text !important;
   white-space: pre-wrap;
   unicode-bidi: plaintext;
 }
 
 tabmodalprompt label[value=""] {
   visibility: collapse;
 }
-
-/* Tab-Modal Payment Request widget */
-.paymentDialogContainer {
-  position: absolute;
-}
-
-.paymentDialogContainerFrame {
-  box-sizing: border-box;
-  height: 500px;
-  /* Center the dialog with 20% on the left/right and 60% width for content */
-  left: 20%;
-  position: absolute;
-  /* Overlap the chrome */
-  top: -6px;
-  width: 60%;
-}
--- a/toolkit/themes/osx/global/tabprompts.css
+++ b/toolkit/themes/osx/global/tabprompts.css
@@ -1,24 +1,19 @@
 /* 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/. */
 
 /* Tab Modal Prompt boxes */
-.tabModalBackground,
 tabmodalprompt {
   background-color: hsla(0,0%,10%,.5);
-}
-
-tabmodalprompt {
   font-family: sans-serif; /* use content font not system UI font */
   font-size: 110%;
 }
 
-.paymentDialogContainerFrame,
 .tabmodalprompt-mainContainer {
   color: black;
   background-color: hsla(0,0%,100%,.95);
   background-clip: padding-box;
   border-radius: 2px;
   border: 1px solid hsla(0,0%,0%,.5);
 }
 
--- a/toolkit/themes/windows/global/tabprompts.css
+++ b/toolkit/themes/windows/global/tabprompts.css
@@ -1,23 +1,18 @@
 /* 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/. */
 
 /* Tab Modal Prompt boxes */
-.tabModalBackground,
 tabmodalprompt {
   background-color: hsla(0,0%,10%,.5);
-}
-
-tabmodalprompt {
   font-family: sans-serif; /* use content font not system UI font */
 }
 
-.paymentDialogContainerFrame,
 .tabmodalprompt-mainContainer {
   color: -moz-fieldText;
   background-color: -moz-field;
   border-radius: 2px;
   border: 1px solid threeDDarkShadow;
 }
 
 .tabmodalprompt-topContainer {