fune/browser/components/uitour/test/browser_UITour_detach_tab.js
Emilio Cobos Álvarez 2e05768081 Bug 1578379 - Make pageshow / pagehide during frame loader swaps not mess with document visibility. r=bzbarsky
Also while doing it:

 * Ensure activity observers get notified after visibility is computed already.
This is how we notify all other activity observers already, and we are
double-notifying in the case we actually get a page show _and_ a visibility
change, but this is a pre-existing problem.

 * Remove special-cases for InFrameSwap() from MediaRecorder. Now that pagehide
doesn't mess up with our visibility state the regular check just works. I
ensured I didn't regress bug 1444541.

 * Had to fix a UITour test that relied on the visibility changing back and
forth for the detached tab. It seems there's no real place in UITour that
listens to that event so we should be good.

 * Added tests, verifying that they both fail without the patch.

After this we can remove nsDocShell::InFrameSwap(), as the only caller is the
assertion, but I wanted to keep it regardless, at least for now, until this
patch has been in for a bit.

Differential Revision: https://phabricator.services.mozilla.com/D45906

--HG--
extra : moz-landing-system : lando
2019-09-23 10:16:44 +00:00

125 lines
3.7 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Detaching a tab to a new window shouldn't break the menu panel.
*/
"use strict";
var gTestTab;
var gContentAPI;
var gContentWindow;
var gContentDoc;
function test() {
registerCleanupFunction(function() {
gContentDoc = null;
});
UITourTest();
}
/**
* When tab is changed we're tearing the tour down. So the UITour client has to always be aware of this
* fact and therefore listens to pageshow events.
* In particular this scenario happens for detaching the tab (ie. moving it to a new window).
*/
var tests = [
taskify(async function test_move_tab_to_new_window() {
const myDocIdentifier =
"Hello, I'm a unique expando to identify this document.";
let highlight = document.getElementById("UITourHighlight");
let windowDestroyedDeferred = PromiseUtils.defer();
let onDOMWindowDestroyed = aWindow => {
if (gContentWindow && aWindow == gContentWindow) {
Services.obs.removeObserver(
onDOMWindowDestroyed,
"dom-window-destroyed"
);
windowDestroyedDeferred.resolve();
}
};
let browserStartupDeferred = PromiseUtils.defer();
Services.obs.addObserver(function onBrowserDelayedStartup(aWindow) {
Services.obs.removeObserver(
onBrowserDelayedStartup,
"browser-delayed-startup-finished"
);
browserStartupDeferred.resolve(aWindow);
}, "browser-delayed-startup-finished");
await ContentTask.spawn(
gBrowser.selectedBrowser,
myDocIdentifier,
contentMyDocIdentifier => {
let onPageShow = () => {
if (!content.document.hidden) {
let win = Cu.waiveXrays(content);
win.Mozilla.UITour.showHighlight("appMenu");
}
};
content.window.addEventListener("pageshow", onPageShow, {
mozSystemGroup: true,
});
content.document.myExpando = contentMyDocIdentifier;
}
);
gContentAPI.showHighlight("appMenu");
await elementVisiblePromise(highlight, "old window highlight");
gContentWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
await browserStartupDeferred.promise;
// This highlight should be shown thanks to the pageshow listener.
let newWindowHighlight = gContentWindow.document.getElementById(
"UITourHighlight"
);
await elementVisiblePromise(newWindowHighlight, "new window highlight");
let selectedTab = gContentWindow.gBrowser.selectedTab;
await ContentTask.spawn(
selectedTab.linkedBrowser,
myDocIdentifier,
contentMyDocIdentifier => {
is(
content.document.myExpando,
contentMyDocIdentifier,
"Document should be selected in new window"
);
}
);
ok(
UITour.tourBrowsersByWindow &&
UITour.tourBrowsersByWindow.has(gContentWindow),
"Window should be known"
);
ok(
UITour.tourBrowsersByWindow
.get(gContentWindow)
.has(selectedTab.linkedBrowser),
"Selected browser should be known"
);
// Need this because gContentAPI in e10s land will try to use gTestTab to
// spawn a content task, which doesn't work if the tab is dead, for obvious
// reasons.
gTestTab = gContentWindow.gBrowser.selectedTab;
let shownPromise = promisePanelShown(gContentWindow);
gContentAPI.showMenu("appMenu");
await shownPromise;
isnot(gContentWindow.PanelUI.panel.state, "closed", "Panel should be open");
gContentAPI.hideHighlight();
gContentAPI.hideMenu("appMenu");
gTestTab = null;
Services.obs.addObserver(onDOMWindowDestroyed, "dom-window-destroyed");
gContentWindow.close();
await windowDestroyedDeferred.promise;
}),
];