From 1c127b7bc61e5219ca369897e617c7bb99686946 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 21 Mar 2024 13:06:47 +0400 Subject: [PATCH] add method which return current cdp --- src/api/test-controller/index.js | 8 ++++++++ src/browser/connection/index.ts | 5 +++++ .../built-in/dedicated/chrome/index.js | 8 ++++---- src/browser/provider/index.ts | 5 +++++ src/browser/provider/plugin-host.js | 4 ++++ src/test-run/commands/actions.d.ts | 4 ++++ src/test-run/commands/actions.js | 8 ++++++++ src/test-run/commands/type.js | 1 + src/test-run/index.ts | 8 ++++++++ .../get-current-cdp-client/pages/child.html | 10 ++++++++++ .../get-current-cdp-client/pages/index.html | 10 ++++++++++ .../es-next/get-current-cdp-client/test.js | 7 +++++++ .../testcafe-fixtures/index.js | 19 +++++++++++++++++++ .../index.js | 18 ++++++++++++++++++ test/server/test-controller-events-test.js | 1 + ts-defs-src/test-api/test-controller.d.ts | 5 +++++ 16 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-client/pages/child.html create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-client/pages/index.html create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-client/test.js create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-client/testcafe-fixtures/index.js diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index 0f5c4d3395f..61c0f02e7b2 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -35,6 +35,7 @@ import { OpenWindowCommand, CloseWindowCommand, GetCurrentWindowCommand, + GetCurrentCDPClientCommand, SwitchToWindowCommand, SwitchToWindowByPredicateCommand, SwitchToParentWindowCommand, @@ -518,6 +519,13 @@ export default class TestController { return this.enqueueCommand(GetCurrentWindowCommand); } + [delegatedAPI(GetCurrentCDPClientCommand.methodName)] () { + const callsite = getCallsiteForMethod(GetCurrentCDPClientCommand.methodName); + const command = this._createCommand(GetCurrentCDPClientCommand, {}, callsite); + + return this.testRun.executeCommand(command, callsite); + } + [delegatedAPI(SwitchToWindowCommand.methodName)] (windowSelector) { this._validateMultipleWindowCommand(SwitchToWindowCommand.methodName); diff --git a/src/browser/connection/index.ts b/src/browser/connection/index.ts index 4047abf289e..cfd0c586d2b 100644 --- a/src/browser/connection/index.ts +++ b/src/browser/connection/index.ts @@ -36,6 +36,7 @@ import { Proxy } from 'testcafe-hammerhead'; import { NextTestRunInfo, OpenBrowserAdditionalOptions } from '../../shared/types'; import { EventType } from '../../native-automation/types'; import { NativeAutomationBase } from '../../native-automation'; +import remoteChrome from 'chrome-remote-interface'; const getBrowserConnectionDebugScope = (id: string): string => `testcafe:browser:connection:${id}`; @@ -660,6 +661,10 @@ export default class BrowserConnection extends EventEmitter { return this.provider.getNewWindowIdInNativeAutomation(this.id, windowId); } + public async getCurrentCDPClient (): Promise { + return this.provider.getCurrentCDPClient(this.id); + } + public resetActiveWindowId (): void { this.provider.resetActiveWindowId(this.id); } diff --git a/src/browser/provider/built-in/dedicated/chrome/index.js b/src/browser/provider/built-in/dedicated/chrome/index.js index 57920cdf045..60e22f41c6b 100644 --- a/src/browser/provider/built-in/dedicated/chrome/index.js +++ b/src/browser/provider/built-in/dedicated/chrome/index.js @@ -25,7 +25,7 @@ export default { return getConfig(name); }, - async _getActiveCDPClient (browserId) { + async getCurrentCDPClient (browserId) { const { browserClient } = this.openedBrowsers[browserId]; const cdpClient = await browserClient.getActiveClient(); @@ -187,19 +187,19 @@ export default { }, async openFileProtocol (browserId, url) { - const cdpClient = await this._getActiveCDPClient(browserId); + const cdpClient = await this.getCurrentCDPClient(browserId); await navigateTo(cdpClient, url); }, async dispatchNativeAutomationEvent (browserId, type, options) { - const cdpClient = await this._getActiveCDPClient(browserId); + const cdpClient = await this.getCurrentCDPClient(browserId); await dispatchNativeAutomationEvent(cdpClient, type, options); }, async dispatchNativeAutomationEventSequence (browserId, eventSequence) { - const cdpClient = await this._getActiveCDPClient(browserId); + const cdpClient = await this.getCurrentCDPClient(browserId); for (const event of eventSequence) { if (event.type === EventType.Delay) diff --git a/src/browser/provider/index.ts b/src/browser/provider/index.ts index 0b71bd38509..ada8b4a8099 100644 --- a/src/browser/provider/index.ts +++ b/src/browser/provider/index.ts @@ -17,6 +17,7 @@ import getLocalOSInfo, { OSInfo } from 'get-os-info'; import { OpenBrowserAdditionalOptions } from '../../shared/types'; import { EventType } from '../../native-automation/types'; import { NativeAutomationBase } from '../../native-automation'; +import remoteChrome from 'chrome-remote-interface'; const DEBUG_LOGGER = debug('testcafe:browser:provider'); @@ -479,6 +480,10 @@ export default class BrowserProvider { return this.plugin.getNativeAutomation(browserId); } + public async getCurrentCDPClient (browserId: string): Promise { + return this.plugin.getCurrentCDPClient(browserId); + } + public getNewWindowIdInNativeAutomation (browserId: string, windowId: string): Promise { return this.plugin.getNewWindowIdInNativeAutomation(browserId, windowId); } diff --git a/src/browser/provider/plugin-host.js b/src/browser/provider/plugin-host.js index 18c5635073e..6923ed58ac1 100644 --- a/src/browser/provider/plugin-host.js +++ b/src/browser/provider/plugin-host.js @@ -178,4 +178,8 @@ export default class BrowserProviderPluginHost { getNewWindowIdInNativeAutomation (/*browserId, windowId*/) { return Promise.resolve(); } + + async getCurrentCDPClient (/*browserId*/) { + return Promise.resolve(); + } } diff --git a/src/test-run/commands/actions.d.ts b/src/test-run/commands/actions.d.ts index 07b07fe8d94..78595f1392f 100644 --- a/src/test-run/commands/actions.d.ts +++ b/src/test-run/commands/actions.d.ts @@ -67,6 +67,10 @@ export class GetCurrentWindowsCommand extends ActionCommandBase { public constructor(obj: object, testRun: TestRun, validateProperties?: boolean); } +export class GetCurrentCDPClientCommand extends ActionCommandBase { + public constructor(obj: object, testRun: TestRun, validateProperties?: boolean); +} + export class SwitchToWindowCommand extends ActionCommandBase { public constructor(obj: object, testRun: TestRun, validateProperties?: boolean); public windowId: string; diff --git a/src/test-run/commands/actions.js b/src/test-run/commands/actions.js index df4a55df651..dc18df321b3 100644 --- a/src/test-run/commands/actions.js +++ b/src/test-run/commands/actions.js @@ -524,6 +524,14 @@ export class GetCurrentWindowsCommand extends ActionCommandBase { } } +export class GetCurrentCDPClientCommand extends ActionCommandBase { + static methodName = camelCase(TYPE.getCurrentCDPClient); + + constructor (obj, testRun, validateProperties) { + super(obj, testRun, TYPE.getCurrentCDPClient, validateProperties); + } +} + export class SwitchToWindowCommand extends ActionCommandBase { static methodName = camelCase(TYPE.switchToWindow); diff --git a/src/test-run/commands/type.js b/src/test-run/commands/type.js index 7979fa877ba..62ea5cfe831 100644 --- a/src/test-run/commands/type.js +++ b/src/test-run/commands/type.js @@ -41,6 +41,7 @@ export default { closeWindow: 'close-window', getCurrentWindow: 'get-current-window', getCurrentWindows: 'get-current-windows', + getCurrentCDPClient: 'get-current-c-d-p-client', switchToWindow: 'switch-to-window', switchToWindowByPredicate: 'switch-to-window-by-predicate', switchToParentWindow: 'switch-to-parent-window', diff --git a/src/test-run/index.ts b/src/test-run/index.ts index 872ea90304f..b81a8f11d75 100644 --- a/src/test-run/index.ts +++ b/src/test-run/index.ts @@ -136,6 +136,7 @@ import { import NativeAutomationRequestPipeline from '../native-automation/request-pipeline'; import { NativeAutomationBase } from '../native-automation'; import ReportDataLog from '../reporter/report-data-log'; +import remoteChrome from 'chrome-remote-interface'; const lazyRequire = require('import-lazy')(require); const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder'); @@ -445,6 +446,10 @@ export default class TestRun extends AsyncEventEmitter { : this.testExecutionTimeout || null; } + public async getCurrentCDPClient (): Promise { + return this.browserConnection.getCurrentCDPClient(); + } + private _addClientScriptContentWarningsIfNecessary (): void { const { empty, duplicatedContent } = findProblematicScripts(this.test.clientScripts as ClientScript[]); @@ -1227,6 +1232,9 @@ export default class TestRun extends AsyncEventEmitter { if (command.type === COMMAND_TYPE.removeRequestHooks) return Promise.all((command as RemoveRequestHooksCommand).hooks.map(hook => this._removeRequestHook(hook))); + if (command.type === COMMAND_TYPE.getCurrentCDPClient) + return this.getCurrentCDPClient(); + return this._enqueueCommand(command, callsite as CallsiteRecord); } diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/child.html b/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/child.html new file mode 100644 index 00000000000..58376b2bbbc --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/child.html @@ -0,0 +1,10 @@ + + + + + Title + + +

new window

+ + diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/index.html b/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/index.html new file mode 100644 index 00000000000..1e82d200cd6 --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-client/pages/index.html @@ -0,0 +1,10 @@ + + + + + Title + + +

Open new window

+ + diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-client/test.js b/test/functional/fixtures/api/es-next/get-current-cdp-client/test.js new file mode 100644 index 00000000000..93869717384 --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-client/test.js @@ -0,0 +1,7 @@ +const { onlyInNativeAutomation } = require('../../../../utils/skip-in'); + +describe('[API] Get current CDP client', function () { + onlyInNativeAutomation('Should return current CPD', function () { + return runTests('./testcafe-fixtures/index.js', 'Get current CDP client', { experimentalMultipleWindows: true }); + }); +}); diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-client/testcafe-fixtures/index.js b/test/functional/fixtures/api/es-next/get-current-cdp-client/testcafe-fixtures/index.js new file mode 100644 index 00000000000..847921300ba --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-client/testcafe-fixtures/index.js @@ -0,0 +1,19 @@ + +fixture `Get current CDP client` + .page `http://localhost:3000/fixtures/regression/gh-479-private/pages/index.html`; + +test(`Get current CDP client`, async t => { + const mainWindowId = await t.testRun.activeWindowId; + + let clientCDP = await t.getCurrentCDPClient(); + + await t.expect(clientCDP.webSocketUrl).contains(mainWindowId); + + await t.click('a').click('h1'); + + const childWindowId = await t.testRun.activeWindowId; + + clientCDP = await t.getCurrentCDPClient(); + + await t.expect(clientCDP.webSocketUrl).contains(childWindowId); +}); diff --git a/test/server/data/test-controller-reporter-expected/index.js b/test/server/data/test-controller-reporter-expected/index.js index a42e1c2f297..8812d43bbea 100644 --- a/test/server/data/test-controller-reporter-expected/index.js +++ b/test/server/data/test-controller-reporter-expected/index.js @@ -649,6 +649,24 @@ module.exports = { }, browser: { alias: 'test-browser', headless: false }, }, + { + testRunId: 'test-run-id', + name: 'getCurrentCDPClient', + command: { + type: 'get-current-c-d-p-client', + actionId: 'GetCurrentCDPClientCommand', + }, + test: { + id: 'test-id', + name: 'test-name', + phase: 'initial', + }, + fixture: { + id: 'fixture-id', + name: 'fixture-name', + }, + browser: { alias: 'test-browser', headless: false }, + }, { testRunId: 'test-run-id', name: 'switchToParentWindow', diff --git a/test/server/test-controller-events-test.js b/test/server/test-controller-events-test.js index 1452ba8e6be..0a54b4703c7 100644 --- a/test/server/test-controller-events-test.js +++ b/test/server/test-controller-events-test.js @@ -128,6 +128,7 @@ const actions = { switchToWindow: [{ id: 'window-id' }], closeWindow: [{ id: 'window-id' }], getCurrentWindow: [], + getCurrentCDPClient: [], switchToParentWindow: [], switchToPreviousWindow: [], setNativeDialogHandler: [() => true], diff --git a/ts-defs-src/test-api/test-controller.d.ts b/ts-defs-src/test-api/test-controller.d.ts index 4a996d4ddb9..6abe7bac471 100644 --- a/ts-defs-src/test-api/test-controller.d.ts +++ b/ts-defs-src/test-api/test-controller.d.ts @@ -413,6 +413,11 @@ interface TestController { * Retrieves a `window` object that corresponds to the currently open window. */ getCurrentWindow(): WindowDescriptorPromise; + + /** + * Retrieves a `Chrome DevTools Protocol` object that corresponds to the currently open window in native automation. + */ + getCurrentCDPClient(): TestControllerPromise; /** * Activates the window that corresponds to the `window` object.