Skip to content

Commit

Permalink
feat: Switch babel to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach committed Aug 23, 2023
1 parent ee7655e commit 2c5501e
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 72 deletions.
17 changes: 14 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
{
"extends": "@appium/eslint-config-appium",
"extends": ["@appium/eslint-config-appium-ts"],
"overrides": [
{
"files": "test/**/*.js",
"rules": {
"func-names": "off"
"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"
}
}
7 changes: 7 additions & 0 deletions .github/workflows/functional-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,12 @@ jobs:
npm install
mkdir -p ./Resources/WebDriverAgent.bundle
name: Install dev dependencies
- run: |
target_sim_id=$(xcrun simctl list devices available | grep "$DEVICE_NAME (" | cut -d "(" -f2 | cut -d ")" -f1)
open -Fn "$(xcode-select -p)/Applications/Simulator.app"
xcrun simctl bootstatus $target_sim_id -b
name: Preboot Simulator
- run: npm run e2e-test
name: Run functional tests
2 changes: 1 addition & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
require: ['@babel/register'],
require: ['ts-node/register'],
forbidOnly: Boolean(process.env.CI)
};
25 changes: 0 additions & 25 deletions babel.config.json

This file was deleted.

4 changes: 2 additions & 2 deletions lib/check-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function checkForDependencies () {

async function bundleWDASim (xcodebuild, opts = {}) {
if (xcodebuild && !_.isFunction(xcodebuild.retrieveDerivedDataPath)) {
xcodebuild = new XcodeBuild();
xcodebuild = new XcodeBuild('', {});
opts = xcodebuild;

Check warning on line 33 in lib/check-dependencies.js

View workflow job for this annotation

GitHub Actions / test (16)

'opts' is assigned a value but never used

Check warning on line 33 in lib/check-dependencies.js

View workflow job for this annotation

GitHub Actions / test (18)

'opts' is assigned a value but never used
}

Expand All @@ -38,7 +38,7 @@ async function bundleWDASim (xcodebuild, opts = {}) {
if (await fs.exists(wdaBundlePath)) {
return wdaBundlePath;
}
await buildWDASim(xcodebuild, opts);
await buildWDASim();
return wdaBundlePath;
}

Expand Down
17 changes: 10 additions & 7 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ CODE_SIGN_IDENTITY = ${signingId}
* @param {DeviceInfo} deviceInfo
* @param {string} sdkVersion - The Xcode SDK version of OS.
* @param {string} bootstrapPath - The folder path containing xctestrun file.
* @param {string} wdaRemotePort - The remote port WDA is listening on.
* @return {string} returns xctestrunFilePath for given device
* @param {number|string} wdaRemotePort - The remote port WDA is listening on.
* @return {Promise<string>} returns xctestrunFilePath for given device
* @throws if WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device
* or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath,
* then it will throw file not found exception
Expand All @@ -207,7 +207,7 @@ async function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemot
/**
* Return the WDA object which appends existing xctest runner content
* @param {string} platformName - The name of the platform
* @param {string} version - The Xcode SDK version of OS.
* @param {number|string} wdaRemotePort - The remote port number
* @return {object} returns a runner object which has USE_PORT
*/
function getAdditionalRunContent (platformName, wdaRemotePort) {
Expand All @@ -228,6 +228,7 @@ function getAdditionalRunContent (platformName, wdaRemotePort) {
* @param {DeviceInfo} deviceInfo
* @param {string} sdkVersion - The Xcode SDK version of OS.
* @param {string} bootstrapPath - The folder path containing xctestrun file.
* @returns {Promise<string>}
*/
async function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) {
// First try the SDK path, for Xcode 10 (at least)
Expand Down Expand Up @@ -256,9 +257,11 @@ async function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) {
}
}

log.errorAndThrow(`If you are using 'useXctestrunFile' capability then you ` +
throw new Error(
`If you are using 'useXctestrunFile' capability then you ` +
`need to have a xctestrun file (expected: ` +
`'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`);
`'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`
);
}


Expand Down Expand Up @@ -316,7 +319,7 @@ function randomInt (low, high) {
/**
* Retrieves WDA upgrade timestamp
*
* @return {?number} The UNIX timestamp of the package manifest. The manifest only gets modified on
* @return {Promise<number?>} The UNIX timestamp of the package manifest. The manifest only gets modified on
* package upgrade.
*/
async function getWDAUpgradeTimestamp () {
Expand Down Expand Up @@ -356,7 +359,7 @@ async function resetTestProcesses (udid, isSimulator) {
* listening on given port, and is expected to return
* either true or false to include/exclude the corresponding PID
* from the resulting array.
* @returns {Array<string>} - the list of matched process ids.
* @returns {Promise<string[]>} - the list of matched process ids.
*/
async function getPIDsListeningOnPort (port, filteringFunc = null) {
const result = [];
Expand Down
23 changes: 14 additions & 9 deletions lib/webdriveragent.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class WebDriverAgent {

/**
* Return boolean if WDA is running or not
* @return {boolean} True if WDA is running
* @return {Promise<boolean>} True if WDA is running
* @throws {Error} If there was invalid response code or body
*/
async isRunning () {
Expand Down Expand Up @@ -183,7 +183,7 @@ class WebDriverAgent {
* }
* }
*
* @return {?object} State Object
* @return {Promise<any?>} State Object
* @throws {Error} If there was invalid response code or body
*/
async getStatus () {
Expand Down Expand Up @@ -234,7 +234,7 @@ class WebDriverAgent {
const box = strongbox(packageInfo.name);
let boxItem = box.getItem(RECENT_MODULE_VERSION_ITEM_NAME);
if (!boxItem) {
const timestampPath = path.resolve(process.env.HOME, WDA_UPGRADE_TIMESTAMP_PATH);
const timestampPath = path.resolve(process.env.HOME ?? '', WDA_UPGRADE_TIMESTAMP_PATH);
if (await fs.exists(timestampPath)) {
// TODO: It is probably a bit ugly to hardcode the recent version string,
// TODO: hovewer it should do the job as a temporary transition trick
Expand Down Expand Up @@ -279,6 +279,7 @@ class WebDriverAgent {
`(${recentModuleVersion} < ${packageInfo.version})`
);
try {
// @ts-ignore xcodebuild should be set
await this.xcodebuild.cleanProject();
await boxItem.write(packageInfo.version);
} catch (e) {
Expand All @@ -289,7 +290,7 @@ class WebDriverAgent {
/**
* Launch WDA with preinstalled package without xcodebuild.
* @param {string} sessionId Launch WDA and establish the session with this sessionId
* @return {?object} State Object
* @return {Promise<any?>} State Object
*/
async launchWithPreinstalledWDA(sessionId) {
const xctestEnv = {
Expand Down Expand Up @@ -330,7 +331,7 @@ class WebDriverAgent {
* }
*
* @param {string} sessionId Launch WDA and establish the session with this sessionId
* @return {?object} State Object
* @return {Promise<any?>} State Object
* @throws {Error} If there was invalid response code or body
*/
async launch (sessionId) {
Expand Down Expand Up @@ -374,12 +375,15 @@ class WebDriverAgent {
return await this.startWithIDB();
}

// @ts-ignore xcodebuild should be set
await this.xcodebuild.init(this.noSessionProxy);

// Start the xcodebuild process
if (this.prebuildWDA) {
// @ts-ignore xcodebuild should be set
await this.xcodebuild.prebuild();
}
// @ts-ignore xcodebuild should be set
return await this.xcodebuild.start();
}

Expand Down Expand Up @@ -463,7 +467,9 @@ class WebDriverAgent {
}
} else if (!this.args.webDriverAgentUrl) {
this.log.info('Shutting down sub-processes');
// @ts-ignore xcodebuild should be set
await this.xcodebuild.quit();
// @ts-ignore xcodebuild should be set
await this.xcodebuild.reset();
} else {
this.log.debug('Do not stop xcodebuild nor XCTest session ' +
Expand Down Expand Up @@ -504,23 +510,22 @@ class WebDriverAgent {
return this.started;
}

set fullyStarted (started = false) {
this.started = started;
set fullyStarted (started) {
this.started = started ?? false;
}

async retrieveDerivedDataPath () {
if (this.canSkipXcodebuild) {
return;
}
// @ts-ignore xcodebuild should be set
return await this.xcodebuild.retrieveDerivedDataPath();
}

/**
* Reuse running WDA if it has the same bundle id with updatedWDABundleId.
* Or reuse it if it has the default id without updatedWDABundleId.
* Uninstall it if the method faces an exception for the above situation.
*
* @param {string} updatedWDABundleId BundleId you'd like to use
*/
async setupCaching () {
const status = await this.getStatus();
Expand Down
40 changes: 33 additions & 7 deletions lib/xcodebuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import _ from 'lodash';
import path from 'path';
import { EOL } from 'os';
import { WDA_RUNNER_BUNDLE_ID } from './constants';
import readline from 'node:readline';


const DEFAULT_SIGNING_ID = 'iPhone Developer';
Expand All @@ -33,6 +34,12 @@ const xcodeLog = logger.getLogger('Xcode');


class XcodeBuild {
/**
* @param {string} xcodeVersion
* @param {any} device
* @param {any} args
* @param {import('@appium/types').AppiumLogger?} log
*/
constructor (xcodeVersion, device, args = {}, log = null) {
this.xcodeVersion = xcodeVersion;

Expand Down Expand Up @@ -201,7 +208,7 @@ class XcodeBuild {
args.push('-resultBundleVersion', this.resultBundleVersion);
}

if (this.useXctestrunFile) {
if (this.useXctestrunFile && this.xctestrunFilePath) {
args.push('-xctestrun', this.xctestrunFilePath);
} else {
const runnerScheme = isTvOS(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS;
Expand Down Expand Up @@ -252,6 +259,7 @@ class XcodeBuild {
const {cmd, args} = this.getCommand(buildOnly);
this.log.debug(`Beginning ${buildOnly ? 'build' : 'test'} with command '${cmd} ${args.join(' ')}' ` +
`in directory '${this.bootstrapPath}'`);
/** @type {Record<string, any>} */
const env = Object.assign({}, process.env, {
USE_PORT: this.wdaRemotePort,
WDA_PRODUCT_BUNDLE_IDENTIFIER: this.updatedWDABundleId || WDA_RUNNER_BUNDLE_ID,
Expand All @@ -260,7 +268,7 @@ class XcodeBuild {
// https://github.com/appium/WebDriverAgent/pull/105
env.MJPEG_SERVER_PORT = this.mjpegServerPort;
}
const upgradeTimestamp = await getWDAUpgradeTimestamp(this.bootstrapPath);
const upgradeTimestamp = await getWDAUpgradeTimestamp();
if (upgradeTimestamp) {
env.UPGRADE_TIMESTAMP = upgradeTimestamp;
}
Expand All @@ -283,7 +291,9 @@ class XcodeBuild {
if (out.includes('Writing diagnostic log for test session to')) {
// pull out the first line that begins with the path separator
// which *should* be the line indicating the log file generated
// @ts-ignore logLocation is a custom property
xcodebuild.logLocation = _.first(_.remove(out.trim().split('\n'), (v) => v.startsWith(path.sep)));
// @ts-ignore logLocation is a custom property
xcodeLog.debug(`Log file for xcodebuild test: ${xcodebuild.logLocation}`);
}

Expand All @@ -295,6 +305,7 @@ class XcodeBuild {
logXcodeOutput = true;

// terrible hack to handle case where xcode return 0 but is failing
// @ts-ignore _wda_error_occurred is a custom property
xcodebuild._wda_error_occurred = true;
}

Expand All @@ -303,6 +314,7 @@ class XcodeBuild {
for (const line of out.split(EOL)) {
xcodeLog.error(line);
if (line) {
// @ts-ignore _wda_error_message is a custom property
xcodebuild._wda_error_message += `${EOL}${line}`;
}
}
Expand All @@ -315,28 +327,39 @@ class XcodeBuild {
async start (buildOnly = false) {
this.xcodebuild = await this.createSubProcess(buildOnly);
// Store xcodebuild message
// @ts-ignore _wda_error_message is a custom property
this.xcodebuild._wda_error_message = '';

// wrap the start procedure in a promise so that we can catch, and report,
// any startup errors that are thrown as events
return await new B((resolve, reject) => {
// @ts-ignore xcodebuild must be present here
this.xcodebuild.on('exit', async (code, signal) => {

Check failure on line 337 in lib/xcodebuild.js

View workflow job for this annotation

GitHub Actions / test (16)

Async arrow function has no 'await' expression

Check failure on line 337 in lib/xcodebuild.js

View workflow job for this annotation

GitHub Actions / test (18)

Async arrow function has no 'await' expression
xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`);
// print out the xcodebuild file if users have asked for it
if (this.showXcodeLog && this.xcodebuild.logLocation) {
// @ts-ignore logLocation is a custom property
if (this.showXcodeLog && this.xcodebuild?.logLocation) {
// @ts-ignore logLocation is a custom property
xcodeLog.error(`Contents of xcodebuild log file '${this.xcodebuild.logLocation}':`);
try {
let data = await fs.readFile(this.xcodebuild.logLocation, 'utf8');
for (let line of data.split('\n')) {
const logFile = readline.createInterface({
// @ts-ignore logLocation is a custom property
input: fs.createReadStream(this.xcodebuild.logLocation),
terminal: false
});
logFile.on('line', (line) => {
xcodeLog.error(line);
}
});
} catch (err) {
xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`);
}
}
// @ts-ignore processExited is a custom property
this.xcodebuild.processExited = true;
// @ts-ignore _wda_error_occurred is a custom property
if (this.xcodebuild._wda_error_occurred || (!signal && code !== 0)) {
return reject(new Error(`xcodebuild failed with code ${code}${EOL}` +
// @ts-ignore _wda_error_message is a custom property
`xcodebuild error message:${EOL}${this.xcodebuild._wda_error_message}`));
}
// in the case of just building, the process will exit and that is our finish
Expand All @@ -348,6 +371,7 @@ class XcodeBuild {
return (async () => {
try {
const timer = new timing.Timer().start();
// @ts-ignore this.xcodebuild must be defined
await this.xcodebuild.start(true);
if (!buildOnly) {
let status = await this.waitForStart(timer);
Expand All @@ -367,8 +391,9 @@ class XcodeBuild {
this.log.debug(`Waiting up to ${this.launchTimeout}ms for WebDriverAgent to start`);
let currentStatus = null;
try {
let retries = parseInt(this.launchTimeout / 500, 10);
let retries = parseInt(`${this.launchTimeout / 500}`, 10);
await retryInterval(retries, 1000, async () => {
// @ts-ignore processExited is a custom property
if (this.xcodebuild.processExited) {
// there has been an error elsewhere and we need to short-circuit
return;
Expand All @@ -389,6 +414,7 @@ class XcodeBuild {
}
});

// @ts-ignore processExited is a custom property
if (this.xcodebuild.processExited) {
// there has been an error elsewhere and we need to short-circuit
return currentStatus;
Expand Down
Loading

0 comments on commit 2c5501e

Please sign in to comment.