Bug 1877469 - [webdriver-bidi] Await visibilitystatus change for previously selected tab when creating or switching tabs. r=webdriver-reviewers,Sasha

Differential Revision: https://phabricator.services.mozilla.com/D201061
This commit is contained in:
Henrik Skupin 2024-02-09 12:18:26 +00:00
Родитель 7bf1636592
Коммит bdbbb4eca8
4 изменённых файлов: 88 добавлений и 10 удалений

Просмотреть файл

@ -145,6 +145,9 @@ const COMMON_PREFERENCES = new Map([
// Do not redirect user when a milstone upgrade of Firefox is detected
["browser.startup.homepage_override.mstone", "ignore"],
// Unload the previously selected tab immediately
["browser.tabs.remote.unloadDelayMs", 0],
// Don't unload tabs when available memory is running low
["browser.tabs.unloadOnLowMemory", false],

Просмотреть файл

@ -885,7 +885,7 @@
{
"testIdPattern": "[page.spec] Page Page.bringToFront should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{

Просмотреть файл

@ -232,11 +232,25 @@ class BrowsingContextModule extends Module {
);
}
const tab = lazy.TabManager.getTabForBrowsingContext(context);
const window = lazy.TabManager.getWindowForTab(tab);
const targetTab = lazy.TabManager.getTabForBrowsingContext(context);
const targetWindow = lazy.TabManager.getWindowForTab(targetTab);
const selectedTab = lazy.TabManager.getTabBrowser(targetWindow).selectedTab;
await lazy.windowManager.focusWindow(window);
await lazy.TabManager.selectTab(tab);
const activated = [
lazy.windowManager.focusWindow(targetWindow),
lazy.TabManager.selectTab(targetTab),
];
if (targetTab !== selectedTab) {
// We need to wait until the "document.visibilityState" of the currently
// selected tab in the target window is marked as "hidden".
const selectedBrowser = lazy.TabManager.getBrowserForTab(selectedTab);
activated.push(
this.#waitForVisibilityChange(selectedBrowser.browsingContext)
);
}
await Promise.all(activated);
}
/**
@ -547,17 +561,39 @@ class BrowsingContextModule extends Module {
);
}
// The window to open the new tab in.
let window = Services.wm.getMostRecentWindow(null);
let referenceTab;
if (referenceContext !== null) {
referenceTab =
lazy.TabManager.getTabForBrowsingContext(referenceContext);
window = lazy.TabManager.getWindowForTab(referenceTab);
}
const tab = await lazy.TabManager.addTab({
focus: !background,
referenceTab,
userContextId: userContext,
});
const promises = [];
if (!background) {
// When opening a new foreground tab we need to wait until the
// "document.visibilityState" of the currently selected tab in this
// window is marked as "hidden".
const selectedTab = lazy.TabManager.getTabBrowser(window).selectedTab;
promises.push(
this.#waitForVisibilityChange(
lazy.TabManager.getBrowserForTab(selectedTab).browsingContext
)
);
}
promises.unshift(
lazy.TabManager.addTab({
focus: !background,
referenceTab,
userContextId: userContext,
})
);
const [tab] = await Promise.all(promises);
browser = lazy.TabManager.getBrowserForTab(tab);
}
@ -1918,6 +1954,21 @@ class BrowsingContextModule extends Module {
}
}
#waitForVisibilityChange(browsingContext) {
return this.messageHandler.forwardCommand({
moduleName: "browsingContext",
commandName: "_awaitVisibilityState",
destination: {
type: lazy.WindowGlobalMessageHandler.type,
id: browsingContext.id,
},
params: {
value: "hidden",
},
retryOnAbort: true,
});
}
/**
* Internal commands
*/

Просмотреть файл

@ -17,6 +17,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
"chrome://remote/content/webdriver-bidi/modules/root/browsingContext.sys.mjs",
OriginType:
"chrome://remote/content/webdriver-bidi/modules/root/browsingContext.sys.mjs",
PollPromise: "chrome://remote/content/shared/Sync.sys.mjs",
});
const DOCUMENT_FRAGMENT_NODE = 11;
@ -356,6 +357,29 @@ class BrowsingContextModule extends WindowGlobalBiDiModule {
});
}
/**
* Waits until the visibility state of the document has the expected value.
*
* @param {object} options
* @param {number} options.value
* Expected value of the visibility state.
*
* @returns {Promise}
* Promise that resolves when the visibility state has the expected value.
*/
async _awaitVisibilityState(options) {
const { value } = options;
const win = this.messageHandler.window;
await lazy.PollPromise((resolve, reject) => {
if (win.document.visibilityState === value) {
resolve();
} else {
reject();
}
});
}
_getBaseURL() {
return this.messageHandler.window.document.baseURI;
}