From 45df9472d71b73cc07105c279a38fbf731a670a1 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Sun, 27 Mar 2022 08:58:10 +0000 Subject: [PATCH 1/5] Bug 1758502 - [remote] Add TabManager.getBrowsingContextById API r=webdriver-reviewers,whimboo Differential Revision: https://phabricator.services.mozilla.com/D141944 --- remote/shared/TabManager.jsm | 19 +++++++++- remote/shared/moz.build | 1 + remote/shared/test/browser/browser.ini | 5 +++ .../shared/test/browser/browser_TabManager.js | 35 +++++++++++++++++++ .../modules/root/browsingContext.jsm | 10 ++---- 5 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 remote/shared/test/browser/browser.ini create mode 100644 remote/shared/test/browser/browser_TabManager.js diff --git a/remote/shared/TabManager.jsm b/remote/shared/TabManager.jsm index bfebcbc65c0b..02b567ef43fb 100644 --- a/remote/shared/TabManager.jsm +++ b/remote/shared/TabManager.jsm @@ -135,7 +135,7 @@ var TabManager = { }, /** - * Retrieve a the browser element corresponding to the provided unique id, + * Retrieve the browser element corresponding to the provided unique id, * previously generated via getIdForBrowser. * * TODO: To avoid creating strong references on browser elements and @@ -163,6 +163,23 @@ var TabManager = { return null; }, + /** + * Retrieve the browsing context corresponding to the provided unique id. + * + * @param {String} id + * A browsing context unique id (created by getIdForBrowsingContext). + * @return {BrowsingContext=} + * The browsing context found for this id, null if none was found. + */ + getBrowsingContextById(id) { + const browser = this.getBrowserById(id); + if (browser) { + return browser.browsingContext; + } + + return BrowsingContext.get(id); + }, + /** * Retrieve the unique id for the given xul browser element. The id is a * dynamically generated uuid associated with the permanentKey property of the diff --git a/remote/shared/moz.build b/remote/shared/moz.build index 4341016ad2c5..8395d2d5dc7a 100644 --- a/remote/shared/moz.build +++ b/remote/shared/moz.build @@ -6,6 +6,7 @@ BROWSER_CHROME_MANIFESTS += [ "listeners/test/browser/browser.ini", "messagehandler/test/browser/broadcast/browser.ini", "messagehandler/test/browser/browser.ini", + "test/browser/browser.ini", ] XPCSHELL_TESTS_MANIFESTS += [ diff --git a/remote/shared/test/browser/browser.ini b/remote/shared/test/browser/browser.ini new file mode 100644 index 000000000000..af0889ca7fca --- /dev/null +++ b/remote/shared/test/browser/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] +tags = remote +subsuite = remote + +[browser_TabManager.js] diff --git a/remote/shared/test/browser/browser_TabManager.js b/remote/shared/test/browser/browser_TabManager.js new file mode 100644 index 000000000000..1d79e79398bb --- /dev/null +++ b/remote/shared/test/browser/browser_TabManager.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { TabManager } = ChromeUtils.import( + "chrome://remote/content/shared/TabManager.jsm" +); + +const FRAME_URL = "https://example.com/document-builder.sjs?html=frame"; +const FRAME_MARKUP = ``; +const TEST_URL = `https://example.com/document-builder.sjs?html=${encodeURI( + FRAME_MARKUP +)}`; + +add_task(async function test_getBrowsingContextById() { + const browser = gBrowser.selectedBrowser; + + is(TabManager.getBrowsingContextById(null), null); + is(TabManager.getBrowsingContextById(undefined), null); + is(TabManager.getBrowsingContextById("wrong-id"), null); + + info(`Navigate to ${TEST_URL}`); + const loaded = BrowserTestUtils.browserLoaded(browser); + BrowserTestUtils.loadURI(browser, TEST_URL); + await loaded; + + const contexts = browser.browsingContext.getAllBrowsingContextsInSubtree(); + is(contexts.length, 2, "Top context has 1 child"); + + const topContextId = TabManager.getIdForBrowsingContext(contexts[0]); + is(TabManager.getBrowsingContextById(topContextId), contexts[0]); + const childContextId = TabManager.getIdForBrowsingContext(contexts[1]); + is(TabManager.getBrowsingContextById(childContextId), contexts[1]); +}); diff --git a/remote/webdriver-bidi/modules/root/browsingContext.jsm b/remote/webdriver-bidi/modules/root/browsingContext.jsm index d1f87fc26534..cae598e16220 100644 --- a/remote/webdriver-bidi/modules/root/browsingContext.jsm +++ b/remote/webdriver-bidi/modules/root/browsingContext.jsm @@ -107,13 +107,7 @@ class BrowsingContextModule extends Module { `Expected "parent" to be a string, got ${parentId}` ); - // If the parent id is for a top-level browsing context get the browsing - // context via the unique id and the related content browser. - const browser = TabManager.getBrowserById(parentId); - contexts = - browser !== null - ? [browser.browsingContext] - : [this.#getBrowsingContext(parentId)]; + contexts = [this.#getBrowsingContext(parentId)]; } else { // Return all top-level browsing contexts. contexts = TabManager.browsers.map(browser => browser.browsingContext); @@ -143,7 +137,7 @@ class BrowsingContextModule extends Module { return null; } - const context = BrowsingContext.get(contextId); + const context = TabManager.getBrowsingContextById(contextId); if (context === null) { throw new error.NoSuchFrameError( `Browsing Context with id ${contextId} not found` From 591076c81b098cd4f0ccece0c104195b854d1b36 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Sun, 27 Mar 2022 08:58:11 +0000 Subject: [PATCH 2/5] Bug 1758502 - [webdriver-bidi] Implement the browsingContext.close command r=webdriver-reviewers,whimboo Depends on D141944 Differential Revision: https://phabricator.services.mozilla.com/D141678 --- .../modules/root/browsingContext.jsm | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/remote/webdriver-bidi/modules/root/browsingContext.jsm b/remote/webdriver-bidi/modules/root/browsingContext.jsm index cae598e16220..5719bcfe3076 100644 --- a/remote/webdriver-bidi/modules/root/browsingContext.jsm +++ b/remote/webdriver-bidi/modules/root/browsingContext.jsm @@ -17,12 +17,17 @@ XPCOMUtils.defineLazyModuleGetters(this, { ContextDescriptorType: "chrome://remote/content/shared/messagehandler/MessageHandler.jsm", error: "chrome://remote/content/shared/webdriver/Errors.jsm", + Log: "chrome://remote/content/shared/Log.jsm", Module: "chrome://remote/content/shared/messagehandler/Module.jsm", TabManager: "chrome://remote/content/shared/TabManager.jsm", waitForInitialNavigationCompleted: "chrome://remote/content/shared/Navigate.jsm", }); +XPCOMUtils.defineLazyGetter(this, "logger", () => + Log.get(Log.TYPES.WEBDRIVER_BIDI) +); + class BrowsingContextModule extends Module { #contextListener; @@ -45,6 +50,53 @@ class BrowsingContextModule extends Module { this.#contextListener.destroy(); } + /** + * Close the provided browsing context. + * + * @param {Object=} options + * @param {string} context + * Id of the browsing context to close. + * + * @throws {NoSuchFrameError} + * If the browsing context cannot be found. + * @throws {InvalidArgumentError} + * If the browsing context is not a top-level one. + */ + close(options = {}) { + const { context: contextId } = options; + + assert.string( + contextId, + `Expected "context" to be a string, got ${contextId}` + ); + + const context = TabManager.getBrowsingContextById(contextId); + if (!context) { + throw new error.NoSuchFrameError( + `Browsing Context with id ${contextId} not found` + ); + } + + if (context.parent) { + throw new error.InvalidArgumentError( + `Browsing Context with id ${contextId} is not top-level` + ); + } + + if (TabManager.getTabCount() === 1) { + // The behavior when closing the last tab is currently unspecified. + // Warn the consumer about potential issues + logger.warn( + `Closing the last open tab (Browsing Context id ${contextId}), expect inconsistent behavior across platforms` + ); + } + + const browser = context.embedderElement; + const tabBrowser = TabManager.getTabBrowser(browser.ownerGlobal); + const tab = tabBrowser.getTabForBrowser(browser); + TabManager.removeTab(tab); + } + /** * An object that holds the WebDriver Bidi browsing context information. * From 30dc45a1a43c70a8d05eeb5241127c6ffa9d5c30 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Sun, 27 Mar 2022 08:58:11 +0000 Subject: [PATCH 3/5] Bug 1758502 - [wdspec] Add browsing context close command to browsing context module r=webdriver-reviewers,whimboo Depends on D141678 Differential Revision: https://phabricator.services.mozilla.com/D141679 --- .../webdriver/webdriver/bidi/modules/browsing_context.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/bidi/modules/browsing_context.py b/testing/web-platform/tests/tools/webdriver/webdriver/bidi/modules/browsing_context.py index 43146777d4be..1fb0e788b3fe 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/bidi/modules/browsing_context.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/bidi/modules/browsing_context.py @@ -4,6 +4,15 @@ from ._module import BidiModule, command class BrowsingContext(BidiModule): + @command + def close(self, context: Optional[str] = None) -> Mapping[str, Any]: + params: MutableMapping[str, Any] = {} + + if context is not None: + params["context"] = context + + return params + @command def get_tree(self, max_depth: Optional[int] = None, From cff6562b1f02d363a9d39068a1f3f80a71c1a221 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Sun, 27 Mar 2022 08:58:12 +0000 Subject: [PATCH 4/5] Bug 1758502 - [wdspec] Added web-platform tests for browsingContext.close command r=webdriver-reviewers,whimboo Depends on D141679 Differential Revision: https://phabricator.services.mozilla.com/D141680 --- .../bidi/browsing_context/close/close.py.ini | 3 ++ .../browsing_context/close/invalid.py.ini | 3 ++ .../bidi/browsing_context/close/__init__.py | 0 .../bidi/browsing_context/close/close.py | 21 +++++++++++++ .../bidi/browsing_context/close/invalid.py | 31 +++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/close.py.ini create mode 100644 testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/invalid.py.ini create mode 100644 testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/__init__.py create mode 100644 testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/close.py create mode 100644 testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/invalid.py diff --git a/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/close.py.ini b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/close.py.ini new file mode 100644 index 000000000000..751fd8c5464a --- /dev/null +++ b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/close.py.ini @@ -0,0 +1,3 @@ +[close.py] + disabled: + if release_or_beta: https://bugzilla.mozilla.org/show_bug.cgi?id=1712902 diff --git a/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/invalid.py.ini b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/invalid.py.ini new file mode 100644 index 000000000000..fabddce2b6c0 --- /dev/null +++ b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/close/invalid.py.ini @@ -0,0 +1,3 @@ +[invalid.py] + disabled: + if release_or_beta: https://bugzilla.mozilla.org/show_bug.cgi?id=1712902 diff --git a/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/__init__.py b/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/close.py b/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/close.py new file mode 100644 index 000000000000..5679557c8e7a --- /dev/null +++ b/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/close.py @@ -0,0 +1,21 @@ +import pytest + +pytestmark = pytest.mark.asyncio + + +@pytest.mark.parametrize("type_hint", ["window", "tab"]) +async def test_top_level_context(bidi_session, current_session, type_hint): + top_level_context_id = current_session.new_window(type_hint=type_hint) + + contexts = await bidi_session.browsing_context.get_tree() + assert len(contexts) == 2 + + await bidi_session.browsing_context.close(context=top_level_context_id) + + contexts = await bidi_session.browsing_context.get_tree() + assert len(contexts) == 1 + + assert contexts[0]["context"] != top_level_context_id + + # TODO: Add a test for closing the last tab once the behavior has been specified + # https://github.com/w3c/webdriver-bidi/issues/187 diff --git a/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/invalid.py b/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/invalid.py new file mode 100644 index 000000000000..35638756d2c7 --- /dev/null +++ b/testing/web-platform/tests/webdriver/tests/bidi/browsing_context/close/invalid.py @@ -0,0 +1,31 @@ +import pytest +import webdriver.bidi.error as error + +pytestmark = pytest.mark.asyncio + + +@pytest.mark.parametrize("value", [False, 42, {}, []]) +async def test_params_context_invalid_type(bidi_session, value): + with pytest.raises(error.InvalidArgumentException): + await bidi_session.browsing_context.close(context=value) + + +async def test_params_context_invalid_value(bidi_session): + with pytest.raises(error.NoSuchFrameException): + await bidi_session.browsing_context.close(context="foo") + + +async def test_child_context( + bidi_session, current_session, test_page_same_origin_frame +): + current_session.url = test_page_same_origin_frame + + all_contexts = await bidi_session.browsing_context.get_tree() + + assert len(all_contexts) == 1 + parent_info = all_contexts[0] + assert len(parent_info["children"]) == 1 + child_info = parent_info["children"][0] + + with pytest.raises(error.InvalidArgumentException): + await bidi_session.browsing_context.close(context=child_info["context"]) From b554ad29473bc67565b81a050151be69faf84084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 27 Mar 2022 17:03:40 +0200 Subject: [PATCH 5/5] Bug 1761663 - Fix --disable-dbus build. MANUAL PUSH: Trivial non-default build configuration fix. --- widget/gtk/GRefPtr.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/widget/gtk/GRefPtr.h b/widget/gtk/GRefPtr.h index aa48467feeeb..071eece56e1d 100644 --- a/widget/gtk/GRefPtr.h +++ b/widget/gtk/GRefPtr.h @@ -12,8 +12,10 @@ #include #include "mozilla/RefPtr.h" +#ifdef MOZ_ENABLE_DBUS // TODO: Remove this (we should use GDBus instead, which is not deprecated). -#include +# include +#endif namespace mozilla { @@ -38,7 +40,9 @@ GOBJECT_TRAITS(GAppInfo) GOBJECT_TRAITS(GdkDragContext) GOBJECT_TRAITS(GdkPixbuf) +#ifdef MOZ_ENABLE_DBUS GOBJECT_TRAITS(DBusGProxy) +#endif #undef GOBJECT_TRAITS @@ -62,6 +66,7 @@ struct RefPtrTraits { } }; +#ifdef MOZ_ENABLE_DBUS template <> struct RefPtrTraits { static void AddRef(DBusGConnection* aObject) { @@ -71,6 +76,7 @@ struct RefPtrTraits { dbus_g_connection_unref(aObject); } }; +#endif } // namespace mozilla