@testrevolution/bugbug-cli 8.14.5 → 8.15.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/package.json
CHANGED
package/src/__mocks__/api.js
CHANGED
|
@@ -41,6 +41,12 @@ module.exports = {
|
|
|
41
41
|
webappUrl: 'http://localhost:3000/organizations/ed67dc98-16be-48d5-97fe-2f579ca6a62a/projects/cli-cc3abe1c-4540-4451-8bdc-41ac893e5720/runs-history/tests/cabe0d21-7693-4953-8851-581554a70368/',
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
+
stopTestRunRunSuccess: {
|
|
45
|
+
data: {
|
|
46
|
+
id: '95a37d6a-a7a5-42ae-8fe3-336a120b807b',
|
|
47
|
+
status: 'stopped',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
44
50
|
getResultTestRunSuccess: {
|
|
45
51
|
data: {
|
|
46
52
|
details: [{
|
|
@@ -21,13 +21,12 @@ beforeAll(() => {
|
|
|
21
21
|
afterAll(() => {
|
|
22
22
|
config.__RewireAPI__.__ResetDependency__('readConfig');
|
|
23
23
|
});
|
|
24
|
+
jest.mock('axios');
|
|
24
25
|
|
|
25
26
|
afterEach(() => {
|
|
26
27
|
jest.restoreAllMocks();
|
|
27
28
|
});
|
|
28
29
|
|
|
29
|
-
jest.mock('axios');
|
|
30
|
-
|
|
31
30
|
describe('commands module', () => {
|
|
32
31
|
describe('help', () => {
|
|
33
32
|
it('should console log main help menu', async () => {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
remote: remoteCommand,
|
|
5
|
+
} = require('../commands');
|
|
6
|
+
const settings = require('../settings');
|
|
7
|
+
const config = require('../utils/config');
|
|
8
|
+
// eslint-disable-next-line jest/no-mocks-import
|
|
9
|
+
const apiMocks = require('../__mocks__/api');
|
|
10
|
+
|
|
11
|
+
const configValue = { item: 'value', token: '1337' };
|
|
12
|
+
|
|
13
|
+
beforeAll(() => {
|
|
14
|
+
// rewire discussion
|
|
15
|
+
// https://github.com/facebook/jest/issues/936#issuecomment-545080082
|
|
16
|
+
config.__RewireAPI__.__Rewire__('readConfig', jest.fn().mockReturnValue(configValue));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterAll(() => {
|
|
20
|
+
config.__RewireAPI__.__ResetDependency__('readConfig');
|
|
21
|
+
});
|
|
22
|
+
jest.mock('axios');
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
jest.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('commands stop module', () => {
|
|
29
|
+
beforeAll(() => {
|
|
30
|
+
settings.API_POLLING_INTERVAL = 1;
|
|
31
|
+
settings.API_POLLING_MAX_RETRY_TIMES = 5;
|
|
32
|
+
settings.API_URL = 'https://bugbug.io/test-api/';
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('stop test command should call API', async () => {
|
|
36
|
+
const consoleLogSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
37
|
+
axios.mockResolvedValueOnce(apiMocks.stopTestRunRunSuccess);
|
|
38
|
+
const id = '95a37d6a-a7a5-42ae-8fe3-336a120b807b';
|
|
39
|
+
const args = {
|
|
40
|
+
_: ['remote', 'stop', 'test', id],
|
|
41
|
+
noprogress: true,
|
|
42
|
+
};
|
|
43
|
+
await remoteCommand(args);
|
|
44
|
+
|
|
45
|
+
expect(consoleLogSpy).toHaveBeenNthCalledWith(1, `Status: ${apiMocks.stopTestRunRunSuccess.data.status}`);
|
|
46
|
+
expect(axios).toHaveBeenCalledWith({
|
|
47
|
+
method: 'POST',
|
|
48
|
+
url: `https://bugbug.io/test-api/v1/testruns/${id}/stop/`,
|
|
49
|
+
data: { triggeredBy: 'cli' },
|
|
50
|
+
params: {},
|
|
51
|
+
headers: { Authorization: `Token ${configValue.token}`, 'User-Agent': settings.USER_AGENT },
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('stop test action should call stopTestRun function', async () => {
|
|
56
|
+
const stopMock = jest.fn();
|
|
57
|
+
remoteCommand.__RewireAPI__.__Rewire__('stopTestRun', stopMock);
|
|
58
|
+
|
|
59
|
+
const id = '95a37d6a-a7a5-42ae-8fe3-336a120b807b';
|
|
60
|
+
const args = {
|
|
61
|
+
_: ['remote', 'stop', 'test', id],
|
|
62
|
+
noprogress: true,
|
|
63
|
+
};
|
|
64
|
+
await remoteCommand(args);
|
|
65
|
+
expect(stopMock).toHaveBeenCalledWith(id, {
|
|
66
|
+
noprogress: true, nowait: false, outputPath: 'test-report.xml', reporter: 'inline', triggeredBy: 'cli', withDetails: false,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('stop suite action should call stopSuiteRun function', async () => {
|
|
71
|
+
const stopMock = jest.fn();
|
|
72
|
+
remoteCommand.__RewireAPI__.__Rewire__('stopSuiteRun', stopMock);
|
|
73
|
+
|
|
74
|
+
const id = '95a37d6a-a7a5-42ae-8fe3-336a120b807b';
|
|
75
|
+
const args = {
|
|
76
|
+
_: ['remote', 'stop', 'suite', id],
|
|
77
|
+
noprogress: true,
|
|
78
|
+
};
|
|
79
|
+
await remoteCommand(args);
|
|
80
|
+
expect(stopMock).toHaveBeenCalledWith(id, {
|
|
81
|
+
noprogress: true, nowait: false, outputPath: 'test-report.xml', reporter: 'inline', triggeredBy: 'cli', withDetails: false,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
});
|
package/src/commands/help.js
CHANGED
|
@@ -23,6 +23,7 @@ const help = {
|
|
|
23
23
|
* run [test|suite] <string:testId|suiteId> [--no-wait] [--no-progress] [--debug] [--with-details] [--profile] [--variable] [--result-timeout <int>]
|
|
24
24
|
* status [test|suite] <string:testRunId|suiteRunId> [--no-progress] [--debug]
|
|
25
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>]
|
|
26
27
|
|
|
27
28
|
optional flags:
|
|
28
29
|
* --debug - show more data (like raw API response)
|
package/src/commands/remote.js
CHANGED
|
@@ -128,6 +128,29 @@ const run = async (type, data, extraParams) => {
|
|
|
128
128
|
return getExitCode(false);
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
+
const stop = async (type, { id }, extraParams) => {
|
|
132
|
+
const { noprogress } = extraParams;
|
|
133
|
+
const route = settings.API_ROUTING[`${type}Stop`];
|
|
134
|
+
|
|
135
|
+
const path = format(route.path, id);
|
|
136
|
+
|
|
137
|
+
const spinner = getSpinner(noprogress);
|
|
138
|
+
try {
|
|
139
|
+
console.log('stop');
|
|
140
|
+
const response = await apiCall(path, route.method, {}, {}, extraParams.triggeredBy);
|
|
141
|
+
printStatus(spinner, response.data.status);
|
|
142
|
+
|
|
143
|
+
return getExitCode(true);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (error.response?.status === 404) {
|
|
146
|
+
spinner.fail(`No ${type}Run with id ${id} found.`);
|
|
147
|
+
} else {
|
|
148
|
+
await printErrorResponse(spinner, error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return getExitCode(false);
|
|
152
|
+
};
|
|
153
|
+
|
|
131
154
|
const runTest = async (testId, profileName, variables, extraParams) => run(settings.TYPE_TEST, {
|
|
132
155
|
test_id: testId, profile_name: profileName, variables,
|
|
133
156
|
}, extraParams);
|
|
@@ -136,6 +159,14 @@ const runSuite = async (suiteId, profileName, variables, extraParams) => run(set
|
|
|
136
159
|
suite_id: suiteId, profile_name: profileName, variables,
|
|
137
160
|
}, extraParams);
|
|
138
161
|
|
|
162
|
+
const stopTestRun = async (testRunId, extraParams) => stop(settings.TYPE_TEST, {
|
|
163
|
+
id: testRunId,
|
|
164
|
+
}, extraParams);
|
|
165
|
+
|
|
166
|
+
const stopSuiteRun = async (suiteRunId, extraParams) => stop(settings.TYPE_SUITE, {
|
|
167
|
+
id: suiteRunId,
|
|
168
|
+
}, extraParams);
|
|
169
|
+
|
|
139
170
|
const checkTokenConfig = async () => {
|
|
140
171
|
try {
|
|
141
172
|
if (await getConfigValue('token') === undefined) {
|
|
@@ -223,6 +254,13 @@ module.exports = async (args) => {
|
|
|
223
254
|
case settings.ACTION_STATUS:
|
|
224
255
|
exitCode = await checkStatus(objectType, id, extraParams);
|
|
225
256
|
break;
|
|
257
|
+
case settings.ACTION_STOP:
|
|
258
|
+
if (objectType === settings.TYPE_TEST) {
|
|
259
|
+
exitCode = await stopTestRun(id, extraParams);
|
|
260
|
+
} else if (objectType === settings.TYPE_SUITE) {
|
|
261
|
+
exitCode = await stopSuiteRun(id, extraParams);
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
226
264
|
case settings.ACTION_RESULT:
|
|
227
265
|
exitCode = await getResult(objectType, id, extraParams);
|
|
228
266
|
break;
|
package/src/settings.js
CHANGED
|
@@ -25,6 +25,7 @@ const ACTION_HELP = 'help';
|
|
|
25
25
|
const ACTION_SET_TOKEN = 'set-token';
|
|
26
26
|
const ACTION_LIST = 'list';
|
|
27
27
|
const ACTION_RUN = 'run';
|
|
28
|
+
const ACTION_STOP = 'stop';
|
|
28
29
|
const ACTION_STATUS = 'status';
|
|
29
30
|
const ACTION_RESULT = 'result';
|
|
30
31
|
|
|
@@ -35,10 +36,12 @@ const API_ROUTING = {
|
|
|
35
36
|
suiteResult: { method: 'GET', path: `${API_VERSION}/suiteruns/%s/` },
|
|
36
37
|
suiteRun: { method: 'POST', path: `${API_VERSION}/suiteruns/` },
|
|
37
38
|
suiteStatus: { method: 'GET', path: `${API_VERSION}/suiteruns/%s/status/` },
|
|
39
|
+
suiteStop: { method: 'POST', path: `${API_VERSION}/suiteruns/%s/stop/` },
|
|
38
40
|
testList: { method: 'GET', path: `${API_VERSION}/tests/` },
|
|
39
41
|
testResult: { method: 'GET', path: `${API_VERSION}/testruns/%s/` },
|
|
40
42
|
testRun: { method: 'POST', path: `${API_VERSION}/testruns/` },
|
|
41
43
|
testStatus: { method: 'GET', path: `${API_VERSION}/testruns/%s/status/` },
|
|
44
|
+
testStop: { method: 'POST', path: `${API_VERSION}/testruns/%s/stop/` },
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
const API_POLLING_MODIFIED_INTERVAL = 120000; // 120 seconds
|
|
@@ -81,6 +84,7 @@ module.exports = {
|
|
|
81
84
|
ACTION_RUN,
|
|
82
85
|
ACTION_SET_TOKEN,
|
|
83
86
|
ACTION_STATUS,
|
|
87
|
+
ACTION_STOP,
|
|
84
88
|
API_CALL_RETRIES,
|
|
85
89
|
API_CALL_RETRY_DELAY,
|
|
86
90
|
API_ERROR_QUOTA_EXCEEDED,
|