@testrevolution/bugbug-cli 12.35.0 → 13.5.3

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/.env CHANGED
@@ -1 +1 @@
1
- SENTRY_DSN=https://33fb182a5d1a45f783ee5362a20f219a@o346063.ingest.sentry.io/6360873
1
+ SENTRY_DSN=https://c850ce209b19d8558600d0ecbb5a160f@sentry.bugbug.io/52
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@testrevolution/bugbug-cli",
3
3
  "description": "BugBug CLI",
4
- "version": "12.35.0",
4
+ "version": "13.5.3",
5
5
  "keywords": [
6
6
  "automation",
7
7
  "cli",
@@ -19,16 +19,17 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@sentry/node": "^10.5.0",
22
- "axios": "^1.10.0",
23
- "console-table-printer": "^2.12.1",
24
- "dotenv": "^16.4.7",
22
+ "axios": "^1.13.4",
23
+ "chalk": "^4.1.2",
24
+ "console-table-printer": "^2.15.0",
25
+ "dotenv": "^17.2.3",
25
26
  "jest-junit": "^16.0.0",
26
27
  "junit-xml": "^1.2.0",
27
28
  "minimist": "^1.2.8",
28
- "nanoid": "^3.3.4",
29
+ "nanoid": "^3.3.11",
29
30
  "ora": "^5.4.1",
30
31
  "path": "^0.12.7",
31
- "validator": "^13.15.0"
32
+ "validator": "^13.15.26"
32
33
  },
33
34
  "scripts": {
34
35
  "start": "cross-env NODE_ENV=development node ./bin/bugbug",
@@ -49,9 +50,9 @@
49
50
  "eslint": "^8.57.1",
50
51
  "eslint-config-airbnb-base": "^15.0.0",
51
52
  "eslint-plugin-import": "^2.32.0",
52
- "eslint-plugin-jest": "^29.0.1",
53
+ "eslint-plugin-jest": "^29.12.2",
53
54
  "eslint-plugin-node": "^11.1.0",
54
- "jest": "^30.0.3"
55
+ "jest": "^30.2.0"
55
56
  },
56
57
  "author": "TestRevolution sp. z o.o."
57
58
  }
@@ -1,5 +1,8 @@
1
1
  const axios = require('axios');
2
2
  const fs = require('fs');
3
+ const chalk = require('chalk');
4
+
5
+ chalk.level = 0;
3
6
 
4
7
  const { join } = require('path');
5
8
  const {
@@ -38,7 +41,7 @@ describe('commands module', () => {
38
41
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
39
42
  await helpCommand(args);
40
43
  expect(consoleLogSpy).toHaveBeenCalled();
41
- expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('bugbug [command] <options>'));
44
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('bugbug <command> [options]'));
42
45
  });
43
46
 
44
47
  it('should console log config help menu', async () => {
@@ -48,7 +51,7 @@ describe('commands module', () => {
48
51
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
49
52
  await helpCommand(args);
50
53
  expect(consoleLogSpy).toHaveBeenCalled();
51
- expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('bugbug config <options>'));
54
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('config <command>'));
52
55
  });
53
56
 
54
57
  it('should console log remote help menu', async () => {
@@ -58,7 +61,7 @@ describe('commands module', () => {
58
61
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
59
62
  await helpCommand(args);
60
63
  expect(consoleLogSpy).toHaveBeenCalled();
61
- expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('bugbug remote <options>'));
64
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('remote <command> [options]'));
62
65
  });
63
66
  });
64
67
 
@@ -299,7 +302,10 @@ describe('commands module', () => {
299
302
  variable: ['var=val', 'var2=val2'],
300
303
  };
301
304
  await remoteCommand(args);
302
- expect(runFunMock).toHaveBeenCalledWith(id, undefined, [{ key: 'var', value: 'val' }, { key: 'var2', value: 'val2' }], {
305
+ expect(runFunMock).toHaveBeenCalledWith(id, undefined, [{ key: 'var', value: 'val' }, {
306
+ key: 'var2',
307
+ value: 'val2',
308
+ }], {
303
309
  noprogress: true,
304
310
  nowait: false,
305
311
  withDetails: false,
@@ -423,7 +429,10 @@ describe('commands module', () => {
423
429
  variable: ['var=val', 'var2=val2'],
424
430
  };
425
431
  await remoteCommand(args);
426
- expect(runFunMock).toHaveBeenCalledWith(id, undefined, [{ key: 'var', value: 'val' }, { key: 'var2', value: 'val2' }], {
432
+ expect(runFunMock).toHaveBeenCalledWith(id, undefined, [{ key: 'var', value: 'val' }, {
433
+ key: 'var2',
434
+ value: 'val2',
435
+ }], {
427
436
  noprogress: true,
428
437
  nowait: false,
429
438
  withDetails: false,
@@ -816,7 +825,7 @@ describe('commands module', () => {
816
825
  test_id: id, profile_name: undefined, variables: [], triggeredBy: 'cli',
817
826
 
818
827
  },
819
- params: { },
828
+ params: {},
820
829
  headers: { Authorization: `Token ${configValue.token}`, 'User-Agent': settings.USER_AGENT },
821
830
  });
822
831
  expect(axios).toHaveBeenNthCalledWith(2, {
@@ -27,7 +27,7 @@ const validateArgs = async (args) => {
27
27
  help({ _: ['config'] });
28
28
  return false;
29
29
  }
30
- const knownKeys = ['_'];
30
+ const knownKeys = ['_', 'color', 'no-color'];
31
31
  const unknownKeys = await getUnknownOptions(args, knownKeys);
32
32
  if (unknownKeys.length > 0) {
33
33
  console.error(`Unknown options: ${unknownKeys.join(', ')}`);
@@ -43,6 +43,10 @@ module.exports = async (args) => {
43
43
  }
44
44
  const { subCmd, token } = await parseArgs(args);
45
45
  switch (subCmd) {
46
+ case settings.ACTION_HELP:
47
+ help({ _: ['config'] });
48
+ exitCode = await getExitCode(true);
49
+ break;
46
50
  case settings.ACTION_SET_TOKEN:
47
51
  exitCode = await setToken(token);
48
52
  break;
@@ -1,40 +1,58 @@
1
+ const chalk = require('chalk');
1
2
  const settings = require('../settings');
2
3
 
3
4
  const help = {
4
5
  main: `
5
- bugbug [command] <options>
6
+ ${chalk.bold('Usage:')}
7
+ ${chalk.green('bugbug')} <command> [options]
6
8
 
7
- config ................
8
- remote ................
9
- version ...............
10
- help <config|remote>... show help menu for a command`,
9
+ ${chalk.bold('Commands:')}
10
+ ${chalk.cyan('config')} Configure CLI settings
11
+ ${chalk.cyan('remote')} Run and manage tests on remote
12
+ ${chalk.cyan('version')} Show version information
13
+ ${chalk.cyan('help <command>')} Show help menu for a command
14
+
15
+ ${chalk.bold('Global flags:')}
16
+ ${chalk.yellow('--debug')} Show raw API responses
17
+ ${chalk.yellow('--no-color')} Disable colored output`,
11
18
 
12
19
  config: `
13
- bugbug config <options>
20
+ ${chalk.bold('Usage:')}
21
+ ${chalk.green('bugbug config')} <command>
14
22
 
15
- options:
16
- * set-token <token>`,
23
+ ${chalk.bold('Commands:')}
24
+ ${chalk.cyan('set-token <token>')} Set BugBug API token`,
17
25
 
18
26
  remote: `
19
- bugbug remote <options>
20
-
21
- options:
22
- * list [test|suite|profile] [--no-wait] [--no-progress] [--debug]
23
- * run [test|suite] <string:testId|suiteId> [--no-wait] [--no-progress] [--debug] [--with-details] [--profile] [--variable] [--result-timeout <int>] [--reporter] [--output-path]
24
- * status [test|suite] <string:testRunId|suiteRunId> [--no-progress] [--debug]
25
- * result [test|suite] <string:testRunId|suiteRunId> [--no-progress] [--debug] [--with-details] [--result-timeout <int>]
26
- * stop [test|suite] <string:testRunId|suiteRunId> [--no-progress] [--debug] [--result-timeout <int>]
27
-
28
- optional flags:
29
- * --debug - show more data (like raw API response)
30
- * --no-progress - don't show progress spinner
31
- * --no-wait - exit immediately, don't wait for result
32
- * --profile <string:"profile name"> - run with specific profile
33
- * --variable <string:"varName=varValue"> - override variable during single run
34
- * --with-details - show result with details
35
- * --reporter <"inline"|"junit"> - the name of the reporter to use (default: "inline")
36
- * --output-path - the path to save the test report; relative to the current working directory
37
- * --result-timeout - modify the default result waiting time (minutes, default: 60)
27
+ ${chalk.bold('Usage:')}
28
+ ${chalk.green('bugbug remote')} <command> [options]
29
+
30
+ ${chalk.bold('Commands:')}
31
+ ${chalk.cyan('list')} <test|suite|profile> List tests, suites or profiles
32
+ ${chalk.cyan('run')} <test|suite> <id> Run a test or suite
33
+ ${chalk.cyan('status')} <test|suite> <id> Check run status
34
+ ${chalk.cyan('result')} <test|suite> <id> Get run result
35
+ ${chalk.cyan('stop')} <test|suite> <id> Stop a running test or suite
36
+
37
+
38
+ ${chalk.bold('Global flags:')}
39
+ ${chalk.yellow('--debug')} Show raw API responses
40
+ ${chalk.yellow('--no-progress')} Hide progress spinner
41
+ ${chalk.yellow('--no-color')} Disable colored output
42
+
43
+ ${chalk.bold('Command-specific flags:')}
44
+ ${chalk.white.underline('run, status')}
45
+ ${chalk.yellow('--no-wait')} Exit immediately, don't wait for result
46
+ ${chalk.yellow('--result-timeout <min>')} Max waiting time (default: 60)
47
+
48
+ ${chalk.white.underline('run')}
49
+ ${chalk.yellow('--profile <name>')} Run with specific profile
50
+ ${chalk.yellow('--variable <key=val>')} Override variable (can be used multiple times)
51
+
52
+ ${chalk.white.underline('run, status, result')}
53
+ ${chalk.yellow('--with-details')} Include detailed step information
54
+ ${chalk.yellow('--reporter <type>')} "inline" or "junit" (default: "inline")
55
+ ${chalk.yellow('--output-path <path>')} Path for JUnit report (default: test-report.xml)
38
56
  `,
39
57
  };
40
58
 
@@ -192,8 +192,8 @@ const checkTokenConfig = async () => {
192
192
  };
193
193
 
194
194
  const parseArgs = async (args) => {
195
- const subCmd = args._[1].toLowerCase();
196
- const objectType = args._[2].toLowerCase();
195
+ const subCmd = (args._[1] || '').toLowerCase();
196
+ const objectType = (args._[2] || '').toLowerCase();
197
197
  const id = args._[3];
198
198
  const variables = await parseVariables(args.variable);
199
199
 
@@ -215,19 +215,24 @@ const parseArgs = async (args) => {
215
215
  };
216
216
 
217
217
  const validateArgs = async (args) => {
218
+ const subCmd = (args._[1] || '').toLowerCase();
219
+ if (subCmd === settings.ACTION_HELP) {
220
+ return true;
221
+ }
222
+
218
223
  if (args._.length < 3) {
219
224
  console.error('Missing parameters!');
220
225
  help({ _: ['remote'] });
221
226
  return false;
222
227
  }
223
228
 
224
- const knownKeys = ['_', 'wait', 'nowait', 'noprogress', 'progress', 'with-details', 'debug', 'profile', 'variable', 'result-timeout', 'reporter', 'output-path', 'triggered-by'];
229
+ const knownKeys = ['_', 'wait', 'nowait', 'noprogress', 'progress', 'with-details', 'debug', 'profile', 'variable', 'result-timeout', 'reporter', 'output-path', 'triggered-by', 'color', 'no-color'];
225
230
  const unknownKeys = await getUnknownOptions(args, knownKeys);
226
231
  if (unknownKeys.length > 0) {
227
232
  console.error(`Unknown options: ${unknownKeys.join(', ')}`);
228
233
  return false;
229
234
  }
230
- const { subCmd, objectType, id } = await parseArgs(args);
235
+ const { objectType, id } = await parseArgs(args);
231
236
 
232
237
  if (!OBJECT_TYPES.includes(objectType)) {
233
238
  console.error(`Incorrect object type ${objectType}. Available types: ${OBJECT_TYPES}.`);
@@ -267,6 +272,10 @@ module.exports = async (args) => {
267
272
  let exitCode;
268
273
  await checkTokenConfig();
269
274
  switch (subCmd) {
275
+ case settings.ACTION_HELP:
276
+ help({ _: ['remote'] });
277
+ exitCode = await getExitCode(true);
278
+ break;
270
279
  case settings.ACTION_LIST:
271
280
  exitCode = await getList(objectType, id, extraParams);
272
281
  break;
package/src/index.js CHANGED
@@ -3,9 +3,10 @@ const minimist = require('minimist');
3
3
  const { nanoid } = require('nanoid');
4
4
  const { sentry, init: initSentry } = require('./utils/sentry');
5
5
  const settings = require('./settings');
6
- require('dotenv').config();
6
+ require('dotenv').config({ quiet: true });
7
7
  require('dotenv').config({
8
8
  path: path.resolve(process.cwd(), `.env.${settings.NODE_ENV}`),
9
+ quiet: true,
9
10
  });
10
11
  // Initialize Sentry first
11
12
  initSentry();
package/src/settings.js CHANGED
@@ -9,7 +9,7 @@ util.inspect.styles.string = 'white';
9
9
  const NODE_ENV = process.env.NODE_ENV || 'production';
10
10
  const ENV_FILE_PATH = path.resolve(__dirname, '..', `.env.${NODE_ENV}`);
11
11
  const USER_AGENT = `BugBug CLI ${VERSION}`;
12
- dotenv.config({ path: ENV_FILE_PATH });
12
+ dotenv.config({ path: ENV_FILE_PATH, quiet: true });
13
13
 
14
14
  // TODO: Fix this path due to Mac OS restrictions
15
15
  const CONFIG_DIR_PATH = path.join(os.homedir(), '.bugbug');
package/test-report.xml CHANGED
@@ -34,4 +34,4 @@ First 3 steps:
34
34
  </system-out>
35
35
  </testcase>
36
36
  </testsuite>
37
- </testsuites>
37
+ </testsuites>