Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit ec93c4a

Browse files
authored
chore(cli): **breaking change** throw errors on unknown flags (#3921)
closes #3216
1 parent 45b8326 commit ec93c4a

File tree

2 files changed

+148
-40
lines changed

2 files changed

+148
-40
lines changed

lib/cli.ts

+142-40
Original file line numberDiff line numberDiff line change
@@ -31,46 +31,137 @@ process.argv.slice(2).forEach(function(arg: string) {
3131
}
3232
});
3333

34-
optimist
35-
.usage(
36-
'Usage: protractor [configFile] [options]\n' +
37-
'configFile defaults to protractor.conf.js\n' +
38-
'The [options] object will override values from the config file.\n' +
39-
'See the reference config for a full list of options.')
40-
.describe('help', 'Print Protractor help menu')
41-
.describe('version', 'Print Protractor version')
42-
.describe('browser', 'Browsername, e.g. chrome or firefox')
43-
.describe('seleniumAddress', 'A running selenium address to use')
44-
.describe('seleniumSessionId', 'Attaching an existing session id')
45-
.describe('seleniumServerJar', 'Location of the standalone selenium jar file')
46-
.describe('seleniumPort', 'Optional port for the selenium standalone server')
47-
.describe('baseUrl', 'URL to prepend to all relative paths')
48-
.describe('rootElement', 'Element housing ng-app, if not html or body')
49-
.describe('specs', 'Comma-separated list of files to test')
50-
.describe('exclude', 'Comma-separated list of files to exclude')
51-
.describe('verbose', 'Print full spec names')
52-
.describe('stackTrace', 'Print stack trace on error')
53-
.describe('params', 'Param object to be passed to the tests')
54-
.describe('framework', 'Test framework to use: jasmine, mocha, or custom')
55-
.describe('resultJsonOutputFile', 'Path to save JSON test result')
56-
.describe('troubleshoot', 'Turn on troubleshooting output')
57-
.describe('elementExplorer', 'Interactively test Protractor commands')
58-
.describe('debuggerServerPort', 'Start a debugger server at specified port instead of repl')
59-
.alias('browser', 'capabilities.browserName')
60-
.alias('name', 'capabilities.name')
61-
.alias('platform', 'capabilities.platform')
62-
.alias('platform-version', 'capabilities.version')
63-
.alias('tags', 'capabilities.tags')
64-
.alias('build', 'capabilities.build')
65-
.alias('grep', 'jasmineNodeOpts.grep')
66-
.alias('invert-grep', 'jasmineNodeOpts.invertGrep')
67-
.alias('explorer', 'elementExplorer')
68-
.string('capabilities.tunnel-identifier')
69-
.check(function(arg: any) {
70-
if (arg._.length > 1) {
71-
throw new Error('Error: more than one config file specified');
72-
}
73-
});
34+
// TODO(cnishina): Make cli checks better.
35+
let allowedNames = [
36+
'seleniumServerJar',
37+
'seleniumServerStartTimeout',
38+
'localSeleniumStandaloneOpts',
39+
'chromeDriver',
40+
'seleniumAddress',
41+
'seleniumSessionId',
42+
'webDriverProxy',
43+
'useBlockingProxy',
44+
'sauceUser',
45+
'sauceKey',
46+
'sauceAgent',
47+
'sauceBuild',
48+
'sauceSeleniumAddress',
49+
'browserstackUser',
50+
'browserstackKey',
51+
'directConnect',
52+
'firefoxPath',
53+
'noGlobals',
54+
'specs',
55+
'exclude',
56+
'suites',
57+
'suite',
58+
'capabilities',
59+
'multiCapabilities',
60+
'getMultiCapabilities',
61+
'maxSessions',
62+
'verboseMultiSessions',
63+
'baseUrl',
64+
'rootElement',
65+
'allScriptsTimeout',
66+
'getPageTimeout',
67+
'beforeLaunch',
68+
'onPrepare',
69+
'onComplete',
70+
'onCleanUp',
71+
'afterLaunch',
72+
'params',
73+
'resultJsonOutputFile',
74+
'restartBrowserBetweenTests',
75+
'untrackOutstandingTimeouts',
76+
'ignoreUncaughtExceptions',
77+
'framework',
78+
'jasmineNodeOpts',
79+
'mochaOpts',
80+
'plugins',
81+
'skipSourceMapSupport',
82+
'disableEnvironmentOverrides',
83+
'ng12Hybrid',
84+
'seleniumArgs',
85+
'jvmArgs',
86+
'configDir',
87+
'troubleshoot',
88+
'seleniumPort',
89+
'mockSelenium',
90+
'v8Debug',
91+
'nodeDebug',
92+
'debuggerServerPort',
93+
'useAllAngular2AppRoots',
94+
'frameworkPath',
95+
'elementExplorer',
96+
'debug',
97+
'disableChecks',
98+
'browser',
99+
'name',
100+
'platform',
101+
'platform-version',
102+
'tags',
103+
'build',
104+
'grep',
105+
'invert-grep',
106+
'explorer'
107+
];
108+
109+
let optimistOptions: any = {
110+
describes: {
111+
help: 'Print Protractor help menu',
112+
version: 'Print Protractor version',
113+
browser: 'Browsername, e.g. chrome or firefox',
114+
seleniumAddress: 'A running selenium address to use',
115+
seleniumSessionId: 'Attaching an existing session id',
116+
seleniumServerJar: 'Location of the standalone selenium jar file',
117+
seleniumPort: 'Optional port for the selenium standalone server',
118+
baseUrl: 'URL to prepend to all relative paths',
119+
rootElement: 'Element housing ng-app, if not html or body',
120+
specs: 'Comma-separated list of files to test',
121+
exclude: 'Comma-separated list of files to exclude',
122+
verbose: 'Print full spec names',
123+
stackTrace: 'Print stack trace on error',
124+
params: 'Param object to be passed to the tests',
125+
framework: 'Test framework to use: jasmine, mocha, or custom',
126+
resultJsonOutputFile: 'Path to save JSON test result',
127+
troubleshoot: 'Turn on troubleshooting output',
128+
elementExplorer: 'Interactively test Protractor commands',
129+
debuggerServerPort: 'Start a debugger server at specified port instead of repl',
130+
disableChecks: 'disable cli checks'
131+
},
132+
aliases: {
133+
browser: 'capabilities.browserName',
134+
name: 'capabilities.name',
135+
platform: 'capabilities.platform',
136+
'platform-version': 'capabilities.version',
137+
tags: 'capabilities.tags',
138+
build: 'capabilities.build',
139+
grep: 'jasmineNodeOpts.grep',
140+
'invert-grep': 'jasmineNodeOpts.invertGrep',
141+
explorer: 'elementExplorer'
142+
},
143+
strings: {'capabilities.tunnel-identifier': ''}
144+
};
145+
146+
optimist.usage(
147+
'Usage: protractor [configFile] [options]\n' +
148+
'configFile defaults to protractor.conf.js\n' +
149+
'The [options] object will override values from the config file.\n' +
150+
'See the reference config for a full list of options.');
151+
for (let key of Object.keys(optimistOptions.describes)) {
152+
optimist.describe(key, optimistOptions.describes[key]);
153+
}
154+
for (let key of Object.keys(optimistOptions.aliases)) {
155+
optimist.alias(key, optimistOptions.aliases[key]);
156+
}
157+
for (let key of Object.keys(optimistOptions.strings)) {
158+
optimist.string(key);
159+
}
160+
optimist.check(function(arg: any) {
161+
if (arg._.length > 1) {
162+
throw new Error('Error: more than one config file specified');
163+
}
164+
});
74165

75166
let argv: any = optimist.parse(args);
76167

@@ -84,6 +175,17 @@ if (argv.version) {
84175
process.exit(0);
85176
}
86177

178+
if (!argv.disableChecks) {
179+
// Check to see if additional flags were used.
180+
let unknownKeys: string[] = Object.keys(argv).filter((element: string) => {
181+
return element !== '$0' && element !== '_' && allowedNames.indexOf(element) === -1;
182+
});
183+
184+
if (unknownKeys.length > 0) {
185+
throw new Error('Found extra flags: ' + unknownKeys.join(', '));
186+
}
187+
}
188+
87189
/**
88190
* Helper to resolve comma separated lists of file pattern strings relative to
89191
* the cwd.

scripts/errorTest.js

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ var checkLogs = function(output, messages) {
1919
*Below are exit failure tests*
2020
******************************/
2121

22+
runProtractor = spawn('node',
23+
['bin/protractor', 'example/conf.js', '--foobar', 'foobar']);
24+
output = runProtractor.stderr.toString();
25+
messages = ['Error: Found extra flags: foobar'];
26+
checkLogs(output, messages);
27+
2228
// assert authentication error for sauce labs
2329
runProtractor = spawn('node',
2430
['bin/protractor', 'spec/errorTest/sauceLabsAuthentication.js']);

0 commit comments

Comments
 (0)