diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 533396cb..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -coverage -build -test/assets diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 950cea2f..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": ["@appium/eslint-config-appium-ts"], - "overrides": [ - { - "files": "test/**/*.js", - "rules": { - "func-names": "off", - "@typescript-eslint/no-var-requires": "off" - } - }, - { - "files": "scripts/**/*", - "parserOptions": {"sourceType": "script"}, - "rules": { - "@typescript-eslint/no-var-requires": "off" - } - } - ], - "rules": { - "require-await": "error" - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..9739375e --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,10 @@ +import appiumConfig from '@appium/eslint-config-appium-ts'; + +export default [ + ...appiumConfig, + { + ignores: [ + 'test/assets/**', + ], + }, +]; diff --git a/lib/defaults-utils.js b/lib/defaults-utils.js index 077488d3..093ee8af 100644 --- a/lib/defaults-utils.js +++ b/lib/defaults-utils.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import { DOMParser, XMLSerializer } from '@xmldom/xmldom'; import { exec } from 'teen_process'; import B from 'bluebird'; -import log from './logger'; +import { log } from './logger'; /** * Serializes the given value to plist-compatible diff --git a/lib/device-utils.js b/lib/device-utils.js index ca378f97..f25d982c 100644 --- a/lib/device-utils.js +++ b/lib/device-utils.js @@ -1,4 +1,4 @@ -import Simctl from 'node-simctl'; +import { Simctl } from 'node-simctl'; /** * @param {import('@appium/types').StringRecord} [simctlOpts] diff --git a/lib/extensions/applications.js b/lib/extensions/applications.js index 6b08a22b..f92e7467 100644 --- a/lib/extensions/applications.js +++ b/lib/extensions/applications.js @@ -37,7 +37,7 @@ export async function getUserInstalledBundleIdsByBundleName (bundleName) { bundleInfoPromises.push((async () => { try { return await plist.parsePlistFile(infoPlist); - } catch (ign) {} + } catch {} })()); } const bundleInfos = (await B.all(bundleInfoPromises)).filter(_.isPlainObject); @@ -69,14 +69,14 @@ export async function isAppInstalled (bundleId) { return false; } return await fs.exists(appContainer); - } catch (err) { + } catch { // get_app_container subcommand fails for system applications, // so we try the hidden appinfo subcommand, which prints correct info for // system/hidden apps try { const info = await this.simctl.appInfo(bundleId); return info.includes('ApplicationType'); - } catch (ign) {} + } catch {} } return false; } @@ -113,7 +113,7 @@ export async function launchApp (bundleId, opts = {}) { waitMs: timeoutMs, intervalMs: 300 }); - } catch (e) { + } catch { throw new Error(`App '${bundleId}' is not runnning after ${timeoutMs}ms timeout.`); } } @@ -160,7 +160,7 @@ export async function scrubApp (bundleId) { try { await this.terminateApp(bundleId); - } catch (ign) {} + } catch {} await B.all(appFiles.map((p) => fs.rimraf(p))); } diff --git a/lib/extensions/geolocation.js b/lib/extensions/geolocation.js index 32c5bfc2..568727bb 100644 --- a/lib/extensions/geolocation.js +++ b/lib/extensions/geolocation.js @@ -46,7 +46,7 @@ export async function setGeolocation (latitude, longitude) { async function setLocationWithLyft (udid, latitude, longitude) { try { await fs.which(LYFT_SET_LOCATION); - } catch (e) { + } catch { throw new Error(`'${LYFT_SET_LOCATION}' binary has not been found in your PATH. ` + 'Please install it as "brew install lyft/formulae/set-simulator-location" by brew or ' + 'read https://github.com/MobileNativeFoundation/set-simulator-location to set ' + diff --git a/lib/extensions/misc.js b/lib/extensions/misc.js index 8406082c..d0e6a0a0 100644 --- a/lib/extensions/misc.js +++ b/lib/extensions/misc.js @@ -22,7 +22,6 @@ export async function shake () { * @returns {Promise} `true` if the certificate has been successfully installed * or `false` if it has already been there */ -// eslint-disable-next-line require-await export async function addCertificate (payload, opts = {}) { throw new Error(`Xcode SDK '${this.xcodeVersion}' is too old add certificates`); } @@ -35,7 +34,6 @@ export async function addCertificate (payload, opts = {}) { * @returns {Promise} * @since Xcode SDK 11.4 */ -// eslint-disable-next-line require-await export async function pushNotification (payload) { throw new Error(`Xcode SDK '${this.xcodeVersion}' is too old to push notifications`); } diff --git a/lib/extensions/permissions.js b/lib/extensions/permissions.js index 72c7f8ea..707a7891 100644 --- a/lib/extensions/permissions.js +++ b/lib/extensions/permissions.js @@ -120,7 +120,7 @@ async function execSQLiteQuery (db, query) { async function execWix (args) { try { await fs.which(WIX_SIM_UTILS); - } catch (e) { + } catch { throw new Error( `${WIX_SIM_UTILS} binary has not been found in your PATH. ` + `Please install it ('brew tap wix/brew && brew install wix/brew/applesimutils') to ` + diff --git a/lib/extensions/safari.js b/lib/extensions/safari.js index 7005d6c8..1058c61d 100644 --- a/lib/extensions/safari.js +++ b/lib/extensions/safari.js @@ -49,7 +49,7 @@ export async function openUrl (url) { waitMs: SAFARI_STARTUP_TIMEOUT_MS, intervalMs: 500, }); - } catch (err) { + } catch { const secondsElapsed = timer.getDuration().asSeconds; if (psError) { this.log.warn(`Mobile Safari process existence cannot be verified after ${secondsElapsed.toFixed(3)}s. ` + @@ -73,7 +73,7 @@ export async function openUrl (url) { export async function scrubSafari (keepPrefs = true) { try { await this.terminateApp(MOBILE_SAFARI_BUNDLE_ID); - } catch (ign) {} + } catch {} this.log.debug('Scrubbing Safari data files'); const safariData = await this.simctl.getAppContainer(MOBILE_SAFARI_BUNDLE_ID, 'data'); diff --git a/lib/extensions/settings.js b/lib/extensions/settings.js index 6501f8fd..1d04c8d9 100644 --- a/lib/extensions/settings.js +++ b/lib/extensions/settings.js @@ -87,7 +87,7 @@ export async function updateSettings (domain, updates) { * @since Xcode SDK 11.4 * @returns {Promise} */ -export async function setAppearance (value) { // eslint-disable-line require-await +export async function setAppearance (value) { throw new Error(`Xcode SDK '${this.xcodeVersion}' is too old to set UI appearance`); } @@ -99,7 +99,7 @@ export async function setAppearance (value) { // eslint-disable-line require-awa * @returns {Promise} * @since Xcode SDK 11.4 */ -export async function getAppearance () { // eslint-disable-line require-await +export async function getAppearance () { throw new Error(`Xcode SDK '${this.xcodeVersion}' is too old to get UI appearance`); } diff --git a/lib/simulator-xcode-10.js b/lib/simulator-xcode-10.js index 76338af6..3afead57 100644 --- a/lib/simulator-xcode-10.js +++ b/lib/simulator-xcode-10.js @@ -9,7 +9,7 @@ import _ from 'lodash'; import path from 'path'; import B from 'bluebird'; import { getPath as getXcodePath } from 'appium-xcode'; -import Simctl from 'node-simctl'; +import { Simctl } from 'node-simctl'; import * as appExtensions from './extensions/applications'; import * as biometricExtensions from './extensions/biometric'; import * as safariExtensions from './extensions/safari'; @@ -238,7 +238,7 @@ export class SimulatorXcode10 extends EventEmitter { try { await this.simctl.getEnv('dummy'); return true; - } catch (e) { + } catch { return false; } } @@ -269,7 +269,7 @@ export class SimulatorXcode10 extends EventEmitter { let stdout; try { ({stdout} = await exec('pgrep', ['-fn', `${SIMULATOR_APP_NAME}/Contents/MacOS/`])); - } catch (e) { + } catch { return null; } if (isNaN(parseInt(stdout, 10))) { @@ -383,7 +383,7 @@ export class SimulatorXcode10 extends EventEmitter { waitMs, intervalMs: 100, }); - } catch (err) { + } catch { throw new Error(`Simulator is not in 'Shutdown' state after ${waitMs}ms`); } } @@ -458,7 +458,7 @@ export class SimulatorXcode10 extends EventEmitter { waitMs: 5000, intervalMs: 100, }); - } catch (e) { + } catch { if (!await this.isRunning()) { throw new Error(`Simulator with UDID '${this.udid}' cannot be transitioned to headless mode`); } diff --git a/lib/simulator-xcode-15.js b/lib/simulator-xcode-15.js index 3becdd39..f355c2de 100644 --- a/lib/simulator-xcode-15.js +++ b/lib/simulator-xcode-15.js @@ -40,7 +40,7 @@ export class SimulatorXcode15 extends SimulatorXcode14 { '-c', 'print CFBundleIdentifier', infoPlistPath ]); return _.trim(stdout); - } catch (ign) { + } catch { return null; } }; @@ -65,7 +65,7 @@ export class SimulatorXcode15 extends SimulatorXcode14 { try { const appContainer = await this.simctl.getAppContainer(bundleId); return appContainer.endsWith('.app') && await fs.exists(appContainer); - } catch (ign) { + } catch { // get_app_container subcommand fails for system applications, // as well as the hidden appinfo command return (await this._fetchSystemAppBundleIds()).has(bundleId); diff --git a/lib/simulator.js b/lib/simulator.js index 83d7cb4c..819924c8 100644 --- a/lib/simulator.js +++ b/lib/simulator.js @@ -3,27 +3,10 @@ import { SimulatorXcode11 } from './simulator-xcode-11'; import { SimulatorXcode11_4 } from './simulator-xcode-11.4'; import { SimulatorXcode14 } from './simulator-xcode-14'; import { SimulatorXcode15 } from './simulator-xcode-15'; -import { getSimulatorInfo } from './utils'; -import xcode from 'appium-xcode'; +import { getSimulatorInfo, assertXcodeVersion, MIN_SUPPORTED_XCODE_VERSION } from './utils'; +import * as xcode from 'appium-xcode'; import { log } from './logger'; -const MIN_SUPPORTED_XCODE_VERSION = 10; - -/** - * @template {import('appium-xcode').XcodeVersion} V - * @param {V} xcodeVersion - * @returns {V} - */ -function handleUnsupportedXcode (xcodeVersion) { - if (xcodeVersion.major < MIN_SUPPORTED_XCODE_VERSION) { - throw new Error( - `Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` + - `${MIN_SUPPORTED_XCODE_VERSION} and up are supported` - ); - } - return xcodeVersion; -} - /** * Finds and returns the corresponding Simulator instance for the given ID. * @@ -42,7 +25,7 @@ export async function getSimulator (udid, opts = {}) { logger, } = opts; - const xcodeVersion = handleUnsupportedXcode( + const xcodeVersion = assertXcodeVersion( /** @type {import('appium-xcode').XcodeVersion} */ (await xcode.getVersion(true)) ); if (checkExistence) { diff --git a/lib/utils.js b/lib/utils.js index e36f46a3..309abdbe 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -import log from './logger'; +import { log } from './logger'; import _ from 'lodash'; import { exec } from 'teen_process'; import { waitForCondition } from 'asyncbox'; @@ -10,6 +10,7 @@ const DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS = 30000; export const SAFARI_STARTUP_TIMEOUT_MS = 25 * 1000; export const MOBILE_SAFARI_BUNDLE_ID = 'com.apple.mobilesafari'; export const SIMULATOR_APP_NAME = 'Simulator.app'; +export const MIN_SUPPORTED_XCODE_VERSION = 10; /** * @param {string} appName @@ -53,7 +54,7 @@ export async function killAllSimulators (timeout = DEFAULT_SIM_SHUTDOWN_TIMEOUT_ try { await exec('xcrun', ['simctl', 'shutdown', xcodeVersion.major > 8 ? 'all' : 'booted'], {timeout}); - } catch (ign) {} + } catch {} const pids = []; try { @@ -74,13 +75,13 @@ export async function killAllSimulators (timeout = DEFAULT_SIM_SHUTDOWN_TIMEOUT_ log.debug(`Killing processes: ${pids.join(', ')}`); try { await exec('kill', ['-9', ...(pids.map((pid) => `${pid}`))]); - } catch (ign) {} + } catch {} } log.debug(`Using pkill to kill application: ${appName}`); try { await pkill(appName, true); - } catch (ign) {} + } catch {} // wait for all the devices to be shutdown before Continuing // but only print out the failed ones when they are actually fully failed @@ -145,3 +146,18 @@ export async function getDeveloperRoot () { const {stdout} = await exec('xcode-select', ['-p']); return stdout.trim(); } + +/** + * @template {import('appium-xcode').XcodeVersion} V + * @param {V} xcodeVersion + * @returns {V} + */ +export function assertXcodeVersion (xcodeVersion) { + if (xcodeVersion.major < MIN_SUPPORTED_XCODE_VERSION) { + throw new Error( + `Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` + + `${MIN_SUPPORTED_XCODE_VERSION} and up are supported` + ); + } + return xcodeVersion; +} diff --git a/package.json b/package.json index 9807e64f..8cc0c82c 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "singleQuote": true }, "devDependencies": { - "@appium/eslint-config-appium-ts": "^0.x", + "@appium/eslint-config-appium-ts": "^1.x", "@appium/tsconfig": "^0.x", "@appium/types": "^0.x", "@colors/colors": "^1.5.0", diff --git a/test/functional/simulator-e2e-specs.js b/test/functional/simulator-e2e-specs.js index 2fd26563..86924a7d 100644 --- a/test/functional/simulator-e2e-specs.js +++ b/test/functional/simulator-e2e-specs.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import { killAllSimulators, MOBILE_SAFARI_BUNDLE_ID } from '../../lib/utils'; import { getSimulator } from '../../lib/simulator'; -import Simctl from 'node-simctl'; +import { Simctl } from 'node-simctl'; import B from 'bluebird'; import { retryInterval, waitForCondition } from 'asyncbox'; import path from 'path'; diff --git a/test/functional/utils-e2e-specs.js b/test/functional/utils-e2e-specs.js index 11d658c2..08695a3c 100644 --- a/test/functional/utils-e2e-specs.js +++ b/test/functional/utils-e2e-specs.js @@ -1,7 +1,7 @@ // transpile:mocha import { killAllSimulators } from '../../lib/utils'; import { getSimulator } from '../../lib/simulator'; -import Simctl from 'node-simctl'; +import { Simctl } from 'node-simctl'; import { LONG_TIMEOUT, verifyStates } from './helpers'; const OS_VERSION = process.env.MOBILE_OS_VERSION || '14.0'; @@ -35,7 +35,7 @@ describe('killAllSimulators', function () { await killAllSimulators(); try { await sim.simctl.deleteDevice(); - } catch (ign) {} + } catch {} }); it('should be able to kill the simulators', async function () { await verifyStates(sim, true, true); diff --git a/test/unit/simulator-specs.js b/test/unit/simulator-specs.js index 64fcf4b4..4fa349f1 100644 --- a/test/unit/simulator-specs.js +++ b/test/unit/simulator-specs.js @@ -1,10 +1,10 @@ import { getSimulator } from '../../lib/simulator'; import * as teenProcess from 'teen_process'; import * as deviceUtils from '../../lib/device-utils'; +import * as utils from '../../lib/utils'; import sinon from 'sinon'; import { devices } from '../assets/deviceList'; import B from 'bluebird'; -import xcode from 'appium-xcode'; import { SimulatorXcode10 } from '../../lib/simulator-xcode-10'; import { SimulatorXcode11 } from '../../lib/simulator-xcode-11'; import { SimulatorXcode11_4 } from '../../lib/simulator-xcode-11.4'; @@ -12,7 +12,7 @@ import { SimulatorXcode11_4 } from '../../lib/simulator-xcode-11.4'; const UDID = devices['10.0'][0].udid; describe('simulator', function () { - let xcodeMock; + let assertXcodeVersionStub; let getDevicesStub; let chai; @@ -25,19 +25,19 @@ describe('simulator', function () { }); beforeEach(function () { - xcodeMock = sinon.mock(xcode); + assertXcodeVersionStub = sinon.stub(utils, 'assertXcodeVersion'); getDevicesStub = sinon.stub(deviceUtils, 'getDevices'); getDevicesStub.returns(B.resolve(devices)); }); afterEach(function () { - xcodeMock.restore(); + assertXcodeVersionStub.restore(); getDevicesStub.restore(); }); describe('getSimulator', function () { it('should create a simulator with default xcode version', async function () { let xcodeVersion = {major: 10, versionString: '10.0.0'}; - xcodeMock.expects('getVersion').returns(B.resolve(xcodeVersion)); + assertXcodeVersionStub.callsFake(() => xcodeVersion); let sim = await getSimulator(UDID); sim.xcodeVersion.should.equal(xcodeVersion); @@ -52,18 +52,17 @@ describe('simulator', function () { for (const [major, minor, versionString, expectedXcodeClass] of xcodeVersions) { it(`should create an xcode ${major} simulator with xcode version ${versionString}`, async function () { - let xcodeVersion = {major, minor, versionString}; - xcodeMock.expects('getVersion').returns(B.resolve(xcodeVersion)); - let sim = await getSimulator(UDID); + const xcodeVersion = {major, minor, versionString}; + assertXcodeVersionStub.callsFake(() => xcodeVersion); + const sim = await getSimulator(UDID); sim.xcodeVersion.should.equal(xcodeVersion); sim.constructor.name.should.be.eql(expectedXcodeClass.name); }); } - it('should throw an error if xcode version less than 6', async function () { - let xcodeVersion = {major: 5, versionString: '5.4.0'}; - xcodeMock.expects('getVersion').returns(B.resolve(xcodeVersion)); - await getSimulator(UDID).should.eventually.be.rejectedWith('version'); + it('should throw an error if xcode version does not match', async function () { + assertXcodeVersionStub.throws(); + await getSimulator(UDID).should.eventually.be.rejected; }); it('should throw an error if udid does not exist', async function () { @@ -72,7 +71,7 @@ describe('simulator', function () { it('should list stats for sim', async function () { let xcodeVersion = {major: 10, versionString: '10.0.0'}; - xcodeMock.expects('getVersion').atLeast(1).returns(B.resolve(xcodeVersion)); + assertXcodeVersionStub.callsFake(() => xcodeVersion); const sims = (await B.all([ 'F33783B2-9EE9-4A99-866E-E126ADBAD410', @@ -114,7 +113,7 @@ launchd_s 35621 mwakizaka 16u unix 0x7b7dbedd6d62e84f 0t0 /private/ beforeEach(function () { sinon.stub(teenProcess, 'exec').callsFake(() => ({ stdout })); const xcodeVersion = {major: 10, versionString: '10.0.0'}; - xcodeMock.expects('getVersion').atLeast(1).returns(B.resolve(xcodeVersion)); + assertXcodeVersionStub.callsFake(() => xcodeVersion); }); afterEach(function () { teenProcess.exec.restore(); @@ -146,7 +145,7 @@ launchd_s 35621 mwakizaka 16u unix 0x7b7dbedd6d62e84f 0t0 /private/ let spawnProcessSpy; beforeEach(async function () { const xcodeVersion = {major: 10, versionString: '10.0.0'}; - xcodeMock.expects('getVersion').atLeast(1).returns(B.resolve(xcodeVersion)); + assertXcodeVersionStub.callsFake(() => xcodeVersion); sim = await getSimulator(UDID); spawnProcessSpy = sinon.stub(sim.simctl, 'spawnProcess'); }); diff --git a/test/unit/utils-specs.js b/test/unit/utils-specs.js index dc03c5e3..ec33747e 100644 --- a/test/unit/utils-specs.js +++ b/test/unit/utils-specs.js @@ -84,7 +84,7 @@ describe('util', function () { try { await killAllSimulators(500); - } catch (e) {} + } catch {} execStub.callCount.should.equal(3); }); });