From 07875177e2fc86bf9e516e44bd0026f342927875 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Thu, 20 Apr 2023 11:15:54 -0700 Subject: [PATCH] fix: make whitespace in execute methods insignificant How this works may change in the future, but XCUITestDriver users expect to be able to use `mobile:foo` instead of or in addition to `mobile: foo`. Any change on the Appium side affects more than just this driver, so the change should happen here for now to fix the extant regression. In addition, updated `package-lock.json` since it was out-of-date w/r/t the package version. See https://github.com/appium/appium/issues/18553 Closes https://github.com/appium/appium/issues/18551 --- lib/commands/execute.js | 12 +++++++++--- package-lock.json | 4 ++-- test/unit/driver-specs.js | 25 +++++++++++++++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/commands/execute.js b/lib/commands/execute.js index dadc1e777b..c0c0fc7357 100644 --- a/lib/commands/execute.js +++ b/lib/commands/execute.js @@ -34,7 +34,7 @@ function executeMethodExpectsParam(script, param) { * @returns {script is keyof XCUITestDriver.executeMethodMap} */ function isExecuteMethod(script) { - return script.match(/^mobile:/) && script in XCUITestDriver.executeMethodMap; + return script in XCUITestDriver.executeMethodMap; } /** @@ -64,7 +64,9 @@ function preprocessExecuteMethodArgs(script, args) { * Most of these Execute Methods (typically beginning with `mobile*`) will accept an `Element|string` for `elementId`, in practice they will only ever get a `string`. `Element|string` in the method's docstring is simply for documentation purposes. */ if ('elementId' in executeMethodArgs && executeMethodExpectsParam(script, 'elementId')) { - executeMethodArgs.elementId = util.unwrapElement(/** @type {import('@appium/types').Element|string} */(executeMethodArgs.elementId)); + executeMethodArgs.elementId = util.unwrapElement( + /** @type {import('@appium/types').Element|string} */ (executeMethodArgs.elementId) + ); } return executeMethodArgs; @@ -111,11 +113,15 @@ export default { */ async execute(script, args) { // TODO: create a type that converts args to the parameters of the associated method using the `command` prop of `executeMethodMap` + // this replaces "mobile:foo" with "mobile: foo" + if (/^mobile:\S/.test(script)) { + script = script.replace(/^mobile:/, 'mobile: '); + } if (isExecuteMethod(script)) { const executeMethodArgs = preprocessExecuteMethodArgs(script, args); return await this.executeMethod(script, [executeMethodArgs]); } else if (this.isWebContext()) { - const atomsArgs = this.convertElementsForAtoms(/** @type {readonly any[]} */(args)); + const atomsArgs = this.convertElementsForAtoms(/** @type {readonly any[]} */ (args)); const result = await this.executeAtom('execute_script', [script, atomsArgs]); return this.cacheWebElements(result); } else { diff --git a/package-lock.json b/package-lock.json index 9a1eacd4f9..c6f1812556 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "appium-xcuitest-driver", - "version": "4.23.1", + "version": "4.24.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "appium-xcuitest-driver", - "version": "4.23.1", + "version": "4.24.1", "license": "Apache-2.0", "dependencies": { "@xmldom/xmldom": "0.8.7", diff --git a/test/unit/driver-specs.js b/test/unit/driver-specs.js index 75d446b46b..59195cb609 100644 --- a/test/unit/driver-specs.js +++ b/test/unit/driver-specs.js @@ -9,8 +9,10 @@ import chai from 'chai'; import * as utils from '../../lib/utils'; import {MOCHA_LONG_TIMEOUT} from './helpers'; import sinonChai from 'sinon-chai'; +import chaiAsPromised from 'chai-as-promised'; chai.should(); -chai.use(sinonChai); +chai.use(sinonChai).use(chaiAsPromised); + const expect = chai.expect; const caps = { @@ -114,8 +116,10 @@ describe('XCUITestDriver', function () { setReduceTransparency: _.noop, }; realDevice = null; - // eslint-disable-next-line require-await - sandbox.stub(driver, 'determineDevice').callsFake(async () => ({device, realDevice, udid: 'stuff'})); + sandbox + .stub(driver, 'determineDevice') + // eslint-disable-next-line require-await + .callsFake(async () => ({device, realDevice, udid: 'stuff'})); sandbox.stub(driver, 'configureApp'); sandbox.stub(driver, 'startLogCapture'); sandbox.stub(driver, 'startSim'); @@ -191,13 +195,26 @@ describe('XCUITestDriver', function () { spy.notCalled.should.be.true; }); }); + + describe('execute', function () { + it('should allow execute methods without whitespace', async function () { + const driver = new XCUITestDriver(); + const jwproxy = new JWProxy(); + const value = {some: 'thing'}; + sandbox.stub(jwproxy, 'command').resolves(value); + driver.wda = { + jwproxy, + }; + await expect(driver.execute('mobile:deviceInfo')).to.eventually.eql(value); + }); + }); }); describe('installOtherApps', function () { /** @type {XCUITestDriver} */ let driver; - beforeEach(function() { + beforeEach(function () { driver = new XCUITestDriver(); });