testem 3.19.0 → 3.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/testem.js CHANGED
@@ -1,76 +1,178 @@
1
1
  #!/usr/bin/env node
2
2
 
3
-
4
- const program = require('commander');
5
- let progOptions = program;
3
+ const { Command } = require('commander');
6
4
  const Config = require('./lib/config');
7
5
  const Api = require('./lib/api');
8
- let appMode = 'dev';
9
-
10
- program
11
- .version(require(__dirname + '/package').version)
12
- .usage('[options]')
13
- .option('-f, --file [file]', 'config file - defaults to testem.json or testem.yml')
14
- .option('-p, --port [num]', 'server port - defaults to 7357', Number)
15
- .option('--host [hostname]', 'host name - defaults to localhost', String)
16
- .option('-l, --launch [list]', 'list of launchers to launch(comma separated)')
17
- .option('-s, --skip [list]', 'list of launchers to skip(comma separated)')
18
- .option('-d, --debug [file]', 'output debug to debug log - defaults to testem.log')
19
- .option('-t, --test_page [page]', 'the html page to drive the tests')
20
- .option('-g, --growl', 'turn on growl / native notifications');
21
-
22
- program
23
- .command('launchers')
24
- .description('Print the list of available launchers (browsers & process launchers)')
25
- .action(act(env => {
26
- env.__proto__ = program;
27
- progOptions = env;
28
- appMode = 'launchers';
29
- }));
30
-
31
- program
32
- .command('ci')
33
- .description('Continuous integration mode')
34
- .option('-T, --timeout [sec]', 'timeout a browser after [sec] seconds', null)
35
- .option('-P, --parallel [num]', 'number of browsers to run in parallel, defaults to 1', Number)
36
- .option('-b, --bail_on_uncaught_error', 'Bail on any uncaught errors')
37
- .option('-R, --reporter [reporter]', 'Test reporter to use [tap|dot|xunit|teamcity]')
38
- .option('--cwd [path]', 'directory to use as root')
39
- .option('--config_dir [path]', 'directory to use as root for resolving configs, if different than cwd')
40
- .action(act(env => {
41
- env.__proto__ = program;
42
- progOptions = env;
43
- appMode = 'ci';
44
- }));
45
-
46
- program
47
- .command('server')
48
- .description('Run just the server')
49
- .action(act(env => {
50
- env.__proto__ = program;
51
- progOptions = env;
52
- appMode = 'server';
53
- }));
54
-
55
- program.on('--help', () => {
56
- console.log(' Keyboard Controls (in dev mode):\n');
57
- console.log(' ENTER run the tests');
58
- console.log(' q quit');
59
- console.log(' LEFT ARROW move to the next browser tab on the left');
60
- console.log(' RIGHT ARROW move to the next browser tab on the right');
61
- console.log(' TAB switch between top and bottom panel (split mode only)');
62
- console.log(' UP ARROW scroll up in the target text panel');
63
- console.log(' DOWN ARROW scroll down in the target text panel');
64
- console.log(' SPACE page down in the target text panel');
65
- console.log(' b page up in the target text panel');
66
- console.log(' d half a page down in the target text panel');
67
- console.log(' u half a page up in the target text panel');
68
- console.log();
69
- });
70
-
71
- main();
6
+
7
+ // this is to workaround the weird behavior in commander where
8
+ // if you provide additional command line arguments that aren't
9
+ // options, it goes in as a string as the 1st argument of the
10
+ // "action" callback, we don't want this
11
+ function act(fun) {
12
+ return function() {
13
+ let options = arguments[arguments.length - 1];
14
+ fun(options);
15
+ };
16
+ }
17
+
18
+ /**
19
+ * Build and parse a fresh Commander program from the given argv array.
20
+ * Returns { progOptions, appMode } where progOptions is a plain object
21
+ * containing all resolved option values (from program.opts() /
22
+ * optsWithGlobals()), so option values are directly accessible as
23
+ * properties rather than requiring access via a Command instance.
24
+ * A _commander reference is attached for internal option enumeration.
25
+ *
26
+ * @param {string[]} argv - process.argv-style array
27
+ * @param {{ exitOverride?: boolean }} [opts]
28
+ * exitOverride: when true, commander throws instead of calling process.exit
29
+ * (useful in tests to prevent the process from terminating)
30
+ */
31
+ function parseArgs(argv, { exitOverride = false } = {}) {
32
+ let progOptions = null;
33
+ let appMode = 'dev';
34
+
35
+ const program = new Command();
36
+
37
+ if (exitOverride) {
38
+ program.exitOverride();
39
+ }
40
+
41
+ program
42
+ .version(require(__dirname + '/package').version)
43
+ .usage('[options]')
44
+ .option(
45
+ '-f, --file [file]',
46
+ 'config file - defaults to testem.json or testem.yml',
47
+ )
48
+ .option('-p, --port [num]', 'server port - defaults to 7357', Number)
49
+ .option('--host [hostname]', 'host name - defaults to localhost', String)
50
+ .option(
51
+ '-l, --launch [list]',
52
+ 'list of launchers to launch(comma separated)',
53
+ )
54
+ .option('-s, --skip [list]', 'list of launchers to skip(comma separated)')
55
+ .option(
56
+ '-d, --debug [file]',
57
+ 'output debug to debug log - defaults to testem.log',
58
+ )
59
+ .option('-t, --test_page [page]', 'the html page to drive the tests')
60
+ .option('-g, --growl', 'turn on growl / native notifications')
61
+ // A root action is required in commander v7+ to prevent the program from
62
+ // automatically displaying help and exiting when no subcommand is given.
63
+ // Without it, running `testem` (dev mode) would show help instead of
64
+ // starting the dev server.
65
+ .action(() => {});
66
+
67
+ program
68
+ .command('launchers')
69
+ .description(
70
+ 'Print the list of available launchers (browsers & process launchers)',
71
+ )
72
+ .action(
73
+ act((env) => {
74
+ progOptions = env.optsWithGlobals();
75
+ progOptions._commander = env;
76
+ appMode = 'launchers';
77
+ }),
78
+ );
79
+
80
+ program
81
+ .command('ci')
82
+ .description('Continuous integration mode')
83
+ .option(
84
+ '-T, --timeout [sec]',
85
+ 'timeout a browser after [sec] seconds',
86
+ null,
87
+ )
88
+ .option(
89
+ '-P, --parallel [num]',
90
+ 'number of browsers to run in parallel, defaults to 1',
91
+ Number,
92
+ )
93
+ .option('-b, --bail_on_uncaught_error', 'Bail on any uncaught errors')
94
+ .option(
95
+ '-R, --reporter [reporter]',
96
+ 'Test reporter to use [tap|dot|xunit|teamcity]',
97
+ )
98
+ .option('--cwd [path]', 'directory to use as root')
99
+ .option(
100
+ '--config_dir [path]',
101
+ 'directory to use as root for resolving configs, if different than cwd',
102
+ )
103
+ .action(
104
+ act((env) => {
105
+ progOptions = env.optsWithGlobals();
106
+ progOptions._commander = env;
107
+ appMode = 'ci';
108
+ }),
109
+ );
110
+
111
+ program
112
+ .command('server')
113
+ .description('Run just the server')
114
+ .action(
115
+ act((env) => {
116
+ progOptions = env.optsWithGlobals();
117
+ progOptions._commander = env;
118
+ appMode = 'server';
119
+ }),
120
+ );
121
+
122
+ program.on('--help', () => {
123
+ console.log(' Keyboard Controls (in dev mode):\n');
124
+ console.log(' ENTER run the tests');
125
+ console.log(' q quit');
126
+ console.log(
127
+ ' LEFT ARROW move to the next browser tab on the left',
128
+ );
129
+ console.log(
130
+ ' RIGHT ARROW move to the next browser tab on the right',
131
+ );
132
+ console.log(
133
+ ' TAB switch between top and bottom panel (split mode only)',
134
+ );
135
+ console.log(
136
+ ' UP ARROW scroll up in the target text panel',
137
+ );
138
+ console.log(
139
+ ' DOWN ARROW scroll down in the target text panel',
140
+ );
141
+ console.log(
142
+ ' SPACE page down in the target text panel',
143
+ );
144
+ console.log(' b page up in the target text panel');
145
+ console.log(
146
+ ' d half a page down in the target text panel',
147
+ );
148
+ console.log(
149
+ ' u half a page up in the target text panel',
150
+ );
151
+ console.log();
152
+ });
153
+
154
+ program.parse(argv);
155
+
156
+ if (progOptions === null) {
157
+ // dev mode: no subcommand was invoked; use opts() so option values are
158
+ // plain properties rather than requiring access via the Command object
159
+ // (commander v14 no longer exposes options as direct Command properties)
160
+ const devOpts = program.opts();
161
+ devOpts._commander = program;
162
+ progOptions = devOpts;
163
+ }
164
+
165
+ return { progOptions, appMode };
166
+ }
167
+
168
+ module.exports = { parseArgs };
169
+
170
+ if (require.main === module) {
171
+ main();
172
+ }
173
+
72
174
  function main() {
73
- program.parse(process.argv);
175
+ const { progOptions, appMode } = parseArgs(process.argv);
74
176
 
75
177
  let config = new Config(appMode, progOptions);
76
178
  if (appMode === 'launchers') {
@@ -86,14 +188,3 @@ function main() {
86
188
  }
87
189
  }
88
190
  }
89
-
90
- // this is to workaround the weird behavior in command where
91
- // if you provide additional command line arguments that aren't
92
- // options, it goes in as a string as the 1st arguments of the
93
- // "action" callback, we don't want this
94
- function act(fun) {
95
- return function() {
96
- let options = arguments[arguments.length - 1];
97
- fun(options);
98
- };
99
- }