Skip to content

Commit e2c7d2b

Browse files
authored
chore(chromium): add chromium to cli and lib (#400)
Most of these methods do not work with Windows and there still needs to have some tests against the chromium.ts file. - provide hooks when used in cli and as a node module - fix update to only have one version of chromium - add methods to get the binary file from the chromium.config.json - add clean and status methods
1 parent af02414 commit e2c7d2b

File tree

7 files changed

+141
-8
lines changed

7 files changed

+141
-8
lines changed

lib/cli/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ const chromedriverLogsOption: yargs.Options = {
1818
describe: 'File path to chrome logs.',
1919
type: 'string'
2020
};
21+
const CHROMIUM = 'chromium';
22+
const chromiumOptions: yargs.Options = {
23+
describe: 'Download chromium.',
24+
default: false,
25+
type: 'boolean'
26+
};
2127
const DETACH = 'detach';
2228
const detachOption: yargs.Options = {
2329
describe: 'Once the selenium server is up and running, return ' +
@@ -68,6 +74,11 @@ const maxVersionsChromedriverOption: yargs.Options = {
6874
describe: 'The chromedriver max version used only for update.',
6975
type: 'string'
7076
};
77+
const MAX_VERSIONS_CHROMIUM = 'max_versions.chromium';
78+
const maxVersionsChromiumOptions: yargs.Options = {
79+
describe: 'The chromium max version used only for update.',
80+
type: 'string'
81+
};
7182
const MAX_VERSIONS_GECKODRIVER_ALIAS = 'max_versions.gecko';
7283
const MAX_VERSIONS_GECKODRIVER = 'max_versions.geckodriver';
7384
const maxVersionsGeckodriverOption: yargs.Options = {
@@ -214,6 +225,7 @@ yargs
214225
return yargs.option(OUT_DIR, outDirOption)
215226
.option(CHROMEDRIVER, chromedriverOption)
216227
.alias(CHROMEDRIVER_ALIAS, CHROMEDRIVER)
228+
.option(CHROMIUM, chromiumOptions)
217229
.option(GECKODRIVER, geckodriverOption)
218230
.alias(GECKODRIVER_ALIAS, GECKODRIVER)
219231
.option(GITHUB_TOKEN, githubTokenOption)
@@ -223,11 +235,13 @@ yargs
223235
.option(LOG_LEVEL, logLevelOption)
224236
.option(MAX_VERSIONS_CHROMEDRIVER, maxVersionsChromedriverOption)
225237
.alias(MAX_VERSIONS_CHROMEDRIVER_ALIAS, MAX_VERSIONS_CHROMEDRIVER)
238+
.option(MAX_VERSIONS_CHROMIUM, maxVersionsChromiumOptions)
226239
.option(MAX_VERSIONS_GECKODRIVER, maxVersionsGeckodriverOption)
227240
.alias(MAX_VERSIONS_GECKODRIVER_ALIAS, MAX_VERSIONS_GECKODRIVER)
228241
.option(MAX_VERSIONS_IEDRIVER, maxVersionsIedriverOption)
229242
.alias(MAX_VERSIONS_IEDRIVER_ALIAS, MAX_VERSIONS_IEDRIVER)
230243
.option(MAX_VERSIONS_SELENIUM, maxVersionsSeleniumOption)
244+
.alias(MAX_VERSIONS_SELENIUM_ALIAS, MAX_VERSIONS_SELENIUM)
231245
.option(OUT_DIR, outDirOption)
232246
.option(PROXY, proxyOption)
233247
.option(SELENIUM, seleniumOption)

lib/cmds/options.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export interface Options {
1616
githubToken?: string;
1717
}
1818

19-
export type BrowserDriverName = 'chromedriver'|'geckodriver'|'iedriver';
19+
export type BrowserDriverName =
20+
'chromedriver'|'geckodriver'|'iedriver'|'chromium';
2021

2122
/**
2223
* Contains information about a browser driver.

lib/cmds/utils.spec-unit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('utils', () => {
1313
};
1414
const options = convertArgs2AllOptions(argv);
1515
expect(options.browserDrivers).toBeTruthy();
16-
expect(options.browserDrivers.length).toBe(3);
16+
expect(options.browserDrivers.length).toBe(4);
1717
expect(options.server).toBeTruthy();
1818
expect(options.server.name).toBe('selenium');
1919
expect(options.outDir).toBe('foobar_download');

lib/cmds/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {SeleniumServer, SeleniumServerProviderConfig} from '../provider/selenium
77

88
import {BrowserDriver, BrowserDriverName, Options} from './options';
99
import {OptionsBinary} from './options_binary';
10+
import { Chromium } from '../provider/chromium';
1011

1112
/**
1213
* Converts an options object into an options binary object.
@@ -27,6 +28,8 @@ export function addOptionsBinary(options: Options): OptionsBinary {
2728
for (const browserDriver of optionsBinary.browserDrivers) {
2829
if (browserDriver.name === 'chromedriver') {
2930
browserDriver.binary = new ChromeDriver(providerConfig);
31+
} else if (browserDriver.name === 'chromium') {
32+
browserDriver.binary = new Chromium(providerConfig);
3033
} else if (browserDriver.name === 'geckodriver') {
3134
const geckoProviderConfig = providerConfig;
3235
geckoProviderConfig.oauthToken = optionsBinary.githubToken;
@@ -57,6 +60,7 @@ export function convertArgs2AllOptions(argv: yargs.Arguments): Options {
5760
return {
5861
browserDrivers: [
5962
{name: 'chromedriver'},
63+
{name: 'chromium'},
6064
{name: 'geckodriver'},
6165
{name: 'iedriver'}
6266
],
@@ -83,6 +87,9 @@ export function convertArgs2Options(argv: yargs.Arguments): Options {
8387
if (argv['chromedriver'] as boolean) {
8488
setVersions('chromedriver', argv, options.browserDrivers);
8589
}
90+
if (argv['chromium'] as boolean) {
91+
setVersions('chromium', argv, options.browserDrivers);
92+
}
8693
if (argv['geckodriver'] as boolean) {
8794
setVersions('geckodriver', argv, options.browserDrivers);
8895
}

lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export {start} from './cmds/start';
1313
export {status} from './cmds/status';
1414
export {update} from './cmds/update';
1515
export {ChromeDriver} from './provider/chromedriver';
16+
export {Chromium} from './provider/chromium';
1617
export {GeckoDriver} from './provider/geckodriver';
1718
export {IEDriver} from './provider/iedriver';
1819
export {ProviderConfig, ProviderInterface} from './provider/provider';

lib/provider/chromium.ts

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import * as childProcess from 'child_process';
12
import * as fs from 'fs';
23
import * as os from 'os';
34
import * as path from 'path';
45
import * as semver from 'semver';
6+
57
import { requestBody, JsonObject, requestBinary } from './utils/http_utils';
6-
import { getBinaryPathFromConfig, removeFiles, unzipFile } from './utils/file_utils';
8+
import { changeFilePermissions, generateConfigFile, getBinaryPathFromConfig, removeFiles, unzipFile } from './utils/file_utils';
79
import { isExpired } from './utils/file_utils';
810
import { OUT_DIR, ProviderClass, ProviderConfig, ProviderInterface } from './provider';
11+
import rimraf = require('rimraf');
912

1013
export class Chromium extends ProviderClass implements ProviderInterface {
1114
cacheFileName = 'chromium-all.json';
@@ -18,6 +21,7 @@ export class Chromium extends ProviderClass implements ProviderInterface {
1821
osArch = os.arch();
1922
outDir = OUT_DIR;
2023
proxy: string = null;
24+
maxVersion: string = null;
2125

2226
constructor(config?: ProviderConfig) {
2327
super();
@@ -28,6 +32,7 @@ export class Chromium extends ProviderClass implements ProviderInterface {
2832
this.osType = this.setVar('osType', this.osType, config);
2933
this.outDir = this.setVar('outDir', this.outDir, config);
3034
this.proxy = this.setVar('proxy', this.proxy, config);
35+
this.maxVersion = this.setVar('maxVersion', this.maxVersion, config);
3136
}
3237

3338
private makeDirectory(fileName: string) {
@@ -223,16 +228,69 @@ export class Chromium extends ProviderClass implements ProviderInterface {
223228
}
224229
}
225230
}
226-
unzipFile(fileName, this.outDir);
231+
232+
if (this.osType === 'Linux') {
233+
unzipFile(fileName, this.outDir);
234+
changeFilePermissions(
235+
path.resolve(this.outDir, 'chrome-linux/chrome'), '0755', this.osType);
236+
} else if (this.osType === 'Darwin') {
237+
spawnProcess('unzip', [fileName, '-d', this.outDir], 'ignore');
238+
} else if (this.osType === 'Windows_NT') {
239+
unzipFile(fileName, this.outDir);
240+
}
227241
}
228242

229-
async updateBinary(majorVersion?: string): Promise<void> {
243+
async updateBinary(_: string, majorVersion?: string): Promise<void> {
244+
try {
245+
this.cleanFiles();
246+
} catch (_) {
247+
// no-op: best attempt to clean files, there can be only one version.
248+
}
230249
const allJson = await this.downloadAllJson();
231250
const downloadVersionJson = await this.downloadVersionJson(
232251
allJson, majorVersion);
233252
const storageObject = await this.downloadStorageObject(
234253
downloadVersionJson, majorVersion);
235254
await this.downloadUrl(storageObject, majorVersion);
255+
256+
let binaryFolder = (): string => {
257+
if (this.osType === 'Linux') {
258+
return path.resolve(this.outDir, 'chrome-linux');
259+
} else if (this.osType === 'Darwin') {
260+
return path.resolve(this.outDir,
261+
'chrome-mac/Chromium.app/Contents/MacOS');
262+
} else if (this.osType === 'Windows_NT') {
263+
return 'fix me';
264+
}
265+
throw new Error('os does not exist');
266+
}
267+
268+
let binaryRegex = (): RegExp => {
269+
if (this.osType === 'Linux') {
270+
return /chrome$/g;
271+
} else if (this.osType === 'Darwin') {
272+
return /Chromium/g;
273+
} else if (this.osType === 'Windows_NT') {
274+
return /fix-me/g;
275+
}
276+
throw new Error('os does not exist');
277+
};
278+
279+
let binaryFile = (): string => {
280+
if (this.osType === 'Linux') {
281+
return path.resolve(this.outDir, 'chrome-linux/chrome');
282+
} else if (this.osType === 'Darwin') {
283+
return path.resolve(this.outDir,
284+
'chrome-mac/Chromium.app/Contents/MacOS/Chromium');
285+
} else if (this.osType === 'Windows_NT') {
286+
return 'fix me';
287+
}
288+
throw new Error('os does not exist');
289+
}
290+
291+
generateConfigFile(binaryFolder(),
292+
path.resolve(this.outDir, this.configFileName),
293+
binaryRegex(), binaryFile());
236294
}
237295

238296
getBinaryPath(version?: string): string | null {
@@ -245,11 +303,47 @@ export class Chromium extends ProviderClass implements ProviderInterface {
245303
}
246304

247305
getStatus(): string | null {
248-
return '';
306+
try {
307+
const existFiles = fs.readdirSync(this.outDir);
308+
for (const existFile of existFiles) {
309+
if (existFile.match(/chromium\-version\.*/g)) {
310+
const regex = /chromium\-version\-(\d+)\.json/g;
311+
const exec = regex.exec(existFile);
312+
if (exec) {
313+
return exec[1];
314+
}
315+
}
316+
}
317+
return null;
318+
} catch (_) {
319+
return null;
320+
}
249321
}
250322

251323
cleanFiles(): string {
252-
return removeFiles(this.outDir, [/chromium.*/g]);
324+
let chromiumPath= '';
325+
if (this.osType === 'Darwin') {
326+
chromiumPath = 'chrome-mac/';
327+
} else if (this.osType === 'Linux') {
328+
chromiumPath = 'chrome-linux/';
329+
} else if (this.osType === 'Windows_NT') {
330+
chromiumPath = 'chrome-win/';
331+
}
332+
333+
rimraf.sync(path.resolve(this.outDir, chromiumPath));
334+
const files = removeFiles(this.outDir, [/chromium.*/g]);
335+
try {
336+
const fileList = files.split('\n');
337+
if (files.length === 0) {
338+
// No files listed to clean.
339+
return '';
340+
}
341+
fileList.push(chromiumPath);
342+
return (fileList.sort()).join('\n');
343+
} catch (_) {
344+
// If files returns null, catch split error.
345+
return '';
346+
}
253347
}
254348
}
255349

@@ -275,4 +369,21 @@ export function osHelper(ostype: string, osarch: string): string {
275369
}
276370
}
277371
return null;
372+
}
373+
374+
/**
375+
* A command line to run. Example 'npm start', the task='npm' and the
376+
* opt_arg=['start']
377+
* @param task The task string.
378+
* @param optArg Optional task args.
379+
* @param optIo Optional io arg. By default, it should log to console.
380+
* @returns The child process.
381+
*/
382+
export function spawnProcess(task: string, optArg?: string[], optIo?: string) {
383+
optArg = typeof optArg !== 'undefined' ? optArg : [];
384+
let stdio: childProcess.StdioOptions = 'inherit';
385+
if (optIo === 'ignore') {
386+
stdio = 'ignore';
387+
}
388+
return childProcess.spawnSync(task, optArg, {stdio});
278389
}

lib/provider/utils/file_utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ export function unzipFile(zipFileName: string, dstDir: string): string[] {
105105
const zip = new AdmZip(zipFileName);
106106
zip.extractAllTo(dstDir, true);
107107
for (const fileItem of zipFileList(zipFileName)) {
108-
console.log(fileItem);
109108
fileList.push(path.resolve(dstDir, fileItem));
110109
}
111110
return fileList;

0 commit comments

Comments
 (0)