Skip to content

Commit 3e9cde8

Browse files
authored
chore(cli): remove yargs typings (#34)
- Do not use yargs typings until DefinitelyTyped/DefinitelyTyped#28061 is resolved. - Created e2e test to updates, checks status, starts server, and removes files. - Expose seleniumProcess from the SeleniumServer class. - Moved SIGINT event to start handler method. This will let a user stop the selenium sever with the process pid and without existing their JavaScript process. closes #24
1 parent 8972ad2 commit 3e9cde8

16 files changed

+582
-287
lines changed

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ jobs:
33
build:
44
working_directory: ~/workspace
55
docker:
6-
- image: circleci/node:8
6+
- image: circleci/node:8-browsers
77
steps:
88
- checkout
9-
9+
1010
- run: node --version
1111
- run: npm --version
1212

1313
- run: npm install
1414
- run: npm run test-unit
1515
- run: npm run test-int
1616
- run: npm run test-proxy
17-
17+
- run: npm run test-e2e

lib/cli/index.ts

Lines changed: 118 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,119 @@
1-
import * as yargs from 'yargs';
2-
import * as clean from '../cmds/clean';
3-
import * as start from '../cmds/start';
4-
import * as status from '../cmds/status';
5-
import * as update from '../cmds/update';
6-
7-
const chrome = {
8-
describe: 'Install or update chromedriver.',
9-
default: true
10-
};
11-
const gecko = {
12-
describe: 'Install or update geckodriver.',
13-
default: true
14-
};
15-
const ie = {
16-
describe: 'Install or update ie driver.',
17-
default: false
18-
};
19-
const ignoreSSL = {
20-
describe: 'Ignore SSL certificates.'
21-
}
22-
const outDir = {
23-
describe: 'Location of output.',
24-
default: 'downloads'
25-
};
26-
const proxy = {
27-
describe: 'Use a proxy server to download files.'
28-
};
29-
const standalone = {
30-
describe: 'Install or update selenium server standalone.',
31-
default: true
32-
};
33-
const versionsChrome = {
34-
describe: 'The chromedriver version.'
35-
};
36-
const versionsGecko = {
37-
describe: 'The geckodriver version.',
38-
};
39-
const versionsIe = {
40-
describe: 'The ie driver version.'
41-
};
42-
const versionsStandalone = {
43-
describe: 'The selenium server standalone version.'
44-
};
45-
46-
yargs
47-
.command('clean', 'Removes downloaded files from the out_dir', {
48-
'out_dir': outDir
49-
}, (argv: yargs.Arguments) => {
50-
clean.handler(argv);
51-
})
52-
.command('start', 'Start up the selenium server.', {
53-
'chrome': chrome,
54-
'gecko': gecko,
55-
'ie': ie,
56-
'out_dir': outDir,
57-
'standalone': standalone,
58-
'versions_chrome': versionsChrome,
59-
'versions_gecko': versionsGecko,
60-
'versions_ie': versionsIe,
61-
'versions_standalone': versionsStandalone,
62-
}, (argv: yargs.Arguments) => {
63-
start.handler(argv);
64-
})
65-
.command('status', 'List the current available binaries.', {
66-
'out_dir': outDir
67-
}, (argv: yargs.Arguments) => {
68-
status.handler(argv);
69-
})
70-
.command('update', 'Install or update selected binaries.', {
71-
'chrome': chrome,
72-
'gecko': gecko,
73-
'ie': ie,
74-
'ignore_ssl': ignoreSSL,
75-
'out_dir': outDir,
76-
'proxy': proxy,
77-
'standalone': standalone,
78-
'versions.chrome': versionsChrome,
79-
'versions.gecko': versionsGecko,
80-
'versions.ie': versionsIe,
81-
'versions.standalone': versionsStandalone,
82-
}, (argv: yargs.Arguments) => {
83-
update.handler(argv);
84-
})
85-
.help()
1+
import * as clean from '../cmds/clean';
2+
import * as start from '../cmds/start';
3+
import * as status from '../cmds/status';
4+
import * as update from '../cmds/update';
5+
6+
// Not using yargs type definitions due to:
7+
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/28061#issuecomment-412365576
8+
// Although the fix is to cast all my objects into a yargs.Options
9+
// objects, the error is not obvious to debug if an error occurs.
10+
const yargs = require('yargs');
11+
12+
const CHROME = 'chrome';
13+
const chromeOption = {
14+
describe: 'Install or update chromedriver.',
15+
default: true,
16+
type: 'boolean'
17+
};
18+
const GECKO = 'gecko';
19+
const geckoOption = {
20+
describe: 'Install or update geckodriver.',
21+
default: true,
22+
type: 'boolean'
23+
};
24+
const IEDRIVER = 'iedriver';
25+
const ieOption = {
26+
describe: 'Install or update ie driver.',
27+
default: false,
28+
type: 'boolean'
29+
};
30+
const IGNORE_SSL = 'ignore_ssl';
31+
const ignoreSSLOption = {
32+
describe: 'Ignore SSL certificates.',
33+
type: 'boolean'
34+
};
35+
const OUT_DIR = 'out_dir';
36+
let outDirOption = {
37+
describe: 'Location of output.',
38+
default: 'downloads',
39+
type: 'string'
40+
};
41+
const PROXY = 'proxy';
42+
const proxyOption = {
43+
describe: 'Use a proxy server to download files.',
44+
type: 'string'
45+
};
46+
const STANDALONE = 'standalone';
47+
const standaloneOption = {
48+
describe: 'Install or update selenium server standalone.',
49+
default: true,
50+
type: 'boolean'
51+
};
52+
const VERSIONS_CHROME = 'versions.chrome';
53+
const versionsChromeOption = {
54+
describe: 'The chromedriver version.',
55+
type: 'string'
56+
};
57+
const VERSIONS_GECKO = 'versions.gecko';
58+
const versionsGeckoOption = {
59+
describe: 'The geckodriver version.',
60+
type: 'string'
61+
};
62+
const VERSIONS_IE = 'versions.ie';
63+
const versionsIeOption = {
64+
describe: 'The ie driver version.',
65+
type: 'string'
66+
};
67+
const VERSIONS_STANDALONE = 'versions.standalone';
68+
const versionsStandaloneOption = {
69+
describe: 'The selenium server standalone version.',
70+
type: 'string'
71+
};
72+
73+
yargs
74+
.command('clean', 'Removes downloaded files from the out_dir.',
75+
(yargs: any) => {
76+
return yargs.option(OUT_DIR, outDirOption)
77+
}, (argv: any) => {
78+
clean.handler(argv);
79+
})
80+
.command('start', 'Start up the selenium server.',
81+
(yargs: any) => {
82+
return yargs
83+
.option(CHROME, chromeOption)
84+
.option(GECKO, geckoOption)
85+
.option(IEDRIVER, ieOption)
86+
.option(OUT_DIR, outDirOption)
87+
.option(STANDALONE, standaloneOption)
88+
.option(VERSIONS_CHROME, versionsChromeOption)
89+
.option(VERSIONS_GECKO, versionsGeckoOption)
90+
.option(VERSIONS_IE, versionsIeOption)
91+
.option(VERSIONS_STANDALONE, versionsStandaloneOption);
92+
}, (argv: any) => {
93+
start.handler(argv);
94+
})
95+
.command('status', 'List the current available binaries.',
96+
(yargs: any) => {
97+
return yargs.option(OUT_DIR, outDirOption)
98+
}, (argv: any) => {
99+
status.handler(argv);
100+
})
101+
.command('update', 'Install or update selected binaries.',
102+
(yargs: any) => {
103+
return yargs.option(OUT_DIR, outDirOption)
104+
.option(CHROME, chromeOption)
105+
.option(GECKO, geckoOption)
106+
.option(IEDRIVER, ieOption)
107+
.option(IGNORE_SSL, ignoreSSLOption)
108+
.option(OUT_DIR, outDirOption)
109+
.option(PROXY, proxyOption)
110+
.option(STANDALONE, standaloneOption)
111+
.option(VERSIONS_CHROME, versionsChromeOption)
112+
.option(VERSIONS_GECKO, versionsGeckoOption)
113+
.option(VERSIONS_IE, versionsIeOption)
114+
.option(VERSIONS_STANDALONE, versionsStandaloneOption);
115+
}, (argv: any) => {
116+
update.handler(argv);
117+
})
118+
.help()
86119
.argv;

lib/cmds/clean.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
1-
import * as yargs from 'yargs';
2-
import { Options } from './options';
3-
import { constructAllProviders } from './utils';
4-
5-
export function handler(argv: yargs.Arguments) {
6-
let options = constructAllProviders(argv);
7-
console.log(clean(options));
8-
}
9-
10-
export function clean(options: Options): string {
11-
let filesCleaned: string[] = [];
12-
for (let provider of options.providers) {
13-
let cleanedFiles = provider.binary.cleanFiles();
14-
if (cleanedFiles) {
15-
filesCleaned.push(cleanedFiles);
16-
}
17-
}
18-
filesCleaned.push(options.server.binary.cleanFiles());
19-
return (filesCleaned.sort()).join();
20-
}
1+
import { Options } from './options';
2+
import { constructAllProviders } from './utils';
3+
4+
/**
5+
* Handles removing files that were downloaded and logs the files.
6+
* @param argv The argv from yargs.
7+
*/
8+
export function handler(argv: any) {
9+
let options = constructAllProviders(argv);
10+
console.log(clean(options));
11+
}
12+
13+
/**
14+
* Goes through all the providers and removes the downloaded files.
15+
* @param options The constructed options.
16+
* @returns A list of deleted files.
17+
*/
18+
export function clean(options: Options): string {
19+
let filesCleaned: string[] = [];
20+
for (let provider of options.providers) {
21+
let cleanedFiles = provider.binary.cleanFiles();
22+
if (cleanedFiles) {
23+
filesCleaned.push(cleanedFiles);
24+
}
25+
}
26+
if (options.server && options.server.binary) {
27+
filesCleaned.push(options.server.binary.cleanFiles());
28+
}
29+
return (filesCleaned.sort()).join('\n');
30+
}

lib/cmds/cmds.spec-e2e.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import * as fs from 'fs';
2+
import * as os from 'os';
3+
import * as path from 'path';
4+
import * as rimraf from 'rimraf';
5+
import {
6+
constructAllProviders,
7+
constructProviders,
8+
} from './utils';
9+
import { update } from './update';
10+
import { status } from './status';
11+
import { start } from './start';
12+
import { clean } from './clean';
13+
import { SeleniumServer } from '../provider/selenium_server';
14+
import { resolve } from 'url';
15+
16+
describe('using the cli', () => {
17+
let tmpDir = path.resolve(os.tmpdir(), 'test');
18+
let origTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
19+
20+
beforeAll(() => {
21+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
22+
try {
23+
fs.mkdirSync(tmpDir);
24+
} catch (err) {}
25+
});
26+
27+
afterAll(() => {
28+
jasmine.DEFAULT_TIMEOUT_INTERVAL = origTimeout;
29+
try {
30+
rimraf.sync(tmpDir);
31+
} catch (err) {}
32+
});
33+
34+
describe('a user runs update', () => {
35+
it('should download the files', async() => {
36+
let argv = {
37+
_: ['foobar'],
38+
chrome: true,
39+
standalone: true,
40+
out_dir: tmpDir,
41+
'$0': 'bin\\webdriver-manager'
42+
};
43+
let options = constructProviders(argv);
44+
await update(options);
45+
const existFiles = fs.readdirSync(tmpDir);
46+
expect(existFiles.length).toBe(7);
47+
});
48+
});
49+
50+
describe('a user runs status', () => {
51+
it('should get the list of versions', () => {
52+
let argv = {
53+
_: ['foobar'],
54+
out_dir: tmpDir,
55+
'$0': 'bin\\webdriver-manager'
56+
};
57+
let options = constructAllProviders(argv);
58+
let statusLog = status(options);
59+
console.log(statusLog);
60+
let lines = statusLog.split('\n');
61+
expect(lines.length).toBe(2);
62+
});
63+
});
64+
65+
describe('a user runs start', () => {
66+
it ('should start the selenium server standalone', async() => {
67+
let argv = {
68+
_: ['foobar'],
69+
chrome: true,
70+
standalone: true,
71+
out_dir: tmpDir,
72+
'$0': 'bin\\webdriver-manager'
73+
};
74+
let options = constructProviders(argv);
75+
// Do not await this promise to start the server since the promise is
76+
// never resolved by waiting, it is either killed by pid or get request.
77+
let startProcess = start(options);
78+
79+
// Arbitrarily wait for the server to start.
80+
await new Promise((resolve, _) => {
81+
setTimeout(resolve, 3000);
82+
});
83+
let seleniumServer = (options.server.binary as SeleniumServer);
84+
expect(seleniumServer.seleniumProcess).toBeTruthy();
85+
expect(seleniumServer.seleniumProcess.pid).toBeTruthy();
86+
87+
// Stop the server using the get request.
88+
await seleniumServer.stopServer();
89+
90+
// Check to see that the exit code is 0.
91+
expect(await startProcess).toBe(0);
92+
});
93+
});
94+
95+
describe('a user runs clean', () => {
96+
it('should remove the files', () => {
97+
let argv = {
98+
_: ['foobar'],
99+
out_dir: tmpDir,
100+
'$0': 'bin\\webdriver-manager'
101+
};
102+
let options = constructAllProviders(argv);
103+
let cleanLogs = clean(options);
104+
console.log(cleanLogs);
105+
let lines = cleanLogs.split('\n');
106+
expect(lines.length).toBe(7);
107+
const existFiles = fs.readdirSync(tmpDir);
108+
expect(existFiles.length).toBe(0);
109+
});
110+
});
111+
});

0 commit comments

Comments
 (0)