@suffolklitlab/alkiln 5.13.2 → 5.13.3-feat-random

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.
Files changed (49) hide show
  1. package/.github/workflows/github_server.yml +7 -7
  2. package/.github/workflows/playground.yml +2 -1
  3. package/CHANGELOG.md +32 -1
  4. package/action.yml +89 -29
  5. package/action_for_github_server/action.yml +73 -29
  6. package/docs/4_environments.md +243 -0
  7. package/docs/artifacts_folder_name.md +135 -0
  8. package/docs/constrained_random_tests.md +254 -0
  9. package/docs/decisions/006_which_log_level_to_pick_2024_09_5.md +70 -0
  10. package/docs/decisions/007_getting_and_storing_logs.md +179 -0
  11. package/docs/decisions/move_runtime_config_to_sources_folder.md +5 -0
  12. package/docs/decisions/reports_and_logs_2024_08_11.md +161 -0
  13. package/docs/kinds_of_errors.md +26 -0
  14. package/docs/prioritize_constrained_random_tests.md +60 -0
  15. package/lib/docassemble/docassemble_api_interface.js +77 -51
  16. package/lib/docassemble/server_install.js +32 -9
  17. package/lib/docassemble/setup.js +41 -24
  18. package/lib/docassemble/takedown.js +33 -10
  19. package/lib/globals.js +10 -0
  20. package/lib/run_cucumber.js +155 -50
  21. package/lib/scope.js +101 -77
  22. package/lib/setup/TestGenerator.js +1745 -0
  23. package/lib/setup/artifacts.js +20 -0
  24. package/lib/setup/generate.js +42 -0
  25. package/lib/setup/get_Gherkin_AST.js +26 -0
  26. package/lib/setup/validate.js +89 -0
  27. package/lib/steps.js +176 -51
  28. package/lib/utils/Log.js +1132 -0
  29. package/lib/utils/_alkiln-constrained_random_tests_old.js +1727 -0
  30. package/lib/utils/files.js +18 -11
  31. package/lib/utils/get_error_stacks.js +16 -0
  32. package/lib/utils/reports.js +95 -28
  33. package/lib/utils/session_vars.js +102 -73
  34. package/lib/utils/set_sources_paths.js +98 -0
  35. package/lib/utils/time.js +44 -0
  36. package/package.json +16 -8
  37. package/tests/log_codes/check_codes.sh +19 -14
  38. package/tests/log_codes/log_code_expected_instances.txt +69 -9
  39. package/tests/unit_tests/constrained_random_answers/invalid.fixtures.js +155 -0
  40. package/tests/unit_tests/constrained_random_answers/invalid.test.js +233 -0
  41. package/tests/unit_tests/constrained_random_answers/valid.fixtures.js +905 -0
  42. package/tests/unit_tests/constrained_random_answers/valid.test.js +521 -0
  43. package/tests/unit_tests/example_of_chai_test_lifecycle.js +78 -0
  44. package/tests/unit_tests/getAllFields.test.js +5 -0
  45. package/tests/unit_tests/getMatchingRows.test.js +5 -0
  46. package/tests/unit_tests/log.test.js +557 -0
  47. package/tests/unit_tests/normalizeTable.test.js +5 -0
  48. package/lib/utils/log.js +0 -96
  49. /package/docs/{expected_inernal_results.md → expected_internal_results.md} +0 -0
@@ -1,5 +1,5 @@
1
1
  const _da_REST = require('./docassemble_api_REST');
2
- const log = require('../utils/log');
2
+ const Log = require('../utils/Log');
3
3
  const session_vars = require('../utils/session_vars' );
4
4
  const time = require('../utils/time');
5
5
 
@@ -61,6 +61,10 @@ const time = require('../utils/time');
61
61
  let da_i = {};
62
62
  module.exports = da_i;
63
63
 
64
+ const context = `da api`;
65
+ const artifacts_path = session_vars.get_artifacts_path_name();
66
+ const log = new Log({ path: artifacts_path, context });
67
+
64
68
 
65
69
  // Constants
66
70
  const DEFAULT_MAX_REQUEST_MS = session_vars.get_setup_timeout_ms();
@@ -92,7 +96,9 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
92
96
 
93
97
  // Defaults
94
98
  let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
95
- log.info({ type: `da api`, code: `ALK0166`, pre: `Waiting for the docassemble server to respond. Will wait for ${ timeout/1000 } seconds at most.` });
99
+ log.info({ code: `ALK0166`, context, },
100
+ `Waiting for the docassemble server to respond. Will wait for ${ timeout/1000 } seconds at most.`
101
+ );
96
102
 
97
103
  try {
98
104
  let start_time = Date.now()
@@ -100,7 +106,9 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
100
106
  let response = await _da_REST.get_dev_id( timeout );
101
107
  let end_time = Date.now()
102
108
  if ( response && response.data && response.data.id ) {
103
- log.info({ type: `da api`, code: `ALK0167`, pre: `The docassemble server responded after ${ (end_time - start_time)/1000 } seconds.` });
109
+ log.info({ code: `ALK0167`, context, },
110
+ `The docassemble server responded after ${ (end_time - start_time)/1000 } seconds.`
111
+ );
104
112
  return false;
105
113
  }
106
114
 
@@ -109,17 +117,16 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
109
117
  if ( is_timeout_error( error ) ) {
110
118
  // Anything that's waiting for the server to not be busy does not want
111
119
  // to move forward without a free server.
112
- log.info({ type: `da api`, code: `ALK0168`, pre: `The docassemble server was still busy after ${ timeout/1000 } seconds.` });
120
+ log.info({ code: `ALK0168`, context, },
121
+ `The docassemble server was still busy after ${ timeout/1000 } seconds.`
122
+ );
113
123
  } else {
114
124
  // Not sure what to do for other errors. It could be a server
115
125
  // error, like an 'Access Denied' error, which should be handled.
116
- log.error({
117
- type: `da api`,
118
- code: `ALK0169`,
119
- pre: `Tried to check if the docassemble server was busy, but `
120
- + `ran into an unexpected error. The error didn't indicate a busy server, though. Error message:\n`
121
- + error
122
- });
126
+ log.warning({ code: `ALK0169`, context, },
127
+ `Checked if the server was busy and ran into a different error`,
128
+ error
129
+ );
123
130
  }
124
131
 
125
132
  throw error;
@@ -187,7 +194,7 @@ da_i.get_api_key_access_status = async function ({ timeout = null, api_key = nul
187
194
  * to allow for server request.
188
195
  */
189
196
 
190
- let auth_data = {
197
+ let auth_feedback = {
191
198
  codes: [ 1 ],
192
199
  has_auth: null,
193
200
  messages: [`API key authorization is not yet determined.`],
@@ -196,16 +203,16 @@ da_i.get_api_key_access_status = async function ({ timeout = null, api_key = nul
196
203
 
197
204
  // Skip this for tests run from ALKilnInThePlayground
198
205
  if ( session_vars.get_origin() === 'playground' ) {
199
- auth_data.codes.push( 2 );
200
- auth_data.messages.push( `API keys are unnecessary for tests run in the Playground.` );
206
+ auth_feedback.codes.push( 2 );
207
+ auth_feedback.messages.push( `API keys are unnecessary for tests run in the Playground.` );
201
208
  }
202
209
 
203
210
  if ( typeof api_key !== `string` ) {
204
- auth_data.codes.push( 3 );
205
- auth_data.messages.push( `The given API key is not a string. Type: ${ typeof api_key }`);
211
+ auth_feedback.codes.push( 3 );
212
+ auth_feedback.messages.push( `The given API key is not a string. Type: ${ typeof api_key }`);
206
213
  }
207
214
 
208
- if ( auth_data.codes.length === 1 ) {
215
+ if ( auth_feedback.codes.length === 1 ) {
209
216
  // Default timeouts
210
217
  timeout = timeout || DEFAULT_MAX_REQUEST_MS;
211
218
  try {
@@ -213,29 +220,31 @@ da_i.get_api_key_access_status = async function ({ timeout = null, api_key = nul
213
220
  api_key,
214
221
  server_url: session_vars.get_da_server_url(),
215
222
  });
216
- auth_data.has_auth = true;
217
- auth_data.codes = [ 6 ];
218
- auth_data.messages = [ `This API key has at least basic authorization on this server.` ];
223
+ auth_feedback.has_auth = true;
224
+ auth_feedback.codes = [ 6 ];
225
+ auth_feedback.messages = [ `This API key has at least basic authorization on this server.` ];
219
226
 
220
227
  } catch ( error ) {
221
- auth_data.error = error;
228
+ auth_feedback.error = error;
222
229
  if ( error.status === 403 ) {
223
- auth_data.has_auth = false;
224
- auth_data.codes = [ 4 ];
225
- auth_data.messages = [ `This API is unverified on this server. It is probably missing or has been deleted.` ];
230
+ auth_feedback.has_auth = false;
231
+ auth_feedback.codes = [ 4 ];
232
+ auth_feedback.messages = [ `This API is unverified on this server. It is probably missing or has been deleted.` ];
226
233
  } else {
227
234
  // Note on 404, non-existent key: 404 == 403 - Since we're using the
228
235
  // key itself to get its own info, if it doesn't exist, we'll get 403
229
- auth_data.codes = [ 5 ];
230
- auth_data.messages = [ `This API key threw a non-403 error.` ];
236
+ auth_feedback.codes = [ 5 ];
237
+ auth_feedback.messages = [ `This API key threw a non-403 error.` ];
231
238
  } // ends error status
232
239
  } // ends try
233
- } // ends auth_data.codes only has the first code
240
+ } // ends auth_feedback.codes only has the first code
234
241
 
235
- log.debug({ type: `da api info`, code: `ALK0202`,
236
- pre: `API key authentication info`, data: auth_data });
242
+ log.debug({ code: `ALK0202`, context, },
243
+ `API key - what happened during authentication:`,
244
+ auth_feedback
245
+ );
237
246
 
238
- return auth_data;
247
+ return auth_feedback;
239
248
  }; // Ends da_i.get_api_key_access_status()
240
249
 
241
250
  // node -e 'require("./lib/docassemble/docassemble_api_interface.js").delete_project( "create1" )'
@@ -247,16 +256,19 @@ da_i.delete_project = async function ( delete_options ) {
247
256
  let { timeout } = delete_options || { timeout: DEFAULT_MAX_REQUEST_MS };
248
257
 
249
258
  let project_name = session_vars.get_project_name()
250
- log.info({ type: `da api`, code: `ALK0170`, pre: `Trying to delete Project ${ project_name }` });
259
+ log.info({ code: `ALK0170`, context, },
260
+ `Trying to delete Project ${ project_name }`
261
+ );
251
262
 
252
263
  try {
253
264
  let response = await _da_REST.delete_project( timeout );
254
- log.info({ type: `da api`, code: `ALK0171`, pre: `Deleted Project "${ project_name }"` });
265
+ log.info({ code: `ALK0171`, context, },
266
+ `Deleted Project "${ project_name }"`
267
+ );
255
268
  } catch ( error ) {
256
- let msg = `Ran into an error when deleting Project "${ project_name }". See https://docassemble.org/docs/api.html#playground_delete_project.`
257
- log.error({ type: `da api`, code: `ALK0172`, pre: msg });
258
- log.debug({ type: `da api`, code: `ALK0173`, pre: msg });
259
- throw error;
269
+ log.throw({ code: `ALK0172`, context, error: error },
270
+ `Ran into an error when deleting Project "${ project_name }". See https://docassemble.org/docs/api.html#playground_delete_project.`
271
+ );
260
272
  }
261
273
 
262
274
  }; // Ends da_i.delete_project()
@@ -280,7 +292,9 @@ da_i.quietly_try_to_delete_interviews = async function ({ interviews = {}, api_k
280
292
  });
281
293
  responses.push( sub_responses );
282
294
  } else {
283
- log.debug({ type: `da api info`, code: `ALK0191`, pre: `There is no interview to delete.` });
295
+ log.debug({ code: `ALK0191`, context, },
296
+ `There is no interview to delete.`
297
+ );
284
298
  }
285
299
  }
286
300
  return responses;
@@ -295,9 +309,9 @@ da_i.quietly_delete_one_interview = async function ( timeout, { interview = {},
295
309
  let responses = [];
296
310
  for ( let api_key of api_keys ) {
297
311
  try {
298
- log.debug({ type: `da api info`, code: `ALK0188`,
299
- pre: `Trying to delete the interview with the id ${ interview.uid } and an API key.`
300
- });
312
+ log.debug({ code: `ALK0188`, context, },
313
+ `Trying to delete the interview with the id ${ interview.uid } and an API key.`
314
+ );
301
315
 
302
316
  // Actual work:
303
317
  let response = await _da_REST.delete_interview( timeout, {
@@ -306,13 +320,15 @@ da_i.quietly_delete_one_interview = async function ( timeout, { interview = {},
306
320
  });
307
321
  responses.push( response );
308
322
 
309
- log.debug({ type: `da api info`, code: `ALK0189`,
310
- pre: `No error when trying to delete interview ${ interview.uid } at ${ interview.i }.`
311
- });
323
+ log.debug({ code: `ALK0189`, context, },
324
+ `No error when trying to delete interview ${ interview.uid } at ${ interview.i }.`
325
+ );
312
326
  } catch ( error ) {
313
327
  error.interview = interview;
314
- let msg = `Error when deleting the interview. See https://docassemble.org/docs/api.html#session_delete.`
315
- log.debug({ type: `da api info`, code: `ALK0190`, pre: msg, data: error });
328
+ log.debug({ code: `ALK0190`, context, },
329
+ `Error when deleting the interview. See https://docassemble.org/docs/api.html#session_delete.`,
330
+ error
331
+ );
316
332
  }
317
333
  } // ends for api keys
318
334
  return responses;
@@ -347,7 +363,9 @@ da_i.get_interview = async function ({ interview = {}, api_keys = [], options =
347
363
  if ( interview && interview.uid ) {
348
364
  for ( let api_key of api_keys ) {
349
365
  try {
350
- log.debug({ type: `da api info`, code: `ALK0192`, pre: `Trying to get the interview with the id ${ interview.uid } and an API key.` });
366
+ log.debug({ code: `ALK0192`, context, },
367
+ `Trying to get the interview with the id ${ interview.uid } and an API key.`
368
+ );
351
369
 
352
370
  // Actual work:
353
371
  let response = await _da_REST.get_interview( timeout, {
@@ -356,20 +374,28 @@ da_i.get_interview = async function ({ interview = {}, api_keys = [], options =
356
374
  });
357
375
 
358
376
  if ( response && response.data && response.data.items && response.data.items[0] && response.data.items[0].session ) {
359
- log.debug({ type: `da api info`, code: `ALK0193`, pre: `Status ${ response.status }. Got ${ response.data.items[0].session }.`});
377
+ log.debug({ code: `ALK0193`, context, },
378
+ `Status ${ response.status }. Got ${ response.data.items[0].session }.`
379
+ );
360
380
  return response.data.items[0];
361
381
  } else {
362
- log.debug({ type: `da api info`, code: `ALK0194`, pre: `Status ${ response.status }. Cannot find ${ interview.uid }`});
382
+ log.debug({ code: `ALK0194`, context, },
383
+ `Status ${ response.status }. Cannot find ${ interview.uid }`
384
+ );
363
385
  }
364
386
 
365
387
  } catch ( error ) {
366
388
  error.interview = interview;
367
- let msg = `${ 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.`
368
- log.debug({ type: `da api info`, code: `ALK0195`, pre: msg, data: error });
389
+ log.debug({ code: `ALK0195`, context, },
390
+ `${ 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.`,
391
+ error
392
+ );
369
393
  }
370
394
  } // ends for api_keys
371
395
  } else {
372
- log.debug({ type: `da api info`, code: `ALK0196`, pre: `There is no interview to get.` });
396
+ log.debug({ code: `ALK0196`, context, },
397
+ `There is no interview to get.`
398
+ );
373
399
  }
374
400
 
375
401
  return null;
@@ -1,10 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const session_vars = require('../utils/session_vars');
4
- const log = require('../utils/log');
4
+ const Log = require('../utils/Log');
5
5
  const fg = require('fast-glob');
6
6
 
7
+ const context = `server_install`;
8
+
7
9
  const server_install = async () => {
10
+ /** For packages we are installing on a temporary GitHub docassemble server.
11
+ *
12
+ * - Store that the package is being installed globally on a server as
13
+ * opposed to on a specific author's account (their Playground).
14
+ * - In the repo, find and store the path to directory that stores the
15
+ * package itself instead of the whole repo. For example, EvictionDefense
16
+ * in the docassemble-EvictionDefense repo.
17
+ * */
8
18
  session_vars.save_install_method(`server`);
9
19
 
10
20
  // Get path to folders inside repo main "docassemble" folder
@@ -23,20 +33,33 @@ const server_install = async () => {
23
33
  // Get names of all folders in repo "docassemble" folder
24
34
  let chosen_folder = folders[0];
25
35
  if ( folders.length === 0 ) {
26
- let msg = `There are 0 folders at ${path}. Stopping tests.`;
27
- log.error({ type: `setup`, code: `ALK0044`, data: msg })
28
- throw new ReferenceError( msg );
36
+ let msg = `ALKiln cannot find the package's files. There are 0 folders at "${ path }". Stopping tests.`;
37
+ log.throw({ code: `ALK0044`, context,
38
+ error: new ReferenceError( msg ) // no logs
39
+ });
29
40
  }
30
41
 
31
42
  if ( folders.length > 1 ) {
32
- log.warn({
33
- type: `setup`,
34
- code: `ALK0045`,
35
- data: `There are ${folders.length} folders at ${path}: "${folders.join('", "')}". ALKiln chose to use the folder "${chosen_folder}".`
36
- })
43
+ log.warn({ code: `ALK0045`, context, },
44
+ `There are ${ folders.length } folders at "${ path }": "${ folders.join('", "') }". ALKiln chose to use the folder "${ chosen_folder }".`
45
+ );
46
+ } else {
47
+ log.info({ code: `ALK0218`, context, },
48
+ `ALKiln found the package folder at "${ chosen_folder }".`
49
+ );
37
50
  }
38
51
 
39
52
  session_vars.save_repo_folder_name( chosen_folder );
40
53
  }; // Ends server_install();
41
54
 
55
+ // 1. session_vars - make sure all the required env vars exist
56
+ session_vars.validateEnvironment();
57
+
58
+ // 2. Prepare logs
59
+ // Local devs: This will be separate from your test paths
60
+ // unless you pass a `path` argument into the cucumber run command
61
+ const argv = require(`minimist`)(process.argv.slice(2));
62
+ const log = new Log({ path: argv.path, context, });
63
+
64
+ // 3. run
42
65
  server_install();
@@ -1,26 +1,35 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // TODO: Rename to playground_install?
3
+ // rename? install_authors_docassemble_interview_package_on_server
4
4
 
5
5
  const child_process = require(`child_process`);
6
6
 
7
- const log = require(`../utils/log`);
7
+ const Log = require(`../utils/Log`);
8
8
  const session_vars = require(`../utils/session_vars` );
9
+ const files = require(`../utils/files` );
10
+ const time = require(`../utils/time` );
11
+
12
+ const context = `setup`;
9
13
 
10
14
  const setup = async () => {
11
- /** In the docassemble testing account identified by the
12
- * DOCASSEMBLE_DEVELOPER_API_KEY secret, create a new Project,
13
- * pull code into that project, and, if needed, wait for the
14
- * server to reload.
15
- */
15
+ /** This is for a package being installed in an author's account (Playground)
16
+ * on their docassemble server. Using the author's
17
+ * DOCASSEMBLE_DEVELOPER_API_KEY secret, create a new Project, pull code
18
+ * into that project, and, if needed, wait for the server to reload.
19
+ */
16
20
 
17
21
  // Make and save project name
18
22
  let project_name = session_vars.get_project_base_name().replace(/[^A-Za-z0-9]/g, '') + `${Date.now()}`;
19
23
  session_vars.save_project_name( project_name );
20
24
 
21
- log.info({ type: `setup`, code: `ALK0046`, pre: `Starting to upload this package to `
25
+ const starting_msg = `Starting to upload this package to `
22
26
  + `a new Project called ${project_name} in the Playground `
23
- + `of your server's testing account. It may take a couple of minutes.` });
27
+ + `of your server's testing account. It may take a couple of minutes.`;
28
+ log.info({ code: `ALK0046`, context, },
29
+ starting_msg
30
+ );
31
+
32
+ // TODO: 1. Start listening to the normal console here (for debug logging)
24
33
 
25
34
  // dainstall . --apiurl https://site.org --apikey $API_KEY --playground --project=name
26
35
  // I think this won't run on windows? Why do I think this? Where on the
@@ -34,29 +43,37 @@ const setup = async () => {
34
43
  `--playground`, `--project=${ project_name }`
35
44
  ],
36
45
  // Prints messages from the process to the console while it's running
46
+ // result.stderr, result.stdout, etc. will be `null`
37
47
  { stdio: 'inherit', }
38
48
  );
39
49
 
40
- // 403 is invalid API key, but I'm not sure how to output
41
- // the response to find out the error code
50
+ // TODO: 2. Stop listening to the normal console here
42
51
 
52
+ // 403 is invalid API key, but I'm not sure how to output
53
+ // the response to find out the error code. stderr is `null`.
43
54
  if ( result.status !== 0 ) {
44
- log.error({
45
- type: `setup`,
46
- code: `ALK0047`,
47
- pre: `Status code ${ result.status }. Could not dainstall this package on your server. See above for more details.`
48
- });
49
- throw(result.stderr);
55
+ const install_err_msg = `Status code ${ result.status }. Could not `
56
+ + `dainstall this package on your server. See above for more details.`;
57
+ log.throw({ code: `ALK0047`, context,
58
+ before: `☝️ ☝️ ☝️ Error data ☝️ ☝️ ☝️\n`,
59
+ error: `Error while installing project` },
60
+ install_err_msg
61
+ );
50
62
  }
51
63
 
52
- log.success({
53
- type: `setup`,
54
- code: `ALK0048`,
55
- pre: `ALKiln created a Project in your Playground named "${ project_name }"!`
56
- });
64
+ log.success({ code: `ALK0048`, context, },
65
+ `ALKiln created a Project in your Playground named "${ project_name }"!`
66
+ );
57
67
  }; // Ends setup();
58
68
 
59
-
60
- // Before everything, make sure all the required env vars exist
69
+ // 1. session_vars - make sure all the required env vars exist
61
70
  session_vars.validateEnvironment();
71
+
72
+ // 2. Prepare logs
73
+ // Local devs: This will be separate from your test paths unless you pass a
74
+ // `path` argument into the cucumber run command
75
+ const argv = require(`minimist`)(process.argv.slice(2));
76
+ const log = new Log({ path: argv.path, context, });
77
+
78
+ // 3. run
62
79
  setup();
@@ -1,26 +1,49 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const da_i = require('./docassemble_api_interface');
4
- const log = require('../utils/log');
5
- const session_vars = require('../utils/session_vars' );
4
+ const session_vars = require('../utils/session_vars');
5
+ const Log = require('../utils/Log');
6
+
7
+ const context = `takedown`;
6
8
 
7
9
  const takedown = async () => {
8
- /* In the docassemble testing account identified by the
9
- * DOCASSEMBLE_DEVELOPER_API_KEY secret, delete the
10
- * Project created for this test.
11
- * For local development, clean up project name file. */
12
- log.info({ type: `takedown`, code: `ALK0177`, pre: `Trying to remove the docassemble Project from the testing account.` });
10
+ /** In the docassemble testing account identified by the
11
+ * DOCASSEMBLE_DEVELOPER_API_KEY secret, delete the Project created for this
12
+ * test. For local development, clean up Project name in the runtime_config
13
+ * file.
14
+ * */
15
+ log.info({ code: `ALK0177`, context, },
16
+ `Trying to remove the docassemble Project from the testing account.`
17
+ );
13
18
  // Explicit try-catch prevents "Unhandled promise rejection error"
14
19
  // avoids showing confusing node errors to users that they shouldn't have to fix
15
20
  try {
16
21
  await da_i.delete_project();
17
22
  session_vars.delete_project_name();
18
- log.success({ type: `takedown`, code: `ALK0178`, pre: `Test takedown has finished successfully!` });
23
+ log.info({ code: `ALK0178`, context, },
24
+ `Test takedown finished successfully!`
25
+ );
19
26
  } catch (error) {
20
- log.error({type: `takedown`, code: `ALK0179`, pre: `Could not delete project`, data: JSON.stringify(error, null, 4)})
21
- // we don't re-throw the exception, so make sure to exit with 1 to let GitHub Actions know the script failed
27
+ log.throw({ code: `ALK0179`, context, error: error },
28
+ `Unable to delete project`,
29
+ );
30
+ // we don't re-throw the exception, so make sure to exit
31
+ // with 1 to let GitHub Actions know the script failed
22
32
  process.exitCode = 1;
23
33
  }
34
+
35
+ // TODO: ? Build the final setup, run, & takedown verbose log
36
+ // file in here. Add to it in the GitHub action ?
24
37
  };
25
38
 
39
+ // 1. session_vars - make sure all the required env vars exist
40
+ session_vars.validateEnvironment();
41
+
42
+ // 2. Prepare logs
43
+ // Local devs: This will be separate from your test artifacts paths unless you
44
+ // pass a `path` argument into the `cucumber` run command
45
+ const argv = require(`minimist`)( process.argv.slice(2) );
46
+ const log = new Log({ path: argv.path, context, });
47
+
48
+ // 3. run
26
49
  takedown();
package/lib/globals.js ADDED
@@ -0,0 +1,10 @@
1
+ let globals = {
2
+ // File name prefix ALKiln can use to identify random answer generator files
3
+ generators_prefix: `alkiln_random`,
4
+ generated_files_folder_name: `_alkiln_generated`,
5
+ }
6
+
7
+ module.exports = globals;
8
+
9
+ // Would this be clearer as a config file instead?
10
+ // If not, change name to `constants`?