From 167fe596ab501c394b75f260b78fe6a4047e64da Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 10:24:30 +0400 Subject: [PATCH 1/2] 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-session/pages/child.html | 10 ++++++++++ .../get-current-cdp-session/pages/index.html | 10 ++++++++++ .../es-next/get-current-cdp-session/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 | 10 ++++++++++ 16 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-session/pages/child.html create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-session/pages/index.html create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-session/test.js create mode 100644 test/functional/fixtures/api/es-next/get-current-cdp-session/testcafe-fixtures/index.js diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index 0f5c4d3395f..7cfd9153f47 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -35,6 +35,7 @@ import { OpenWindowCommand, CloseWindowCommand, GetCurrentWindowCommand, + GetCurrentCDPSessionCommand, SwitchToWindowCommand, SwitchToWindowByPredicateCommand, SwitchToParentWindowCommand, @@ -518,6 +519,13 @@ export default class TestController { return this.enqueueCommand(GetCurrentWindowCommand); } + [delegatedAPI(GetCurrentCDPSessionCommand.methodName)] () { + const callsite = getCallsiteForMethod(GetCurrentCDPSessionCommand.methodName); + const command = this._createCommand(GetCurrentCDPSessionCommand, {}, 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..9e9cf5a7b85 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 getCurrentCDPSession (): Promise { + return this.provider.getCurrentCDPSession(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..f5c2b7981f5 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 getCurrentCDPSession (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.getCurrentCDPSession(browserId); await navigateTo(cdpClient, url); }, async dispatchNativeAutomationEvent (browserId, type, options) { - const cdpClient = await this._getActiveCDPClient(browserId); + const cdpClient = await this.getCurrentCDPSession(browserId); await dispatchNativeAutomationEvent(cdpClient, type, options); }, async dispatchNativeAutomationEventSequence (browserId, eventSequence) { - const cdpClient = await this._getActiveCDPClient(browserId); + const cdpClient = await this.getCurrentCDPSession(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..0680086c1fd 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 getCurrentCDPSession (browserId: string): Promise { + return this.plugin.getCurrentCDPSession(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..413e439800d 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 getCurrentCDPSession (/*browserId*/) { + return Promise.resolve(); + } } diff --git a/src/test-run/commands/actions.d.ts b/src/test-run/commands/actions.d.ts index 07b07fe8d94..9bdaf9ba4b0 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 GetCurrentCDPSessionCommand 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..f960af8f2e0 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 GetCurrentCDPSessionCommand extends ActionCommandBase { + static methodName = camelCase(TYPE.getCurrentCDPSession); + + constructor (obj, testRun, validateProperties) { + super(obj, testRun, TYPE.getCurrentCDPSession, 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..eca19b7b208 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', + getCurrentCDPSession: 'get-current-c-d-p-session', 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..16a7be9ec2b 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 getCurrentCDPSession (): Promise { + return this.browserConnection.getCurrentCDPSession(); + } + 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.getCurrentCDPSession) + return this.getCurrentCDPSession(); + return this._enqueueCommand(command, callsite as CallsiteRecord); } diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-session/pages/child.html b/test/functional/fixtures/api/es-next/get-current-cdp-session/pages/child.html new file mode 100644 index 00000000000..58376b2bbbc --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-session/pages/child.html @@ -0,0 +1,10 @@ + + + + + Title + + +

new window

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

Open new window

+ + diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-session/test.js b/test/functional/fixtures/api/es-next/get-current-cdp-session/test.js new file mode 100644 index 00000000000..d075a8e8dd8 --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-session/test.js @@ -0,0 +1,7 @@ +const { onlyInNativeAutomation } = require('../../../../utils/skip-in'); + +describe('[API] Get current CDP session', function () { + onlyInNativeAutomation('Should return current CPD', function () { + return runTests('./testcafe-fixtures/index.js', 'Get current CDP session', { experimentalMultipleWindows: true }); + }); +}); diff --git a/test/functional/fixtures/api/es-next/get-current-cdp-session/testcafe-fixtures/index.js b/test/functional/fixtures/api/es-next/get-current-cdp-session/testcafe-fixtures/index.js new file mode 100644 index 00000000000..19d2f587704 --- /dev/null +++ b/test/functional/fixtures/api/es-next/get-current-cdp-session/testcafe-fixtures/index.js @@ -0,0 +1,19 @@ + +fixture `Get current CDP session` + .page `http://localhost:3000/fixtures/api/es-next/get-current-cdp-session/pages/index.html`; + +test(`Get current CDP session`, async t => { + const mainWindowId = await t.testRun.activeWindowId; + + let clientCDP = await t.getCurrentCDPSession(); + + await t.expect(clientCDP.webSocketUrl).contains(mainWindowId); + + await t.click('a').click('h1'); + + const childWindowId = await t.testRun.activeWindowId; + + clientCDP = await t.getCurrentCDPSession(); + + 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..85b8af9163d 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: 'getCurrentCDPSession', + command: { + type: 'get-current-c-d-p-session', + actionId: 'GetCurrentCDPSessionCommand', + }, + 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..c5768c507da 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: [], + getCurrentCDPSession: [], 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..cebc370c723 100644 --- a/ts-defs-src/test-api/test-controller.d.ts +++ b/ts-defs-src/test-api/test-controller.d.ts @@ -90,6 +90,8 @@ interface Browser { type WindowDescriptor = unknown; +type CDPSession = unknown; + interface WindowFilterData { /** * The window title. @@ -413,6 +415,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. + */ + getCurrentCDPSession(): CDPSessionPromise; /** * Activates the window that corresponds to the `window` object. @@ -576,3 +583,6 @@ interface TestControllerPromise extends TestController, Promise { interface WindowDescriptorPromise extends TestControllerPromise { } +interface CDPSessionPromise extends TestControllerPromise { +} + From 273e331ea13cb7cd6dc5ef67ee4b904da9dafb5d Mon Sep 17 00:00:00 2001 From: PavelMor25 <77216072+PavelMor25@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:21:13 +0400 Subject: [PATCH 2/2] Update ts-defs-src/test-api/test-controller.d.ts Co-authored-by: Gene <43554315+titerman@users.noreply.github.com> --- ts-defs-src/test-api/test-controller.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts-defs-src/test-api/test-controller.d.ts b/ts-defs-src/test-api/test-controller.d.ts index cebc370c723..87fb6edbfc6 100644 --- a/ts-defs-src/test-api/test-controller.d.ts +++ b/ts-defs-src/test-api/test-controller.d.ts @@ -417,7 +417,7 @@ interface TestController { getCurrentWindow(): WindowDescriptorPromise; /** - * Retrieves a `Chrome DevTools Protocol` object that corresponds to the currently open window in native automation. + * Retrieves a `Chrome DevTools Protocol` object that corresponds to the currently open window (native automation only). */ getCurrentCDPSession(): CDPSessionPromise;