@suffolklitlab/alkiln 5.12.0 → 5.13.0-logs2
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.example +29 -0
- package/.github/workflows/github_server.yml +59 -12
- package/.github/workflows/playground.yml +11 -4
- package/CHANGELOG.md +41 -1
- package/CONTRIBUTING.md +98 -83
- package/README.md +1 -1
- package/action.yml +69 -29
- package/action_for_github_server/action.yml +65 -31
- package/docs/decisions/006_which_log_level_to_pick_2024_09_5.md +46 -0
- package/docs/decisions/adopt_architectural_decision_records.md +58 -0
- package/docs/decisions/detect_sign_in.md +124 -0
- package/docs/decisions/pdfjs_version_2024_08_08.md +18 -0
- package/docs/decisions/reports_and_logs_2024_08_11.md +141 -0
- package/docs/decisions/update_puppeteer_2024_07_28.md +62 -0
- package/docs/story_tables.md +1 -1
- package/lib/docassemble/docassemble_api_REST.js +67 -1
- package/lib/docassemble/docassemble_api_interface.js +225 -18
- package/lib/docassemble/server_install.js +23 -9
- package/lib/docassemble/setup.js +33 -20
- package/lib/docassemble/takedown.js +27 -7
- package/lib/run_cucumber.js +83 -33
- package/lib/scope.js +222 -82
- package/lib/steps.js +206 -62
- package/lib/utils/files.js +8 -6
- package/lib/utils/log.js +477 -84
- package/lib/utils/reports.js +14 -5
- package/lib/utils/session_vars.js +25 -18
- package/lib/utils/time.js +44 -0
- package/npm-shrinkwrap.json +635 -193
- package/package.json +8 -8
- package/setup.py +1 -1
- package/tests/log_codes/check_codes.sh +163 -108
- package/tests/log_codes/log_code_expected_instances.txt +213 -0
- package/tests/unit_tests/getAllFields.test.js +5 -0
- package/tests/unit_tests/getMatchingRows.test.js +5 -0
- package/tests/unit_tests/log.test.js +20 -0
- package/tests/unit_tests/normalizeTable.test.js +5 -0
- package/tests/log_codes/deleted_codes.json +0 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const _da_REST = require('./docassemble_api_REST');
|
|
2
|
-
const
|
|
2
|
+
const Log = require('../utils/log');
|
|
3
3
|
const session_vars = require('../utils/session_vars' );
|
|
4
4
|
const time = require('../utils/time');
|
|
5
5
|
|
|
@@ -15,6 +15,9 @@ const time = require('../utils/time');
|
|
|
15
15
|
// to specific functions, which can run in a very small
|
|
16
16
|
// window.
|
|
17
17
|
|
|
18
|
+
// TODO: Move get_dev_id() and such into here instead of in
|
|
19
|
+
// docassemble_REST - args should be the same vals as the request expects
|
|
20
|
+
|
|
18
21
|
/** Notes:
|
|
19
22
|
* - Checking for a busy server is vulnerable to race conditions, but
|
|
20
23
|
* there's nothing we can do about that.
|
|
@@ -58,6 +61,10 @@ const time = require('../utils/time');
|
|
|
58
61
|
let da_i = {};
|
|
59
62
|
module.exports = da_i;
|
|
60
63
|
|
|
64
|
+
const artifacts_path = session_vars.get_artifacts_path_name();
|
|
65
|
+
const log = new Log({ path: artifacts_path, context: `api` });
|
|
66
|
+
const context = `da api`;
|
|
67
|
+
|
|
61
68
|
|
|
62
69
|
// Constants
|
|
63
70
|
const DEFAULT_MAX_REQUEST_MS = session_vars.get_setup_timeout_ms();
|
|
@@ -89,7 +96,9 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
|
|
|
89
96
|
|
|
90
97
|
// Defaults
|
|
91
98
|
let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
92
|
-
log.info({
|
|
99
|
+
log.info({ code: `ALK0166`, context: `da api`, },
|
|
100
|
+
`Waiting for the docassemble server to respond. Will wait for ${ timeout/1000 } seconds at most.`
|
|
101
|
+
);
|
|
93
102
|
|
|
94
103
|
try {
|
|
95
104
|
let start_time = Date.now()
|
|
@@ -97,7 +106,9 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
|
|
|
97
106
|
let response = await _da_REST.get_dev_id( timeout );
|
|
98
107
|
let end_time = Date.now()
|
|
99
108
|
if ( response && response.data && response.data.id ) {
|
|
100
|
-
log.info({
|
|
109
|
+
log.info({ code: `ALK0167`, context: `da api`, },
|
|
110
|
+
`The docassemble server responded after ${ (end_time - start_time)/1000 } seconds.`
|
|
111
|
+
);
|
|
101
112
|
return false;
|
|
102
113
|
}
|
|
103
114
|
|
|
@@ -106,17 +117,16 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
|
|
|
106
117
|
if ( is_timeout_error( error ) ) {
|
|
107
118
|
// Anything that's waiting for the server to not be busy does not want
|
|
108
119
|
// to move forward without a free server.
|
|
109
|
-
log.info({
|
|
120
|
+
log.info({ code: `ALK0168`, context: `da api`, },
|
|
121
|
+
`The docassemble server was still busy after ${ timeout/1000 } seconds.`
|
|
122
|
+
);
|
|
110
123
|
} else {
|
|
111
124
|
// Not sure what to do for other errors. It could be a server
|
|
112
125
|
// error, like an 'Access Denied' error, which should be handled.
|
|
113
|
-
log.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
+ `ran into an unexpected error. The error didn't indicate a busy server, though. Error message:\n`
|
|
118
|
-
+ error
|
|
119
|
-
});
|
|
126
|
+
log.warning({ code: `ALK0169`, context: `da api` },
|
|
127
|
+
`Checked if the server was busy and ran into a different error`,
|
|
128
|
+
error
|
|
129
|
+
);
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
throw error;
|
|
@@ -174,25 +184,222 @@ da_i.get_dev_id = async function ( dev_id_options ) {
|
|
|
174
184
|
return dev_id;
|
|
175
185
|
}; // Ends da_i.get_dev_id();
|
|
176
186
|
|
|
187
|
+
da_i.get_api_key_access_status = async function ({ timeout = null, api_key = null }) {
|
|
188
|
+
/** Check if the API key has minimal authorization on the server.
|
|
189
|
+
* See https://docassemble.org/docs/api.html#api_user_api_get.
|
|
190
|
+
*
|
|
191
|
+
* @param options {obj} Options for getting authorization of the API key
|
|
192
|
+
* @param options.api_key {str | null} Required. The API key to test.
|
|
193
|
+
* @param options.timeout {int | null} Optional. Max MS
|
|
194
|
+
* to allow for server request.
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
let auth_data = {
|
|
198
|
+
codes: [ 1 ],
|
|
199
|
+
has_auth: null,
|
|
200
|
+
messages: [`API key authorization is not yet determined.`],
|
|
201
|
+
error: null
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Skip this for tests run from ALKilnInThePlayground
|
|
205
|
+
if ( session_vars.get_origin() === 'playground' ) {
|
|
206
|
+
auth_data.codes.push( 2 );
|
|
207
|
+
auth_data.messages.push( `API keys are unnecessary for tests run in the Playground.` );
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if ( typeof api_key !== `string` ) {
|
|
211
|
+
auth_data.codes.push( 3 );
|
|
212
|
+
auth_data.messages.push( `The given API key is not a string. Type: ${ typeof api_key }`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if ( auth_data.codes.length === 1 ) {
|
|
216
|
+
// Default timeouts
|
|
217
|
+
timeout = timeout || DEFAULT_MAX_REQUEST_MS;
|
|
218
|
+
try {
|
|
219
|
+
let response = await _da_REST.get_api_key_info( timeout, {
|
|
220
|
+
api_key,
|
|
221
|
+
server_url: session_vars.get_da_server_url(),
|
|
222
|
+
});
|
|
223
|
+
auth_data.has_auth = true;
|
|
224
|
+
auth_data.codes = [ 6 ];
|
|
225
|
+
auth_data.messages = [ `This API key has at least basic authorization on this server.` ];
|
|
226
|
+
|
|
227
|
+
} catch ( error ) {
|
|
228
|
+
auth_data.error = error;
|
|
229
|
+
if ( error.status === 403 ) {
|
|
230
|
+
auth_data.has_auth = false;
|
|
231
|
+
auth_data.codes = [ 4 ];
|
|
232
|
+
auth_data.messages = [ `This API is unverified on this server. It is probably missing or has been deleted.` ];
|
|
233
|
+
} else {
|
|
234
|
+
// Note on 404, non-existent key: 404 == 403 - Since we're using the
|
|
235
|
+
// key itself to get its own info, if it doesn't exist, we'll get 403
|
|
236
|
+
auth_data.codes = [ 5 ];
|
|
237
|
+
auth_data.messages = [ `This API key threw a non-403 error.` ];
|
|
238
|
+
} // ends error status
|
|
239
|
+
} // ends try
|
|
240
|
+
} // ends auth_data.codes only has the first code
|
|
241
|
+
|
|
242
|
+
// log.debug({ type: `da api info`, code: `ALKx0202`,
|
|
243
|
+
// pre: `API key authentication info`, data: auth_data });
|
|
244
|
+
log.debug({ code: `ALK0202`, context: `da api`, },
|
|
245
|
+
`API key authentication info`,
|
|
246
|
+
auth_data
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
return auth_data;
|
|
250
|
+
}; // Ends da_i.get_api_key_access_status()
|
|
251
|
+
|
|
177
252
|
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").delete_project( "create1" )'
|
|
178
253
|
da_i.delete_project = async function ( delete_options ) {
|
|
179
254
|
/** Delete a project on the user's da server. Do we need to watch
|
|
180
255
|
* for a timeout? */
|
|
181
256
|
|
|
182
257
|
// Defaults
|
|
183
|
-
let { timeout } = delete_options ||
|
|
258
|
+
let { timeout } = delete_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
184
259
|
|
|
185
260
|
let project_name = session_vars.get_project_name()
|
|
186
|
-
log.info({
|
|
261
|
+
log.info({ code: `ALK0170`, context: `da api`, },
|
|
262
|
+
`Trying to delete Project ${ project_name }`
|
|
263
|
+
);
|
|
187
264
|
|
|
188
265
|
try {
|
|
189
266
|
let response = await _da_REST.delete_project( timeout );
|
|
190
|
-
log.info({
|
|
267
|
+
log.info({ code: `ALK0171`, context: `da api`, },
|
|
268
|
+
`Deleted Project "${ project_name }"`
|
|
269
|
+
);
|
|
191
270
|
} catch ( error ) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
throw error;
|
|
271
|
+
log.throw({ code: `ALK0172`, context: `da api`, error: error },
|
|
272
|
+
`Ran into an error when deleting Project "${ project_name }". See https://docassemble.org/docs/api.html#playground_delete_project.`
|
|
273
|
+
);
|
|
274
|
+
// throw error;
|
|
196
275
|
}
|
|
197
276
|
|
|
198
277
|
}; // Ends da_i.delete_project()
|
|
278
|
+
|
|
279
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").quietly_try_to_delete_interviews(...)'
|
|
280
|
+
da_i.quietly_try_to_delete_interviews = async function ({ interviews = {}, api_keys = [], options = {} }) {
|
|
281
|
+
/** Try to delete the given interviews. Fail silently. Example failure: the test
|
|
282
|
+
* did not log in any users and the testing account's role prevents
|
|
283
|
+
* access to other user's interviews. Do we need to watch for a timeout? */
|
|
284
|
+
|
|
285
|
+
// Defaults
|
|
286
|
+
let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
287
|
+
|
|
288
|
+
let responses = [];
|
|
289
|
+
for ( let id in interviews ) {
|
|
290
|
+
let interview = interviews[ id ];
|
|
291
|
+
if ( interview && interview.uid ) {
|
|
292
|
+
let sub_responses = await da_i.quietly_delete_one_interview( timeout, {
|
|
293
|
+
interview,
|
|
294
|
+
api_keys
|
|
295
|
+
});
|
|
296
|
+
responses.push( sub_responses );
|
|
297
|
+
} else {
|
|
298
|
+
log.debug({ code: `ALK0191`, context: `da api` },
|
|
299
|
+
`There is no interview to delete.`
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return responses;
|
|
304
|
+
}; // Ends da_i.quietly_try_to_delete_interviews()
|
|
305
|
+
|
|
306
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").quietly_delete_one_interview(...)'
|
|
307
|
+
da_i.quietly_delete_one_interview = async function ( timeout, { interview = {}, api_keys = [] }) {
|
|
308
|
+
/** Try to delete an interview using all available API keys. Fail silently.
|
|
309
|
+
* Example failure: the test did not log in any users and the testing
|
|
310
|
+
* account's role prevents access to other user's interviews. */
|
|
311
|
+
|
|
312
|
+
let responses = [];
|
|
313
|
+
for ( let api_key of api_keys ) {
|
|
314
|
+
try {
|
|
315
|
+
log.debug({ code: `ALK0188`, context: `da api` },
|
|
316
|
+
`Trying to delete the interview with the id ${ interview.uid } and an API key.`
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
// Actual work:
|
|
320
|
+
let response = await _da_REST.delete_interview( timeout, {
|
|
321
|
+
session: interview.uid,
|
|
322
|
+
api_key
|
|
323
|
+
});
|
|
324
|
+
responses.push( response );
|
|
325
|
+
|
|
326
|
+
log.debug({ code: `ALK0189`, context: `da api` },
|
|
327
|
+
`No error when trying to delete interview ${ interview.uid } at ${ interview.i }.`
|
|
328
|
+
);
|
|
329
|
+
} catch ( error ) {
|
|
330
|
+
error.interview = interview;
|
|
331
|
+
log.debug({ code: `ALK0190`, context: `da api` },
|
|
332
|
+
`Error when deleting the interview. See https://docassemble.org/docs/api.html#session_delete.`,
|
|
333
|
+
error
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
} // ends for api keys
|
|
337
|
+
return responses;
|
|
338
|
+
}; // Ends da_i.quietly_delete_one_interview()
|
|
339
|
+
|
|
340
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").get_interviews(...)'
|
|
341
|
+
da_i.get_interviews = async function ({ interviews = {}, api_keys = [], options = {} }) {
|
|
342
|
+
/** Return an object of interviews that exist on the server
|
|
343
|
+
* that match the given interviews. Keys are the session ids. */
|
|
344
|
+
|
|
345
|
+
let fetched_interviews = {};
|
|
346
|
+
if ( interviews ) {
|
|
347
|
+
for ( let id in interviews ) {
|
|
348
|
+
let interview = interviews[ id ];
|
|
349
|
+
let fetched = await da_i.get_interview({ interview, api_keys, options });
|
|
350
|
+
if ( fetched && fetched.session ) {
|
|
351
|
+
fetched_interviews[ fetched.session ] = fetched;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} // ends if interviews
|
|
355
|
+
|
|
356
|
+
return fetched_interviews;
|
|
357
|
+
}; // Ends da_i.get_interviews()
|
|
358
|
+
|
|
359
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").get_interview(...)'
|
|
360
|
+
da_i.get_interview = async function ({ interview = {}, api_keys = [], options = {} }) {
|
|
361
|
+
/** Try to get an interview from the server that matches the given interview data. */
|
|
362
|
+
|
|
363
|
+
// Defaults
|
|
364
|
+
let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
365
|
+
|
|
366
|
+
if ( interview && interview.uid ) {
|
|
367
|
+
for ( let api_key of api_keys ) {
|
|
368
|
+
try {
|
|
369
|
+
log.debug({ code: `ALK0192`, context: `da api` },
|
|
370
|
+
`Trying to get the interview with the id ${ interview.uid } and an API key.`
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
// Actual work:
|
|
374
|
+
let response = await _da_REST.get_interview( timeout, {
|
|
375
|
+
session: interview.uid,
|
|
376
|
+
api_key
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if ( response && response.data && response.data.items && response.data.items[0] && response.data.items[0].session ) {
|
|
380
|
+
log.debug({ code: `ALK0193`, context: `da api` },
|
|
381
|
+
`Status ${ response.status }. Got ${ response.data.items[0].session }.`
|
|
382
|
+
);
|
|
383
|
+
return response.data.items[0];
|
|
384
|
+
} else {
|
|
385
|
+
log.debug({ code: `ALK0194`, context: `da api` },
|
|
386
|
+
`Status ${ response.status }. Cannot find ${ interview.uid }`
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
} catch ( error ) {
|
|
391
|
+
error.interview = interview;
|
|
392
|
+
log.debug({ code: `ALK0195`, context: `da api` },
|
|
393
|
+
`${ error.status || `No error.status.` } ${ error.statusText || error.data || `No error.statusText.` } Ran into an error when getting the interview ${ interview.uid }. See https://docassemble.org/docs/api.html#interviews.`,
|
|
394
|
+
error
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
} // ends for api_keys
|
|
398
|
+
} else {
|
|
399
|
+
log.debug({ code: `ALK0196`, context: `da api` },
|
|
400
|
+
`There is no interview to get.`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return null;
|
|
405
|
+
}; // Ends da_i.get_interview()
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const session_vars = require('../utils/session_vars');
|
|
4
|
-
const
|
|
4
|
+
const Log = require('../utils/log');
|
|
5
5
|
const fg = require('fast-glob');
|
|
6
6
|
|
|
7
7
|
const server_install = async () => {
|
|
8
|
+
/** Finds out where in this directory the package's folders are. */
|
|
8
9
|
session_vars.save_install_method(`server`);
|
|
9
10
|
|
|
10
11
|
// Get path to folders inside repo main "docassemble" folder
|
|
@@ -23,20 +24,33 @@ const server_install = async () => {
|
|
|
23
24
|
// Get names of all folders in repo "docassemble" folder
|
|
24
25
|
let chosen_folder = folders[0];
|
|
25
26
|
if ( folders.length === 0 ) {
|
|
26
|
-
let msg = `There are 0 folders at ${path}. Stopping tests.`;
|
|
27
|
-
log.
|
|
28
|
-
|
|
27
|
+
let msg = `ALKiln cannot find the package's files. There are 0 folders at "${ path }". Stopping tests.`;
|
|
28
|
+
log.throw({ code: `ALK0044`, context: `server_install`,
|
|
29
|
+
error: new ReferenceError( msg ); // no logs
|
|
30
|
+
});
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
if ( folders.length > 1 ) {
|
|
32
|
-
log.warn({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
34
|
+
log.warn({ code: `ALK0045`, context: `setup`, },
|
|
35
|
+
`There are ${ folders.length } folders at "${ path }": "${ folders.join('", "') }". ALKiln chose to use the folder "${ chosen_folder }".`
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
log.info({ code: `ALK0218`, context: `setup`, },
|
|
39
|
+
`ALKiln found the package folder at "${ chosen_folder }".`
|
|
40
|
+
);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
session_vars.save_repo_folder_name( chosen_folder );
|
|
40
44
|
}; // Ends server_install();
|
|
41
45
|
|
|
46
|
+
// 1. session_vars - make sure all the required env vars exist
|
|
47
|
+
session_vars.validateEnvironment();
|
|
48
|
+
|
|
49
|
+
// 2. Prepare logs
|
|
50
|
+
// Local devs: This will be separate from your test paths
|
|
51
|
+
// unless you pass a `path` argument into the cucumber run command
|
|
52
|
+
const argv = require(`minimist`)(process.argv.slice(2));
|
|
53
|
+
const log = new Log({ path: argv.path, context: `server_install` });
|
|
54
|
+
|
|
55
|
+
// 3. run
|
|
42
56
|
server_install();
|
package/lib/docassemble/setup.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// TODO: Rename to playground_install?
|
|
4
|
-
|
|
5
3
|
const child_process = require(`child_process`);
|
|
6
4
|
|
|
7
|
-
const
|
|
5
|
+
const Log = require(`../utils/log`);
|
|
8
6
|
const session_vars = require(`../utils/session_vars` );
|
|
7
|
+
const files = require(`../utils/files` );
|
|
8
|
+
const time = require(`../utils/time` );
|
|
9
9
|
|
|
10
10
|
const setup = async () => {
|
|
11
11
|
/** In the docassemble testing account identified by the
|
|
@@ -18,9 +18,14 @@ const setup = async () => {
|
|
|
18
18
|
let project_name = session_vars.get_project_base_name().replace(/[^A-Za-z0-9]/g, '') + `${Date.now()}`;
|
|
19
19
|
session_vars.save_project_name( project_name );
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const starting_msg = `Starting to upload this package to `
|
|
22
22
|
+ `a new Project called ${project_name} in the Playground `
|
|
23
|
-
+ `of your server's testing account. It may take a couple of minutes
|
|
23
|
+
+ `of your server's testing account. It may take a couple of minutes.`;
|
|
24
|
+
log.info({ code: `ALK0046`, context: `setup` },
|
|
25
|
+
starting_msg
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// TODO: 1. Start listening to the normal console here (for debug logging)
|
|
24
29
|
|
|
25
30
|
// dainstall . --apiurl https://site.org --apikey $API_KEY --playground --project=name
|
|
26
31
|
// I think this won't run on windows? Why do I think this? Where on the
|
|
@@ -34,29 +39,37 @@ const setup = async () => {
|
|
|
34
39
|
`--playground`, `--project=${ project_name }`
|
|
35
40
|
],
|
|
36
41
|
// Prints messages from the process to the console while it's running
|
|
42
|
+
// result.stderr, result.stdout, etc. will be `null`
|
|
37
43
|
{ stdio: 'inherit', }
|
|
38
44
|
);
|
|
39
45
|
|
|
40
|
-
//
|
|
41
|
-
// the response to find out the error code
|
|
46
|
+
// TODO: 2. Stop listening to the normal console here
|
|
42
47
|
|
|
48
|
+
// 403 is invalid API key, but I'm not sure how to output
|
|
49
|
+
// the response to find out the error code. stderr is `null`.
|
|
43
50
|
if ( result.status !== 0 ) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const install_err_msg = `Status code ${ result.status }. Could not `
|
|
52
|
+
+ `dainstall this package on your server. See above for more details.`;
|
|
53
|
+
log.throw({ code: `ALK0047`, context: `setup`,
|
|
54
|
+
before: `☝️ ☝️ ☝️ Error data ☝️ ☝️ ☝️\n`,
|
|
55
|
+
error: `Error while installing project` },
|
|
56
|
+
install_err_msg
|
|
57
|
+
);
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
log.success({
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
pre: `ALKiln created a Project in your Playground named "${ project_name }"!`
|
|
56
|
-
});
|
|
60
|
+
log.success({ code: `ALK0048`, context: `setup`, },
|
|
61
|
+
`ALKiln created a Project in your Playground named "${ project_name }"!`
|
|
62
|
+
);
|
|
57
63
|
}; // Ends setup();
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
// Before everything, make sure all the required env vars exist
|
|
65
|
+
// 1. session_vars - make sure all the required env vars exist
|
|
61
66
|
session_vars.validateEnvironment();
|
|
67
|
+
|
|
68
|
+
// 2. Prepare logs
|
|
69
|
+
// Local devs: This will be separate from your test paths
|
|
70
|
+
// unless you pass a `path` argument into the cucumber run command
|
|
71
|
+
const argv = require(`minimist`)(process.argv.slice(2));
|
|
72
|
+
const log = new Log({ path: argv.path, context: `setup` });
|
|
73
|
+
|
|
74
|
+
// 3. run
|
|
62
75
|
setup();
|
|
@@ -1,26 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const da_i = require('./docassemble_api_interface');
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const session_vars = require('../utils/session_vars');
|
|
5
|
+
const Log = require('../utils/log');
|
|
6
6
|
|
|
7
7
|
const takedown = async () => {
|
|
8
|
-
|
|
8
|
+
/** In the docassemble testing account identified by the
|
|
9
9
|
* DOCASSEMBLE_DEVELOPER_API_KEY secret, delete the
|
|
10
10
|
* Project created for this test.
|
|
11
11
|
* For local development, clean up project name file. */
|
|
12
|
-
log.info({
|
|
12
|
+
log.info({ code: `ALK0177`, context: `takedown`, },
|
|
13
|
+
`Trying to remove the docassemble Project from the testing account.`
|
|
14
|
+
);
|
|
13
15
|
// Explicit try-catch prevents "Unhandled promise rejection error"
|
|
14
16
|
// avoids showing confusing node errors to users that they shouldn't have to fix
|
|
15
17
|
try {
|
|
16
18
|
await da_i.delete_project();
|
|
17
19
|
session_vars.delete_project_name();
|
|
18
|
-
log.
|
|
20
|
+
log.info({ code: `ALK0178`, context: `takedown`, },
|
|
21
|
+
`Test takedown finished successfully!`
|
|
22
|
+
);
|
|
19
23
|
} catch (error) {
|
|
20
|
-
log.
|
|
21
|
-
|
|
24
|
+
log.throw({ code: `ALK0179`, context: `takedown`, error: error },
|
|
25
|
+
`Unable to delete project`,
|
|
26
|
+
);
|
|
27
|
+
// we don't re-throw the exception, so make sure to exit
|
|
28
|
+
// with 1 to let GitHub Actions know the script failed
|
|
22
29
|
process.exitCode = 1;
|
|
23
30
|
}
|
|
31
|
+
|
|
32
|
+
// TODO: ? Build the final setup, run, & takedown verbose log
|
|
33
|
+
// file in here. Add to it in the GitHub action ?
|
|
24
34
|
};
|
|
25
35
|
|
|
36
|
+
// 1. session_vars - make sure all the required env vars exist
|
|
37
|
+
session_vars.validateEnvironment();
|
|
38
|
+
|
|
39
|
+
// 2. Prepare logs
|
|
40
|
+
// Local devs: This will be separate from your test artifacts paths
|
|
41
|
+
// unless you pass a `path` argument into the `cucumber` run command
|
|
42
|
+
const argv = require(`minimist`)( process.argv.slice(2) );
|
|
43
|
+
const log = new Log({ path: argv.path, context: `takedown` });
|
|
44
|
+
|
|
45
|
+
// 3. run
|
|
26
46
|
takedown();
|