diff --git a/src/browser/provider/built-in/dedicated/base.js b/src/browser/provider/built-in/dedicated/base.js index 6083d201a5a..1931845e622 100644 --- a/src/browser/provider/built-in/dedicated/base.js +++ b/src/browser/provider/built-in/dedicated/base.js @@ -105,6 +105,14 @@ export default { await this.resizeWindow(browserId, maximumSize.width, maximumSize.height, maximumSize.width, maximumSize.height); }, + async maximizeWindowNativeAutomation (browserId) { + await this.maximizeWindowNativeAutomation(browserId); + }, + + async resizeWindowNativeAutomation (browserId, width, height, currentWidth, currentHeight) { + await this.resizeBounds(browserId, width, height, currentWidth, currentHeight); + }, + async closeBrowserChildWindow (browserId, windowId) { const runtimeInfo = this.openedBrowsers[browserId]; const browserClient = this._getBrowserProtocolClient(runtimeInfo); diff --git a/src/browser/provider/built-in/dedicated/chrome/cdp-client/index.ts b/src/browser/provider/built-in/dedicated/chrome/cdp-client/index.ts index ca3a88f97d5..310bcb280a3 100644 --- a/src/browser/provider/built-in/dedicated/chrome/cdp-client/index.ts +++ b/src/browser/provider/built-in/dedicated/chrome/cdp-client/index.ts @@ -232,6 +232,55 @@ export class BrowserClient { } } + public async maximizeWindowNativeAutomation (): Promise { + const target = await getFirstTab(this._port); + const client = await this.getActiveClient(); + + if (client) { + const windowParams = await client.Browser.getWindowForTarget({ targetId: target.id }); + + await client.Browser.setWindowBounds({ windowId: windowParams.windowId, bounds: { windowState: 'maximized' } }); + } + } + + public async resizeBounds (newDimensions: Size): Promise { + const { viewportSize, config } = this._runtimeInfo; + + let nonClientWidth = 0; + let nonClientHeight = 0; + + if (viewportSize.outerWidth && viewportSize.outerHeight) { + nonClientWidth = viewportSize.outerWidth - viewportSize.width; + nonClientHeight = viewportSize.outerHeight - viewportSize.height; + } + + const target = await getFirstTab(this._port); + const client = await this.getActiveClient(); + + if (client) { + await this._setDeviceMetricsOverride(client, newDimensions.width, newDimensions.height, 1, config.mobile); + + const windowParams = await client.Browser.getWindowForTarget({ targetId: target.id }); + + if (windowParams.bounds.windowState !== 'normal') { + await client.Browser.setWindowBounds({ + windowId: windowParams.windowId, + bounds: { + windowState: 'normal', + }, + }); + } + + await client.Browser.setWindowBounds({ + windowId: windowParams.windowId, + bounds: { + width: newDimensions.width + nonClientWidth, + height: newDimensions.height + nonClientHeight, + }, + }); + } + } + public isHeadlessTab (): boolean { return !!this._parentTarget && this._config.headless; } diff --git a/src/browser/provider/built-in/dedicated/chrome/index.js b/src/browser/provider/built-in/dedicated/chrome/index.js index f5c2b7981f5..e6bd8eefdaf 100644 --- a/src/browser/provider/built-in/dedicated/chrome/index.js +++ b/src/browser/provider/built-in/dedicated/chrome/index.js @@ -144,6 +144,18 @@ export default { await runtimeInfo.browserClient.resizeWindow({ width, height }); }, + async maximizeWindowNativeAutomation (browserId) { + const { browserClient } = this.openedBrowsers[browserId]; + + await browserClient.maximizeWindowNativeAutomation(); + }, + + async resizeBounds (browserId, width, height, currentWidth, currentHeight) { + const { browserClient } = this.openedBrowsers[browserId]; + + await browserClient.resizeBounds({ width, height, currentWidth, currentHeight }); + }, + async startCapturingVideo (browserId) { const { browserClient } = this.openedBrowsers[browserId]; diff --git a/src/browser/provider/built-in/dedicated/chrome/interfaces.ts b/src/browser/provider/built-in/dedicated/chrome/interfaces.ts index a8b5be0ff0b..0e01ebd1c59 100644 --- a/src/browser/provider/built-in/dedicated/chrome/interfaces.ts +++ b/src/browser/provider/built-in/dedicated/chrome/interfaces.ts @@ -3,6 +3,8 @@ import { BrowserClient } from './cdp-client'; export interface Size { width: number; height: number; + outerWidth?: number; + outerHeight?: number; } export interface Config { diff --git a/src/browser/provider/index.ts b/src/browser/provider/index.ts index 0680086c1fd..39222cdfb8e 100644 --- a/src/browser/provider/index.ts +++ b/src/browser/provider/index.ts @@ -355,11 +355,15 @@ export default class BrowserProvider { return await this.plugin.isValidBrowserName(browserName); } - public async resizeWindow (browserId: string, width: number, height: number, currentWidth: number, currentHeight: number): Promise { + public async resizeWindow (browserId: string, width: number, height: number, currentWidth: number, currentHeight: number, isNativeAutomation: boolean): Promise { const canUseDefaultWindowActions = await this.canUseDefaultWindowActions(browserId); const customActionsInfo = await this.hasCustomActionForBrowser(browserId); const hasCustomResizeWindow = customActionsInfo.hasResizeWindow; + if (canUseDefaultWindowActions && !hasCustomResizeWindow && isNativeAutomation) { + await this.plugin.resizeWindowNativeAutomation(browserId, width, height, currentWidth, currentHeight); + return; + } if (canUseDefaultWindowActions && !hasCustomResizeWindow) { await this._resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight); @@ -381,11 +385,14 @@ export default class BrowserProvider { return await this.plugin.canResizeWindowToDimensions(browserId, width, height); } - public async maximizeWindow (browserId: string): Promise { + public async maximizeWindow (browserId: string, isNativeAutomation: boolean): Promise { const canUseDefaultWindowActions = await this.canUseDefaultWindowActions(browserId); const customActionsInfo = await this.hasCustomActionForBrowser(browserId); const hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; + if (canUseDefaultWindowActions && !hasCustomMaximizeWindow && isNativeAutomation) + return await this.plugin.maximizeWindowNativeAutomation(browserId); + if (canUseDefaultWindowActions && !hasCustomMaximizeWindow) return await this._maximizeLocalBrowserWindow(browserId); diff --git a/src/test-run/browser-manipulation-queue.js b/src/test-run/browser-manipulation-queue.js index b31e190b469..28d60cd02e0 100644 --- a/src/test-run/browser-manipulation-queue.js +++ b/src/test-run/browser-manipulation-queue.js @@ -5,12 +5,13 @@ import WARNING_MESSAGE from '../notifications/warning-message'; import { WindowDimensionsOverflowError } from '../errors/test-run/'; export default class BrowserManipulationQueue { - constructor (browserConnection, screenshotCapturer, warningLog) { + constructor (browserConnection, screenshotCapturer, warningLog, isNativeAutomation) { this.commands = []; this.browserId = browserConnection.id; this.browserProvider = browserConnection.provider; this.screenshotCapturer = screenshotCapturer; this.warningLog = warningLog; + this.isNativeAutomation = isNativeAutomation; } async _resizeWindow (width, height, currentWidth, currentHeight) { @@ -20,7 +21,7 @@ export default class BrowserManipulationQueue { throw new WindowDimensionsOverflowError(); try { - return await this.browserProvider.resizeWindow(this.browserId, width, height, currentWidth, currentHeight); + return await this.browserProvider.resizeWindow(this.browserId, width, height, currentWidth, currentHeight, this.isNativeAutomation); } catch (err) { this.warningLog.addWarning(WARNING_MESSAGE.resizeError, err.message); @@ -40,7 +41,7 @@ export default class BrowserManipulationQueue { async _maximizeWindow () { try { - return await this.browserProvider.maximizeWindow(this.browserId); + return await this.browserProvider.maximizeWindow(this.browserId, this.isNativeAutomation); } catch (err) { this.warningLog.addWarning(WARNING_MESSAGE.maximizeError, err.message); diff --git a/src/test-run/index.ts b/src/test-run/index.ts index 16a7be9ec2b..0063bceef20 100644 --- a/src/test-run/index.ts +++ b/src/test-run/index.ts @@ -338,7 +338,7 @@ export default class TestRun extends AsyncEventEmitter { this.disableDebugBreakpoints = false; this.debugReporterPluginHost = new ReporterPluginHost({ noColors: false }); - this.browserManipulationQueue = new BrowserManipulationQueue(browserConnection, screenshotCapturer, this.warningLog); + this.browserManipulationQueue = new BrowserManipulationQueue(browserConnection, screenshotCapturer, this.warningLog, nativeAutomation); this.debugLog = new TestRunDebugLog(this.browserConnection.userAgent); diff --git a/test/functional/fixtures/api/es-next/resize-window/test.js b/test/functional/fixtures/api/es-next/resize-window/test.js index 6c8152860cc..ed6a4e8bd53 100644 --- a/test/functional/fixtures/api/es-next/resize-window/test.js +++ b/test/functional/fixtures/api/es-next/resize-window/test.js @@ -30,6 +30,10 @@ describe('[API] Resize window actions', function () { errorInEachBrowserContains(errs, '> 76 | await t.resizeWindow(500, 500);', 0); }); }); + + it('Should resize the window after maximizeWindow', function () { + return runTests('./testcafe-fixtures/resize-window-test.js', 'Resize the window after maximizeWindow', { only: 'chrome' }); + }); }); describe('t.resizeWindowToFitDevice', function () { diff --git a/test/functional/fixtures/api/es-next/resize-window/testcafe-fixtures/resize-window-test.js b/test/functional/fixtures/api/es-next/resize-window/testcafe-fixtures/resize-window-test.js index f8e997614bc..6732169a72b 100644 --- a/test/functional/fixtures/api/es-next/resize-window/testcafe-fixtures/resize-window-test.js +++ b/test/functional/fixtures/api/es-next/resize-window/testcafe-fixtures/resize-window-test.js @@ -88,3 +88,15 @@ test('Too big size', async t => { await t.resizeWindow(hugeWidth, hugeHeight); }); + +test('Resize the window after maximizeWindow', async t => { + await t.maximizeWindow(); + + expect(await getWindowWidth()).to.be.at.least(640); + expect(await getWindowHeight()).to.be.at.least(480); + + await t.resizeWindow(640, 480); + + expect(await getWindowWidth()).equals(640); + expect(await getWindowHeight()).equals(480); +});