summaryrefslogtreecommitdiffstats
path: root/remote/cdp/test/browser/target
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /remote/cdp/test/browser/target
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'remote/cdp/test/browser/target')
-rw-r--r--remote/cdp/test/browser/target/browser.ini28
-rw-r--r--remote/cdp/test/browser/target/browser_activateTarget.js78
-rw-r--r--remote/cdp/test/browser/target/browser_attachToTarget.js54
-rw-r--r--remote/cdp/test/browser/target/browser_attachedToTarget.js50
-rw-r--r--remote/cdp/test/browser/target/browser_browserContext.js72
-rw-r--r--remote/cdp/test/browser/target/browser_closeTarget.js43
-rw-r--r--remote/cdp/test/browser/target/browser_createTarget.js103
-rw-r--r--remote/cdp/test/browser/target/browser_getTargets.js298
-rw-r--r--remote/cdp/test/browser/target/browser_sendMessageToTarget.js41
-rw-r--r--remote/cdp/test/browser/target/browser_setDiscoverTargets.js293
-rw-r--r--remote/cdp/test/browser/target/browser_targetCreated.js18
-rw-r--r--remote/cdp/test/browser/target/browser_targetDestroyed.js21
-rw-r--r--remote/cdp/test/browser/target/doc_test.html9
-rw-r--r--remote/cdp/test/browser/target/head.js9
14 files changed, 1117 insertions, 0 deletions
diff --git a/remote/cdp/test/browser/target/browser.ini b/remote/cdp/test/browser/target/browser.ini
new file mode 100644
index 0000000000..a708976baa
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser.ini
@@ -0,0 +1,28 @@
+[DEFAULT]
+tags = cdp
+subsuite = remote
+args =
+ --remote-debugging-port
+ --remote-allow-origins=null
+prefs = # Bug 1600054: Make CDP Fission compatible
+ fission.bfcacheInParent=false
+ fission.webContentIsolationStrategy=0
+support-files =
+ !/remote/cdp/test/browser/chrome-remote-interface.js
+ !/remote/cdp/test/browser/head.js
+ head.js
+ doc_test.html
+
+[browser_activateTarget.js]
+[browser_attachToTarget.js]
+[browser_attachedToTarget.js]
+https_first_disabled = true
+[browser_browserContext.js]
+[browser_closeTarget.js]
+[browser_createTarget.js]
+[browser_getTargets.js]
+https_first_disabled = true
+[browser_sendMessageToTarget.js]
+[browser_setDiscoverTargets.js]
+[browser_targetCreated.js]
+[browser_targetDestroyed.js]
diff --git a/remote/cdp/test/browser/target/browser_activateTarget.js b/remote/cdp/test/browser/target/browser_activateTarget.js
new file mode 100644
index 0000000000..fb1e0700f5
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_activateTarget.js
@@ -0,0 +1,78 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function raisesWithoutArguments({ client, tab }) {
+ const { Target } = client;
+ let errorThrown = false;
+ try {
+ await Target.activateTarget();
+ } catch (e) {
+ errorThrown = true;
+ }
+ ok(errorThrown, "activateTarget raised error without an argument");
+});
+
+add_task(async function raisesWithUnknownTargetId({ client, tab }) {
+ const { Target } = client;
+ let errorThrown = false;
+ try {
+ await Target.activateTarget({ targetId: "-1" });
+ } catch (e) {
+ errorThrown = true;
+ }
+ ok(errorThrown, "activateTarget raised error with unkown target id");
+});
+
+add_task(async function selectTabInOtherWindow({ client, tab }) {
+ const { Target, target } = client;
+
+ const currentTargetId = target.id;
+ const targets = await getDiscoveredTargets(Target);
+ const filtered_targets = targets.filter(target => {
+ return target.targetId == currentTargetId;
+ });
+ is(filtered_targets.length, 1, "The current target has been found");
+ const initialTarget = filtered_targets[0];
+
+ is(tab.ownerGlobal, getFocusedNavigator(), "Initial window is focused");
+
+ // open some more tabs in the initial window
+ await openTab(Target);
+ await openTab(Target);
+ const lastTabFirstWindow = await openTab(Target);
+ is(
+ gBrowser.selectedTab,
+ lastTabFirstWindow.newTab,
+ "Last openend tab in initial window is the selected tab"
+ );
+
+ const { newWindow } = await openWindow(Target);
+
+ const lastTabSecondWindow = await openTab(Target);
+ is(
+ gBrowser.selectedTab,
+ lastTabSecondWindow.newTab,
+ "Last openend tab in new window is the selected tab"
+ );
+
+ try {
+ is(newWindow, getFocusedNavigator(), "The new window is focused");
+ await Target.activateTarget({
+ targetId: initialTarget.targetId,
+ });
+ is(
+ tab.ownerGlobal,
+ getFocusedNavigator(),
+ "Initial window is focused again"
+ );
+ is(gBrowser.selectedTab, tab, "Selected tab is the initial tab again");
+ } finally {
+ await BrowserTestUtils.closeWindow(newWindow);
+ }
+});
+
+function getFocusedNavigator() {
+ return Services.wm.getMostRecentWindow("navigator:browser");
+}
diff --git a/remote/cdp/test/browser/target/browser_attachToTarget.js b/remote/cdp/test/browser/target/browser_attachToTarget.js
new file mode 100644
index 0000000000..1ad34f3305
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_attachToTarget.js
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function raisesWithoutArguments({ client, tab }) {
+ const { Target } = client;
+ let errorThrown = false;
+ try {
+ await Target.attachToTarget();
+ } catch (e) {
+ errorThrown = true;
+ }
+ ok(errorThrown, "attachToTarget raised error without an argument");
+});
+
+add_task(async function raisesWithUnknownTargetId({ client, tab }) {
+ const { Target } = client;
+ let errorThrown = false;
+ try {
+ await Target.attachToTarget({ targetId: "-1" });
+ } catch (e) {
+ errorThrown = true;
+ }
+ ok(errorThrown, "attachToTarget raised error with unkown target id");
+});
+
+add_task(
+ async function attachPageTarget({ client }) {
+ const { Target } = client;
+ const { targetInfo } = await openTab(Target);
+
+ ok(!targetInfo.attached, "New target is not attached");
+
+ info("Attach new target");
+ const { sessionId } = await Target.attachToTarget({
+ targetId: targetInfo.targetId,
+ });
+
+ is(
+ typeof sessionId,
+ "string",
+ "attachToTarget returns the session id as string"
+ );
+
+ const { targetInfos } = await Target.getTargets();
+ const listedTarget = targetInfos.find(
+ info => info.targetId === targetInfo.targetId
+ );
+
+ ok(listedTarget.attached, "New target is attached");
+ },
+ { createTab: false }
+);
diff --git a/remote/cdp/test/browser/target/browser_attachedToTarget.js b/remote/cdp/test/browser/target/browser_attachedToTarget.js
new file mode 100644
index 0000000000..4f25868f2a
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_attachedToTarget.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PAGE_TEST =
+ "https://example.com/browser/remote/cdp/test/browser/target/doc_test.html";
+
+add_task(
+ async function attachedPageTarget({ client }) {
+ const { Target } = client;
+ const { targetInfo } = await openTab(Target);
+
+ ok(
+ !targetInfo.attached,
+ "Got expected target attached status before attaching"
+ );
+
+ await loadURL(PAGE_TEST);
+
+ info("Attach new page target");
+ const attachedToTarget = Target.attachedToTarget();
+ const { sessionId } = await Target.attachToTarget({
+ targetId: targetInfo.targetId,
+ });
+ const {
+ targetInfo: eventTargetInfo,
+ sessionId: eventSessionId,
+ waitingForDebugger: eventWaitingForDebugger,
+ } = await attachedToTarget;
+
+ is(eventTargetInfo.targetId, targetInfo.targetId, "Got expected target id");
+ is(eventTargetInfo.type, "page", "Got expected target type");
+ is(eventTargetInfo.title, "Test Page", "Got expected target title");
+ is(eventTargetInfo.url, PAGE_TEST, "Got expected target URL");
+ ok(eventTargetInfo.attached, "Got expected target attached status");
+
+ is(
+ eventSessionId,
+ sessionId,
+ "attachedToTarget and attachToTarget refer to the same session id"
+ );
+ is(
+ typeof eventWaitingForDebugger,
+ "boolean",
+ "Got expected type for waitingForDebugger"
+ );
+ },
+ { createTab: false }
+);
diff --git a/remote/cdp/test/browser/target/browser_browserContext.js b/remote/cdp/test/browser/target/browser_browserContext.js
new file mode 100644
index 0000000000..98c2ccee2e
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_browserContext.js
@@ -0,0 +1,72 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function ({ CDP }) {
+ // Connect to the server
+ const { webSocketDebuggerUrl } = await CDP.Version();
+ const client = await CDP({ target: webSocketDebuggerUrl });
+ info("CDP client has been instantiated");
+
+ const { Target } = client;
+ await getDiscoveredTargets(Target);
+
+ // Test if Target.getBrowserContexts is empty before creatinga ny
+ const { browserContextIds: browserContextIdsBefore } =
+ await Target.getBrowserContexts();
+
+ is(
+ browserContextIdsBefore.length,
+ 0,
+ "No browser context is open by default"
+ );
+
+ const { browserContextId } = await Target.createBrowserContext();
+
+ // Test if Target.getBrowserContexts includes the context we just created
+ const { browserContextIds } = await Target.getBrowserContexts();
+
+ is(browserContextIds.length, 1, "Got expected length of browser contexts");
+ is(
+ browserContextIds[0],
+ browserContextId,
+ "Got expected browser context id from getBrowserContexts"
+ );
+
+ const targetCreated = Target.targetCreated();
+ const { targetId } = await Target.createTarget({
+ url: "about:blank",
+ browserContextId,
+ });
+ ok(!!targetId, "Target.createTarget returns a non-empty target id");
+
+ const { targetInfo } = await targetCreated;
+ is(
+ targetId,
+ targetInfo.targetId,
+ "targetCreated refers to the same target id"
+ );
+ is(
+ browserContextId,
+ targetInfo.browserContextId,
+ "targetCreated refers to the same browser context"
+ );
+ is(targetInfo.type, "page", "The target is a page");
+
+ // Releasing the browser context is going to remove the tab opened when calling createTarget
+ await Target.disposeBrowserContext({ browserContextId });
+
+ // Test if Target.getBrowserContexts now is empty
+ const { browserContextIds: browserContextIdsAfter } =
+ await Target.getBrowserContexts();
+
+ is(
+ browserContextIdsAfter.length,
+ 0,
+ "After closing all browser contexts none is available anymore"
+ );
+
+ await client.close();
+ info("The client is closed");
+});
diff --git a/remote/cdp/test/browser/target/browser_closeTarget.js b/remote/cdp/test/browser/target/browser_closeTarget.js
new file mode 100644
index 0000000000..22d58f02e6
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_closeTarget.js
@@ -0,0 +1,43 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function raisesWithoutArguments({ client, tab }) {
+ const { Target } = client;
+ let exceptionThrown = false;
+ try {
+ await Target.closeTarget();
+ } catch (e) {
+ exceptionThrown = true;
+ }
+ ok(exceptionThrown, "closeTarget raised error without an argument");
+});
+
+add_task(async function raisesWithUnknownTargetId({ client, tab }) {
+ const { Target } = client;
+ let exceptionThrown = false;
+ try {
+ await Target.closeTarget({ targetId: "-1" });
+ } catch (e) {
+ exceptionThrown = true;
+ }
+ ok(exceptionThrown, "closeTarget raised error with unkown target id");
+});
+
+add_task(async function triggersTargetDestroyed({ client, tab }) {
+ const { Target } = client;
+ const { targetInfo, newTab } = await openTab(Target);
+
+ const tabClosed = BrowserTestUtils.waitForEvent(newTab, "TabClose");
+ const targetDestroyed = Target.targetDestroyed();
+
+ info("Closing the target");
+ await Target.closeTarget({ targetId: targetInfo.targetId });
+
+ await tabClosed;
+ info("Tab was closed");
+
+ await targetDestroyed;
+ info("Received the Target.targetDestroyed event");
+});
diff --git a/remote/cdp/test/browser/target/browser_createTarget.js b/remote/cdp/test/browser/target/browser_createTarget.js
new file mode 100644
index 0000000000..80e45f1c7a
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_createTarget.js
@@ -0,0 +1,103 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PAGE_TEST =
+ "https://example.com/browser/remote/cdp/test/browser/target/doc_test.html";
+
+add_task(
+ async function raisesWithoutArguments({ client }) {
+ const { Target } = client;
+
+ let exceptionThrown = false;
+ try {
+ await Target.createTarget();
+ } catch (e) {
+ exceptionThrown = true;
+ }
+ ok(exceptionThrown, "createTarget raised error without a URL");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function raisesWithInvalidUrlType({ client }) {
+ const { Target } = client;
+
+ for (const url of [null, true, 1, [], {}]) {
+ info(`Checking url with invalid value: ${url}`);
+
+ let errorThrown = "";
+ try {
+ await Target.createTarget({
+ url,
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/url: string value expected/),
+ `URL fails for invalid type: ${url}`
+ );
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function invalidUrlDefaults({ client }) {
+ const { Target } = client;
+ const expectedUrl = "about:blank";
+
+ for (const url of ["", "example.com", "https://example[.com", "https:"]) {
+ // Here we cannot wait for browserLoaded, because the tab might already
+ // be on about:blank when `createTarget` resolves.
+ const onNewTabLoaded = BrowserTestUtils.waitForNewTab(
+ gBrowser,
+ "about:blank",
+ true
+ );
+ const { targetId } = await Target.createTarget({ url });
+ is(typeof targetId, "string", "Got expected type for target id");
+
+ // Wait for the load to be done before checking the URL.
+ const tab = await onNewTabLoaded;
+ const browser = tab.linkedBrowser;
+ is(browser.currentURI.spec, expectedUrl, "Expected URL loaded");
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function opensTabWithCorrectInfo({ client }) {
+ const { Target } = client;
+
+ const url = PAGE_TEST;
+ const onNewTabLoaded = BrowserTestUtils.waitForNewTab(gBrowser, url, true);
+ const { targetId } = await Target.createTarget({ url });
+
+ is(typeof targetId, "string", "Got expected type for target id");
+
+ const tab = await onNewTabLoaded;
+ const browser = tab.linkedBrowser;
+ is(browser.currentURI.spec, url, "Expected URL loaded");
+
+ const { targetInfos } = await Target.getTargets();
+ const targetInfo = targetInfos.find(info => info.targetId === targetId);
+ ok(!!targetInfo, "Found target info with the same target id");
+ is(targetInfo.url, url, "Target info refers to the same target URL");
+ is(
+ targetInfo.type,
+ "page",
+ "Target info refers to the same target as page type"
+ );
+ ok(
+ !targetInfo.attached,
+ "Target info refers to the same target as not attached"
+ );
+ },
+ { createTab: false }
+);
diff --git a/remote/cdp/test/browser/target/browser_getTargets.js b/remote/cdp/test/browser/target/browser_getTargets.js
new file mode 100644
index 0000000000..b0eb0378ce
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_getTargets.js
@@ -0,0 +1,298 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PAGE_TEST =
+ "https://example.com/browser/remote/cdp/test/browser/target/doc_test.html";
+
+add_task(
+ async function getTargetsDetails({ client }) {
+ const { Target, target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ const { targetInfos } = await Target.getTargets();
+
+ Assert.equal(targetInfos.length, 1, "Got expected amount of targets");
+
+ const targetInfo = targetInfos[0];
+ is(targetInfo.id, target.id, "Got expected target id");
+ is(targetInfo.type, "page", "Got expected target type");
+ is(targetInfo.title, "Test Page", "Got expected target title");
+ is(targetInfo.url, PAGE_TEST, "Got expected target URL");
+ ok(targetInfo.attached, "Got expected target attached status");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargetsCount({ client }) {
+ const { Target, target } = client;
+ const { targetInfo: newTabTargetInfo } = await openTab(Target);
+
+ await loadURL(PAGE_TEST);
+
+ const { targetInfos } = await Target.getTargets();
+
+ Assert.equal(targetInfos.length, 2, "Got expected amount of targets");
+ const targetIds = targetInfos.map(info => info.id);
+ ok(targetIds.includes(target.id), "Got expected original target id");
+ ok(targetIds.includes(newTabTargetInfo.id), "Got expected new target id");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargetsAttached({ client }) {
+ const { Target } = client;
+ await openTab(Target);
+
+ await loadURL(PAGE_TEST);
+
+ const { targetInfos } = await Target.getTargets();
+
+ ok(targetInfos[0].attached, "Current target is attached");
+ ok(!targetInfos[1].attached, "New tab target is detached");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterAllBlank({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Blank/all filter so all targets are returned, including main process
+ const { targetInfos } = await Target.getTargets({
+ filter: [{}],
+ });
+
+ is(
+ targetInfos.length,
+ 2,
+ "Got expected amount of targets with all (blank) filter"
+ );
+
+ const pageTarget = targetInfos.find(info => info.type === "page");
+ ok(!!pageTarget, "Found page target in targets with all (blank) filter");
+
+ const mainProcessTarget = targetInfos.find(info => info.type === "browser");
+ ok(
+ !!mainProcessTarget,
+ "Found main process target in targets with all (blank) filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterAllExplicit({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Blank/all filter so all targets are returned, including main process
+ const { targetInfos } = await Target.getTargets({
+ filter: [{ type: "browser" }, { type: "page" }],
+ });
+
+ is(
+ targetInfos.length,
+ 2,
+ "Got expected amount of targets with all (explicit) filter"
+ );
+
+ const pageTarget = targetInfos.find(info => info.type === "page");
+ ok(!!pageTarget, "Found page target in targets with all (explicit) filter");
+
+ const mainProcessTarget = targetInfos.find(info => info.type === "browser");
+ ok(
+ !!mainProcessTarget,
+ "Found main process target in targets with all (explicit) filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterPage({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Filter so only page targets are returned
+ // This returns same as default but pass our own custom filter to ensure
+ const { targetInfos } = await Target.getTargets({
+ filter: [{ type: "page" }],
+ });
+
+ is(
+ targetInfos.length,
+ 1,
+ "Got expected amount of targets with page filter"
+ );
+ is(
+ targetInfos[0].type,
+ "page",
+ "Got expected type 'page' of target from page filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterBrowser({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Filter so only main process target is returned
+ const { targetInfos } = await Target.getTargets({
+ filter: [{ type: "browser" }],
+ });
+
+ is(
+ targetInfos.length,
+ 1,
+ "Got expected amount of targets with browser filter"
+ );
+ is(
+ targetInfos[0].type,
+ "browser",
+ "Got expected type 'browser' of target from browser filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterExcludePage({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Filter so page targets are excluded (so only main process target is returned)
+ // A blank object ({}) means include everything else
+ const { targetInfos } = await Target.getTargets({
+ filter: [{ type: "page", exclude: true }, {}],
+ });
+
+ is(
+ targetInfos.length,
+ 1,
+ "Got expected amount of targets with exclude page filter"
+ );
+ is(
+ targetInfos[0].type,
+ "browser",
+ "Got expected type 'browser' of target from exclude page filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterExcludeBrowserIncludePage({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ // Filter so main process is excluded and only page types are returned explicitly
+ const { targetInfos } = await Target.getTargets({
+ filter: [{ type: "browser", exclude: true }, { type: "page" }],
+ });
+
+ is(
+ targetInfos.length,
+ 1,
+ "Got expected amount of targets with exclude browser include page filter"
+ );
+ is(
+ targetInfos[0].type,
+ "page",
+ "Got expected type 'page' of target from exclude browser include page filter"
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function getTargets_filterInvalid({ client }) {
+ const { Target } = client;
+
+ for (const filter of [null, true, 1, "foo", {}]) {
+ info(`Checking filter with invalid value: ${filter}`);
+
+ let errorThrown = "";
+ try {
+ await Target.getTargets({
+ filter,
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: array value expected/),
+ `Filter fails for invalid type: ${filter}`
+ );
+ }
+
+ for (const filterEntry of [null, true, 1, "foo", []]) {
+ info(`Checking filter entry with invalid value: ${filterEntry}`);
+
+ let errorThrown = "";
+ try {
+ await Target.getTargets({
+ filter: [filterEntry],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: object values expected in array/),
+ `Filter entry fails for invalid type: ${filterEntry}`
+ );
+ }
+
+ for (const type of [null, true, 1, [], {}]) {
+ info(`Checking filter entry with type as invalid value: ${type}`);
+
+ let errorThrown = "";
+ try {
+ await Target.getTargets({
+ filter: [{ type }],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: type: string value expected/),
+ `Filter entry type fails for invalid type: ${type}`
+ );
+ }
+
+ for (const exclude of [null, 1, "foo", [], {}]) {
+ info(`Checking filter entry with exclude as invalid value: ${exclude}`);
+
+ let errorThrown = "";
+ try {
+ await Target.getTargets({
+ filter: [{ exclude }],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: exclude: boolean value expected/),
+ `Filter entry exclude for invalid type: ${exclude}`
+ );
+ }
+ },
+ { createTab: false }
+);
diff --git a/remote/cdp/test/browser/target/browser_sendMessageToTarget.js b/remote/cdp/test/browser/target/browser_sendMessageToTarget.js
new file mode 100644
index 0000000000..b440066178
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_sendMessageToTarget.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function sendToAttachedTarget({ client }) {
+ const { Target } = client;
+ const { targetInfo } = await openTab(Target);
+
+ const attachedToTarget = Target.attachedToTarget();
+ const { sessionId } = await Target.attachToTarget({
+ targetId: targetInfo.targetId,
+ });
+ await attachedToTarget;
+ info("Target attached");
+
+ const id = 1;
+ const message = JSON.stringify({
+ id,
+ method: "Page.navigate",
+ params: {
+ url: toDataURL("new-page"),
+ },
+ });
+
+ info("Calling Target.sendMessageToTarget");
+ const onResponse = Target.receivedMessageFromTarget();
+ await Target.sendMessageToTarget({ sessionId, message });
+ const response = await onResponse;
+ info("Message from target received");
+
+ ok(!!response, "The response is not empty");
+ is(response.sessionId, sessionId, "The response is from the same session");
+
+ const responseMessage = JSON.parse(response.message);
+ is(responseMessage.id, id, "The response is from the same session");
+ ok(
+ !!responseMessage.result.frameId,
+ "received the `frameId` out of `Page.navigate` request"
+ );
+});
diff --git a/remote/cdp/test/browser/target/browser_setDiscoverTargets.js b/remote/cdp/test/browser/target/browser_setDiscoverTargets.js
new file mode 100644
index 0000000000..1d0c59dbd2
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_setDiscoverTargets.js
@@ -0,0 +1,293 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// These tests are a near copy of the tests for Target.getTargets, but using
+// the `setDiscoverTargets` method and `targetCreated` events instead.
+// Calling `setDiscoverTargets` with `discover: true` will dispatch a
+// `targetCreated` event for all already opened tabs and NOT the browser target
+// with the default filter.
+
+const PAGE_TEST =
+ "https://example.com/browser/remote/cdp/test/browser/target/doc_test.html";
+
+add_task(
+ async function discoverInvalidTypes({ client }) {
+ const { Target } = client;
+
+ for (const discover of [null, undefined, 1, "foo", [], {}]) {
+ info(`Checking discover with invalid value: ${discover}`);
+
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({ discover });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/discover: boolean value expected/),
+ `Discover fails for invalid type: ${discover}`
+ );
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function filterInvalid({ client }) {
+ const { Target } = client;
+
+ for (const filter of [null, true, 1, "foo", {}]) {
+ info(`Checking filter with invalid value: ${filter}`);
+
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({ discover: true, filter });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: array value expected/),
+ `Filter fails for invalid type: ${filter}`
+ );
+ }
+
+ for (const filterEntry of [null, undefined, true, 1, "foo", []]) {
+ info(`Checking filter entry with invalid value: ${filterEntry}`);
+
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({
+ discover: true,
+ filter: [filterEntry],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: object values expected in array/),
+ `Filter entry fails for invalid type: ${filterEntry}`
+ );
+ }
+
+ for (const type of [null, true, 1, [], {}]) {
+ info(`Checking filter entry with type as invalid value: ${type}`);
+
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({
+ discover: true,
+ filter: [{ type }],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: type: string value expected/),
+ `Filter entry type fails for invalid type: ${type}`
+ );
+ }
+
+ for (const exclude of [null, 1, "foo", [], {}]) {
+ info(`Checking filter entry with exclude as invalid value: ${exclude}`);
+
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({
+ discover: true,
+ filter: [{ exclude }],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: exclude: boolean value expected/),
+ `Filter entry exclude for invalid type: ${exclude}`
+ );
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function noFilterWithDiscoverFalse({ client }) {
+ const { Target } = client;
+
+ // Check filter cannot be given with discover: false
+ let errorThrown = "";
+ try {
+ await Target.setDiscoverTargets({
+ discover: false,
+ filter: [{}],
+ });
+ } catch (e) {
+ errorThrown = e.message;
+ }
+
+ ok(
+ errorThrown.match(/filter: should not be present when discover is false/),
+ `Error throw when given filter with discover false`
+ );
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function noTargetsWithDiscoverFalse({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ const targets = await getDiscoveredTargets(Target, { discover: false });
+ is(targets.length, 0, "Got 0 targets with discover false");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function noEventsWithDiscoverFalse({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ const targets = [];
+ const unsubscribe = Target.targetCreated(target => {
+ targets.push(target.targetInfo);
+ });
+
+ await Target.setDiscoverTargets({
+ discover: false,
+ });
+
+ // Cannot use openTab() helper as it relies on the event
+ await BrowserTestUtils.openNewForegroundTab(gBrowser);
+
+ // Wait 1s for the event to possibly dispatch
+ await timeoutPromise(1000);
+
+ unsubscribe();
+ is(targets.length, 0, "Got 0 target created events with discover false");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function targetInfoValues({ client }) {
+ const { Target, target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ const targets = await getDiscoveredTargets(Target);
+
+ Assert.equal(targets.length, 1, "Got expected amount of targets");
+
+ const targetInfo = targets[0];
+ is(targetInfo.id, target.id, "Got expected target id");
+ is(targetInfo.type, "page", "Got expected target type");
+ is(targetInfo.title, "Test Page", "Got expected target title");
+ is(targetInfo.url, PAGE_TEST, "Got expected target URL");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function discoverEnabledAndMultipleTabs({ client }) {
+ const { Target, target } = client;
+ const { targetInfo: newTabTargetInfo } = await openTab(Target);
+
+ await loadURL(PAGE_TEST);
+
+ const targets = await getDiscoveredTargets(Target);
+
+ Assert.equal(targets.length, 2, "Got expected amount of targets");
+ const targetIds = targets.map(info => info.id);
+ ok(targetIds.includes(target.id), "Got expected original target id");
+ ok(targetIds.includes(newTabTargetInfo.id), "Got expected new target id");
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function allFilters({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ for (const filter of [[{}], [{ type: "browser" }, { type: "page" }]]) {
+ // Blank/all filter so all targets are returned, including main process
+ const targets = await getDiscoveredTargets(Target, { filter });
+
+ is(targets.length, 2, "Got expected amount of targets with all filter");
+
+ const pageTarget = targets.find(info => info.type === "page");
+ ok(!!pageTarget, "Found page target in targets with all filter");
+
+ const mainProcessTarget = targets.find(info => info.type === "browser");
+ ok(
+ !!mainProcessTarget,
+ "Found main process target in targets with all filter"
+ );
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function pageOnlyFilters({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ for (const filter of [
+ [{ type: "page" }],
+ [{ type: "browser", exclude: true }, { type: "page" }],
+ ]) {
+ // Filter so only page targets are returned
+ // This returns same as default but pass our own custom filter to ensure
+ // these filters still return what they should
+ const targets = await getDiscoveredTargets(Target, { filter });
+
+ is(targets.length, 1, "Got expected amount of targets with page filter");
+ is(
+ targets[0].type,
+ "page",
+ "Got expected type 'page' of target from page filter"
+ );
+ }
+ },
+ { createTab: false }
+);
+
+add_task(
+ async function browserOnlyFilters({ client }) {
+ const { Target } = client;
+
+ await loadURL(PAGE_TEST);
+
+ for (const filter of [
+ [{ type: "browser" }],
+ [{ type: "page", exclude: true }, {}],
+ ]) {
+ // Filter so only main process target is returned
+ const targets = await getDiscoveredTargets(Target, { filter });
+
+ is(
+ targets.length,
+ 1,
+ "Got expected amount of targets with browser only filter"
+ );
+ is(
+ targets[0].type,
+ "browser",
+ "Got expected type 'browser' of target from browser only filter"
+ );
+ }
+ },
+ { createTab: false }
+);
diff --git a/remote/cdp/test/browser/target/browser_targetCreated.js b/remote/cdp/test/browser/target/browser_targetCreated.js
new file mode 100644
index 0000000000..bfb7287f87
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_targetCreated.js
@@ -0,0 +1,18 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function eventFiredWhenTabIsCreated({ client }) {
+ const { Target } = client;
+
+ const targetCreated = Target.targetCreated();
+ await BrowserTestUtils.openNewForegroundTab(gBrowser);
+ const { targetInfo } = await targetCreated;
+
+ is(typeof targetInfo.targetId, "string", "Got expected type for target id");
+ is(targetInfo.type, "page", "Got expected target type");
+ is(targetInfo.title, "", "Got expected target title");
+ is(targetInfo.url, "about:blank", "Got expected target URL");
+ is(targetInfo.attached, false, "Got expected attached status");
+});
diff --git a/remote/cdp/test/browser/target/browser_targetDestroyed.js b/remote/cdp/test/browser/target/browser_targetDestroyed.js
new file mode 100644
index 0000000000..2ad657b135
--- /dev/null
+++ b/remote/cdp/test/browser/target/browser_targetDestroyed.js
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function eventFiredWhenTabIsClosed({ client, tab }) {
+ const { Target } = client;
+ const { newTab } = await openTab(Target);
+
+ const tabClosed = BrowserTestUtils.waitForEvent(newTab, "TabClose");
+ const targetDestroyed = Target.targetDestroyed();
+
+ info("Closing the tab");
+ BrowserTestUtils.removeTab(newTab);
+
+ await tabClosed;
+ info("Tab was closed");
+
+ await targetDestroyed;
+ info("Received the Target.targetDestroyed event");
+});
diff --git a/remote/cdp/test/browser/target/doc_test.html b/remote/cdp/test/browser/target/doc_test.html
new file mode 100644
index 0000000000..14d377f07a
--- /dev/null
+++ b/remote/cdp/test/browser/target/doc_test.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test Page</title>
+</head>
+<body>
+</body>
+</html>
diff --git a/remote/cdp/test/browser/target/head.js b/remote/cdp/test/browser/target/head.js
new file mode 100644
index 0000000000..1a1c90fbf6
--- /dev/null
+++ b/remote/cdp/test/browser/target/head.js
@@ -0,0 +1,9 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/remote/cdp/test/browser/head.js",
+ this
+);