diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /remote/cdp/test/browser/target | |
parent | Initial commit. (diff) | |
download | thunderbird-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')
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 +); |