Skip to content

Commit

Permalink
feat: use new selenium atoms from remote debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
jlipps committed Aug 16, 2023
1 parent a564156 commit 2707c01
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 151 deletions.
11 changes: 6 additions & 5 deletions lib/commands/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const commands = {
async getWindowSize(windowHandle = 'current') {
if (windowHandle !== 'current') {
throw new errors.NotYetImplementedError(
'Currently only getting current window size is supported.'
'Currently only getting current window size is supported.',
);
}

Expand Down Expand Up @@ -74,7 +74,7 @@ const commands = {
const parsedTimestamp = moment.utc(stdout, inputFormat);
if (!parsedTimestamp.isValid()) {
this.log.warn(
`Cannot parse the timestamp '${stdout}' returned by '${cmd}' command. Returning it as is`
`Cannot parse the timestamp '${stdout}' returned by '${cmd}' command. Returning it as is`,
);
return stdout;
}
Expand Down Expand Up @@ -141,7 +141,7 @@ const commands = {
async launchApp() {
this.log.warn(
'launchApp is deprecated. Please use activateApp, ' +
'mobile:launchApp or create a new session instead.'
'mobile:launchApp or create a new session instead.',
);
const appName = this.opts.app || this.opts.bundleId;
try {
Expand All @@ -160,7 +160,7 @@ const commands = {
async closeApp() {
this.log.warn(
'closeApp is deprecated. Please use terminateApp, ' +
'mobile:terminateApp, mobile:killApp or quit the session instead.'
'mobile:terminateApp, mobile:killApp or quit the session instead.',
);
const appName = this.opts.app || this.opts.bundleId;
try {
Expand Down Expand Up @@ -287,7 +287,8 @@ const helpers = {
* @this {XCUITestDriver}
*/
async getWindowSizeWeb() {
return await this.executeAtom('get_window_size', []);
const script = 'return {width: window.innerWidth, height: window.innerHeight}';
return await this.executeAtom('execute_script', [script]);
},
/**
* @this {XCUITestDriver}
Expand Down
67 changes: 37 additions & 30 deletions lib/commands/gesture.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function toElementOrApplicationId(driver, elementId) {
return util.unwrapElement(elementId);
}
return util.unwrapElement(
await driver.findNativeElementOrElements(`class name`, `XCUIElementTypeApplication`, false)
await driver.findNativeElementOrElements(`class name`, `XCUIElementTypeApplication`, false),
);
}

Expand All @@ -47,7 +47,7 @@ function asFloat(value, paramName) {
const num = parseFloat(String(value));
if (Number.isNaN(num)) {
throw new errors.InvalidArgumentError(
`"${paramName}" parameter should be a valid number. "${value}" is given instead`
`"${paramName}" parameter should be a valid number. "${value}" is given instead`,
);
}
return num;
Expand All @@ -65,7 +65,7 @@ function asInt(value, paramName) {
const num = parseInt(String(value), 10);
if (Number.isNaN(num)) {
throw new errors.InvalidArgumentError(
`"${paramName}" parameter should be a valid integer. "${value}" is given instead`
`"${paramName}" parameter should be a valid integer. "${value}" is given instead`,
);
}
return num;
Expand All @@ -87,7 +87,7 @@ export function gesturesChainToString(gestures, keysToInclude = ['options']) {
`${item.action}` +
`(${_.map(
otherKeys,
(x) => x + '=' + (_.isPlainObject(item[x]) ? JSON.stringify(item[x]) : item[x])
(x) => x + '=' + (_.isPlainObject(item[x]) ? JSON.stringify(item[x]) : item[x]),
).join(', ')})`
);
}
Expand All @@ -110,20 +110,15 @@ const commands = {
el = util.unwrapElement(el);

if (this.isWebContext()) {
let {x, y} = await this.getLocation(el);
let coords = {
x: x + xoffset,
y: y + yoffset,
};
this.curWebCoords = coords;
let atomsElement = this.getAtomsElement(el);
let relCoords = {x: xoffset, y: yoffset};
await this.executeAtom('move_mouse', [atomsElement, relCoords]);
throw new errors.UnknownMethodError(
'The moveTo command is not available in the web context. Use the Actions API in the ' +
'native context instead',
);
} else {
if (_.isNil(el)) {
if (!this.curCoords) {
throw new errors.UnknownError(
'Current cursor position unknown, please use moveTo with an element the first time.'
'Current cursor position unknown, please use moveTo with an element the first time.',
);
}
this.curCoords = {
Expand Down Expand Up @@ -167,7 +162,19 @@ const commands = {
await this.nativeWebTap(el);
} else {
const atomsElement = this.getAtomsElement(el);
return await this.executeAtom('click', [atomsElement]);
// clicking can cause an alert to pop up and freeze the event loop, meaning the click atom
// itself never returns. we have alert handling in `waitForAtom` but with click, we create
// a special case where if a click results in an unexpected alert error, we just return
// control to the client. they will encounter the error on their next command, which mirrors
// the behaviour of selenium.
try {
return await this.executeAtom('click', [atomsElement]);
} catch (err) {
if (err.error === errors.UnexpectedAlertOpenError.error()) {
return;
}
throw err;
}
}
},
/**
Expand Down Expand Up @@ -197,14 +204,14 @@ const commands = {
pointerType: 'touch',
},
}
: {}
)
: {},
),
)
.map((action) => {
const modifiedAction = _.clone(action) || {};
// Selenium API unexpectedly inserts zero pauses, which are not supported by WDA
modifiedAction.actions = (action.actions || []).filter(
(innerAction) => !(innerAction.type === 'pause' && innerAction.duration === 0)
(innerAction) => !(innerAction.type === 'pause' && innerAction.duration === 0),
);
return modifiedAction;
});
Expand All @@ -229,7 +236,7 @@ const commands = {
this.log.errorAndThrow(
'The Touch API is aimed for usage in NATIVE context. ' +
'Consider using "execute" API with custom events trigger script ' +
`to emulate touch events being in WEBVIEW context. Original error: ${e.message}`
`to emulate touch events being in WEBVIEW context. Original error: ${e.message}`,
);
}
},
Expand All @@ -255,7 +262,7 @@ const commands = {
this.log.errorAndThrow(
'The MultiTouch API is aimed for usage in NATIVE context. ' +
'Consider using "execute" API with custom events trigger script ' +
`to emulate multitouch events being in WEBVIEW context. Original error: ${e.message}`
`to emulate multitouch events being in WEBVIEW context. Original error: ${e.message}`,
);
}
},
Expand Down Expand Up @@ -338,7 +345,7 @@ const helpers = {
} else if (direction) {
if (!SUPPORTED_GESTURE_DIRECTIONS.includes(_.toLower(direction))) {
throw new errors.InvalidArgumentError(
`'direction' must be one of: ${SUPPORTED_GESTURE_DIRECTIONS}`
`'direction' must be one of: ${SUPPORTED_GESTURE_DIRECTIONS}`,
);
}
params.direction = direction;
Expand All @@ -349,7 +356,7 @@ const helpers = {
} else {
throw new errors.InvalidArgumentError(
'Mobile scroll supports the following strategies: name, direction, predicateString, and toVisible. ' +
'Specify one of these'
'Specify one of these',
);
}
// we can also optionally pass a distance which appears to be a ratio of
Expand All @@ -369,7 +376,7 @@ const helpers = {
async mobileSwipe(direction, velocity, elementId) {
if (!SUPPORTED_GESTURE_DIRECTIONS.includes(_.toLower(direction))) {
throw new errors.InvalidArgumentError(
`'direction' must be one of: ${SUPPORTED_GESTURE_DIRECTIONS}`
`'direction' must be one of: ${SUPPORTED_GESTURE_DIRECTIONS}`,
);
}
const params = {direction};
Expand Down Expand Up @@ -558,7 +565,7 @@ const helpers = {
fromX,
fromY,
toX,
toY
toY,
) {
const params = {
pressDuration: asFloat(pressDuration, 'pressDuration'),
Expand All @@ -570,14 +577,14 @@ const helpers = {
toElementId = toElementId ? util.unwrapElement(toElementId) : undefined;
if (!toElementId) {
throw new errors.InvalidArgumentError(
`"toElementId" parameter is mandatory for "dragFromToWithVelocity" call`
`"toElementId" parameter is mandatory for "dragFromToWithVelocity" call`,
);
}
params.toElement = toElementId;
return await this.proxyCommand(
`/wda/element/${fromElementId}/pressAndDragWithVelocity`,
'POST',
params
params,
);
}
params.fromX = asFloat(fromX, 'fromX');
Expand Down Expand Up @@ -606,7 +613,7 @@ const helpers = {
async mobileTapWithNumberOfTaps(elementId, numberOfTouches, numberOfTaps) {
if (!elementId) {
throw new errors.InvalidArgumentError(
'Element id is expected to be set for tapWithNumberOfTaps method'
'Element id is expected to be set for tapWithNumberOfTaps method',
);
}
const params = {
Expand Down Expand Up @@ -658,13 +665,13 @@ const helpers = {
elementId = /** @type {string} */ (toElementId(elementId));
if (!elementId) {
throw new errors.InvalidArgumentError(
'elementId is expected to be set for selectPickerWheelValue method'
'elementId is expected to be set for selectPickerWheelValue method',
);
}
if (!_.isString(order) || !['next', 'previous'].includes(order.toLowerCase())) {
throw new errors.InvalidArgumentError(
`The mandatory 'order' parameter is expected to be equal either to 'next' or 'previous'. ` +
`'${order}' is given instead`
`'${order}' is given instead`,
);
}
const params = {order};
Expand Down Expand Up @@ -704,7 +711,7 @@ const helpers = {
elementId = /** @type {string} */ (toElementId(elementId));
if (!elementId) {
throw new errors.InvalidArgumentError(
'Element id is expected to be set for rotateElement method'
'Element id is expected to be set for rotateElement method',
);
}
const params = {
Expand Down
Loading

0 comments on commit 2707c01

Please sign in to comment.