Skip to content

Commit

Permalink
feat: Support resize window (#10)
Browse files Browse the repository at this point in the history
* feat: Support resize window

* validate before setting the browser size

* extract window file

* cleanup

* revise get window size function

* remove deprecated window related functions

* pack variables

* sort params

* remove unnecessary check

* cleanup

* cleanup

* rename

* refine comments
  • Loading branch information
tianfeng92 authored Aug 1, 2024
1 parent 58fa94b commit e45af5b
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 5 deletions.
49 changes: 49 additions & 0 deletions src/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import wd, { Client } from 'webdriver';
import { isDevice, isSimulator } from './device';
import { CreateSessionError } from './errors';

export type Size = {
width: number;
height: number;
};

export class SauceDriver {
private readonly username: string;
private readonly accessKey: string;
Expand Down Expand Up @@ -90,4 +95,48 @@ export class SauceDriver {
await this.sessions.get(browserId)?.deleteSession();
this.sessions.delete(browserId);
}

/**
* Calculates the required browser window size to accommodate the requested viewport size.
* @param newViewport - The requested viewport size.
* @param viewport - The current size of the viewport.
* @param windowSize - The current size of the browser window, including its utility area.
* @returns - The required browser window size.
*/
getNewWindowSize(newViewport: Size, viewport: Size, windowSize: Size): Size {
const horizontalDiff = windowSize.width - viewport.width;
const verticalDiff = windowSize.height - viewport.height;

return {
width: newViewport.width + horizontalDiff,
height: newViewport.height + verticalDiff,
};
}

/**
* Resizes the browser window to match the requested viewport size.
* @param browserId - The ID of the browser session.
* @param viewport - The requested viewport size.
* @param currentViewport - The current viewport size.
*/
async resizeWindow(browserId: string, viewport: Size, currentViewport: Size) {
const browser = this.sessions.get(browserId);
if (!browser) {
return;
}

const currentWindowSize = await browser.getWindowRect();
const newWindowSize = this.getNewWindowSize(
viewport,
currentViewport,
currentWindowSize,
);

await browser.setWindowRect(
null,
null,
newWindowSize.width,
newWindowSize.height,
);
}
}
9 changes: 9 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,12 @@ export class CreateSessionError extends Error {
this.name = 'CreateSessionError';
}
}

export class WindowSizeRangeError extends Error {
constructor() {
super(
'Invalid resize value: width and height must be within the range of 0 to 2^31 - 1.',
);
this.name = 'WindowSizeRangeError';
}
}
30 changes: 25 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SauceDriver } from './driver.js';
import { AuthError, TunnelNameError } from './errors';
import { AuthError, TunnelNameError, WindowSizeRangeError } from './errors';
import { getPlatforms } from './api';
import { rcompareOses, rcompareVersions } from './sort';
import { isDevice } from './device.js';
Expand All @@ -8,6 +8,9 @@ type Browser = string;
type Version = string;
type Os = string;

// Maximum window size in pixels.
const maxWindowSize = 2 ** 31 - 1;

let sauceDriver: SauceDriver;

const platforms: string[] = [];
Expand Down Expand Up @@ -196,13 +199,30 @@ module.exports = {
},

/**
* Called by TestCafe to resize the browser window.
* Called by TestCafe to resize the browser window to match the requested viewport size.
*
* https://github.com/DevExpress/testcafe/blob/master/src/browser/provider/plugin-host.js#L126
*
* @param browserId - The id of the browser session.
* @param width - The requested viewport width in pixels.
* @param height - The requested viewport height in pixels.
* @param currentWidth - The current viewport width in pixels.
* @param currentHeight - The current viewport height in pixels.
*/
async resizeWindow(/* id, width, height, currentWidth, currentHeight */) {
this.reportWarning(
'The window resize functionality is not supported by the Sauce Labs browser provider plugin.',
async resizeWindow(
browserId: string,
width: number,
height: number,
currentWidth: number,
currentHeight: number,
) {
if (width > maxWindowSize || height > maxWindowSize) {
throw new WindowSizeRangeError();
}
return sauceDriver.resizeWindow(
browserId,
{ width, height },
{ width: currentWidth, height: currentHeight },
);
},

Expand Down

0 comments on commit e45af5b

Please sign in to comment.