Skip to content

Commit 5993a04

Browse files
feat: Switch babel to typescript (#61)
1 parent 5fcb35a commit 5993a04

8 files changed

+100
-59
lines changed

.eslintrc.json

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
{
2-
"extends": "@appium/eslint-config-appium",
2+
"extends": ["@appium/eslint-config-appium-ts"],
33
"overrides": [
44
{
55
"files": "test/**/*.js",
66
"rules": {
7-
"func-names": "off"
7+
"func-names": "off",
8+
"@typescript-eslint/no-var-requires": "off"
9+
}
10+
},
11+
{
12+
"files": "scripts/**/*",
13+
"parserOptions": {"sourceType": "script"},
14+
"rules": {
15+
"@typescript-eslint/no-var-requires": "off"
816
}
917
}
10-
]
18+
],
19+
"rules": {
20+
"require-await": "error"
21+
}
1122
}

.mocharc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module.exports = {
2-
require: ['@babel/register'],
2+
require: ['ts-node/register'],
33
forbidOnly: Boolean(process.env.CI)
44
};

babel.config.json

-25
This file was deleted.

lib/driver.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { desiredCapConstraints } from './desired-caps';
55
import commands from './commands/index';
66
import { formatCapsForServer } from './utils';
77

8+
/** @type {import('@appium/types').RouteMatcher[]} */
89
const NO_PROXY = [
910
['GET', new RegExp('^/session/[^/]+/appium')],
1011
['POST', new RegExp('^/session/[^/]+/appium')],
@@ -13,7 +14,11 @@ const NO_PROXY = [
1314
];
1415

1516
class GeckoDriver extends BaseDriver {
17+
/** @type {boolean} */
18+
isProxyActive;
19+
1620
constructor (opts = {}) {
21+
// @ts-ignore TODO: make args typed
1722
super(opts);
1823
this.desiredCapConstraints = desiredCapConstraints;
1924
this.locatorStrategies = [
@@ -51,7 +56,9 @@ class GeckoDriver extends BaseDriver {
5156
return true;
5257
}
5358

59+
// @ts-ignore TODO: make args typed
5460
async createSession (...args) {
61+
// @ts-ignore TODO: make args typed
5562
const [sessionId, caps] = await super.createSession(...args);
5663
this.gecko = new GeckoDriverServer(this.log, caps);
5764
try {
@@ -60,14 +67,14 @@ class GeckoDriver extends BaseDriver {
6067
await this.deleteSession();
6168
throw e;
6269
}
63-
this.proxyReqRes = this.gecko.proxy.proxyReqRes.bind(this.gecko.proxy);
70+
this.proxyReqRes = this.gecko.proxy?.proxyReqRes.bind(this.gecko.proxy);
6471
this.isProxyActive = true;
6572
return [sessionId, caps];
6673
}
6774

6875
async deleteSession () {
6976
this.log.info('Ending Gecko Driver session');
70-
await this.gecko.stop();
77+
await this.gecko?.stop();
7178
this.resetState();
7279

7380
await super.deleteSession();

lib/gecko.js

+33-11
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const PROCESS_SPECIFIC_OPTION_NAMES_MAP = Object.freeze({
2727

2828

2929
class GeckoProxy extends JWProxy {
30+
/** @type {boolean|undefined} */
31+
didProcessExit;
32+
3033
async proxyCommand (url, method, body = null) {
3134
if (this.didProcessExit) {
3235
throw new errors.InvalidContextError(
@@ -38,6 +41,21 @@ class GeckoProxy extends JWProxy {
3841
}
3942

4043
class GeckoDriverProcess {
44+
/** @type {boolean|undefined} */
45+
noReset;
46+
47+
/** @type {string|undefined} */
48+
verbosity;
49+
50+
/** @type {string|undefined} */
51+
androidStorage;
52+
53+
/** @type {number|undefined} */
54+
marionettePort;
55+
56+
/** @type {number|undefined} */
57+
port;
58+
4159
constructor (log, opts = {}) {
4260
for (const [optName, propName] of _.toPairs(PROCESS_SPECIFIC_OPTION_NAMES_MAP)) {
4361
this[propName] = opts[optName];
@@ -76,6 +94,7 @@ class GeckoDriverProcess {
7694
throw new Error(`${GD_BINARY} binary cannot be found in PATH. ` +
7795
`Please make sure it is present on your system`);
7896
}
97+
/** @type {string[]} */
7998
const args = [];
8099
/* #region Options */
81100
switch (_.toLower(this.verbosity)) {
@@ -93,13 +112,13 @@ class GeckoDriverProcess {
93112
this.log.info(`'marionettePort' capability value is not provided while 'noReset' is enabled`);
94113
this.log.info(`Assigning 'marionettePort' to the default value (${DEFAULT_MARIONETTE_PORT})`);
95114
}
96-
args.push('--marionette-port', this.marionettePort ?? DEFAULT_MARIONETTE_PORT);
115+
args.push('--marionette-port', `${this.marionettePort ?? DEFAULT_MARIONETTE_PORT}`);
97116
} else if (!_.isNil(this.marionettePort)) {
98-
args.push('--marionette-port', this.marionettePort);
117+
args.push('--marionette-port', `${this.marionettePort}`);
99118
}
100119
/* #endregion */
101120

102-
args.push('-p', this.port);
121+
args.push('-p', `${this.port}`);
103122
if (this.androidStorage) {
104123
args.push('--android-storage', this.androidStorage);
105124
}
@@ -119,14 +138,14 @@ class GeckoDriverProcess {
119138

120139
async stop () {
121140
if (this.isRunning) {
122-
await this.proc.stop('SIGTERM');
141+
await this.proc?.stop('SIGTERM');
123142
}
124143
}
125144

126145
async kill () {
127146
if (this.isRunning) {
128147
try {
129-
await this.proc.stop('SIGKILL');
148+
await this.proc?.stop('SIGKILL');
130149
} catch (ign) {}
131150
}
132151
}
@@ -168,17 +187,19 @@ class GeckoDriverServer {
168187
keepAlive: true,
169188
});
170189
this.proxy.didProcessExit = false;
171-
this.process.proc.on('exit', () => {
172-
this.proxy.didProcessExit = true;
190+
this.process?.proc?.on('exit', () => {
191+
if (this.proxy) {
192+
this.proxy.didProcessExit = true;
193+
}
173194
});
174195

175196
try {
176197
await waitForCondition(async () => {
177198
try {
178-
await this.proxy.command('/status', 'GET');
199+
await this.proxy?.command('/status', 'GET');
179200
return true;
180201
} catch (err) {
181-
if (this.proxy.didProcessExit) {
202+
if (this.proxy?.didProcessExit) {
182203
throw new Error(err.message);
183204
}
184205
return false;
@@ -198,10 +219,11 @@ class GeckoDriverServer {
198219
}
199220
throw e;
200221
}
201-
const pid = this.process.proc.pid;
222+
const pid = this.process.proc?.pid;
202223
RUNNING_PROCESS_IDS.push(pid);
203-
this.process.proc.on('exit', () => void _.pull(RUNNING_PROCESS_IDS, pid));
224+
this.process.proc?.on('exit', () => void _.pull(RUNNING_PROCESS_IDS, pid));
204225

226+
// @ts-ignore The body is ok
205227
await this.proxy.command('/session', 'POST', {
206228
capabilities: {
207229
firstMatch: [{}],

package.json

+26-15
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
"appium": "^2.0.0-beta.40"
5252
},
5353
"dependencies": {
54-
"@babel/runtime": "^7.0.0",
5554
"asyncbox": "^2.0.2",
5655
"bluebird": "^3.5.1",
5756
"lodash": "^4.17.4",
@@ -60,7 +59,9 @@
6059
"teen_process": "^2.0.0"
6160
},
6261
"scripts": {
63-
"build": "rimraf build && babel --out-dir=build/lib lib && babel --out-dir=build index.js",
62+
"build": "tsc -b",
63+
"clean": "npm run build -- --clean",
64+
"rebuild": "npm run clean; npm run build",
6465
"dev": "npm run build -- --watch",
6566
"lint": "eslint .",
6667
"lint:fix": "npm run lint -- --fix",
@@ -75,30 +76,40 @@
7576
"precommit-lint"
7677
],
7778
"devDependencies": {
78-
"@appium/eslint-config-appium": "^6.0.0",
79-
"@babel/cli": "^7.18.10",
80-
"@babel/core": "^7.18.10",
81-
"@babel/eslint-parser": "^7.18.9",
82-
"@babel/plugin-transform-runtime": "^7.18.10",
83-
"@babel/preset-env": "^7.18.10",
84-
"@babel/register": "^7.18.9",
79+
"@appium/eslint-config-appium": "^8.0.4",
80+
"@appium/eslint-config-appium-ts": "^0.3.1",
81+
"@appium/tsconfig": "^0.3.0",
82+
"@appium/types": "^0.13.2",
8583
"@semantic-release/changelog": "^6.0.1",
8684
"@semantic-release/git": "^10.0.1",
87-
"babel-plugin-source-map-support": "^2.2.0",
85+
"@types/bluebird": "^3.5.38",
86+
"@types/chai": "^4.3.5",
87+
"@types/chai-as-promised": "^7.1.5",
88+
"@types/lodash": "^4.14.196",
89+
"@types/mocha": "^10.0.1",
90+
"@types/node": "^20.4.7",
91+
"@types/sinon": "^10.0.16",
92+
"@types/sinon-chai": "^3.2.9",
93+
"@types/teen_process": "2.0.0",
94+
"@typescript-eslint/eslint-plugin": "^5.62.0",
95+
"@typescript-eslint/parser": "^5.62.0",
8896
"chai": "^4.1.2",
8997
"chai-as-promised": "^7.1.1",
9098
"conventional-changelog-conventionalcommits": "^6.0.0",
91-
"eslint": "^7.32.0",
92-
"eslint-config-prettier": "^8.5.0",
93-
"eslint-plugin-import": "^2.25.3",
94-
"eslint-plugin-mocha": "^9.0.0",
95-
"eslint-plugin-promise": "^6.0.0",
99+
"eslint": "^8.46.0",
100+
"eslint-config-prettier": "^8.9.0",
101+
"eslint-import-resolver-typescript": "^3.5.5",
102+
"eslint-plugin-import": "^2.28.0",
103+
"eslint-plugin-mocha": "^10.1.0",
104+
"eslint-plugin-promise": "^6.1.1",
96105
"lint-staged": "^14.0.0",
97106
"mocha": "^10.0.0",
98107
"pre-commit": "^1.1.3",
99108
"rimraf": "^5.0.0",
100109
"semantic-release": "^20.0.2",
101110
"sinon": "^15.0.0",
111+
"ts-node": "^10.9.1",
112+
"typescript": "^5.1.6",
102113
"webdriverio": "^8.0.5"
103114
}
104115
}

test/functional/desktop-driver-e2e-specs.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const CAPS = {
1515
describe('Desktop Gecko Driver', function () {
1616
this.timeout(MOCHA_TIMEOUT);
1717

18+
/** @type {import('webdriverio').Browser} */
1819
let driver;
1920
beforeEach(async function () {
2021
driver = await remote({
@@ -32,8 +33,8 @@ describe('Desktop Gecko Driver', function () {
3233

3334
it('should start and stop a session', async function () {
3435
await driver.url('https://appium.io/');
35-
const button = await driver.$('#downloadLink');
36-
await button.getText().should.eventually.eql('Download Appium');
36+
const input = await driver.$('input[data-md-component="search-query"]');
37+
(await input.isExisting()).should.be.true;
3738
});
3839
});
3940

tsconfig.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "https://json.schemastore.org/tsconfig",
3+
"extends": "@appium/tsconfig/tsconfig.json",
4+
"compilerOptions": {
5+
"strict": false, // TODO: make this flag true
6+
"outDir": "build",
7+
"types": ["node"],
8+
"checkJs": true
9+
},
10+
"include": [
11+
"index.js",
12+
"lib"
13+
]
14+
}

0 commit comments

Comments
 (0)