@suffolklitlab/alkiln 5.12.0 → 5.13.0-logs1

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 (38) hide show
  1. package/.env.example +29 -0
  2. package/.github/workflows/github_server.yml +59 -12
  3. package/.github/workflows/playground.yml +11 -4
  4. package/CHANGELOG.md +41 -1
  5. package/CONTRIBUTING.md +98 -83
  6. package/README.md +1 -1
  7. package/action.yml +67 -29
  8. package/action_for_github_server/action.yml +59 -31
  9. package/docs/decisions/006_which_log_level_to_pick_2024_09_5.md +46 -0
  10. package/docs/decisions/adopt_architectural_decision_records.md +58 -0
  11. package/docs/decisions/detect_sign_in.md +124 -0
  12. package/docs/decisions/pdfjs_version_2024_08_08.md +18 -0
  13. package/docs/decisions/reports_and_logs_2024_08_11.md +141 -0
  14. package/docs/decisions/update_puppeteer_2024_07_28.md +62 -0
  15. package/docs/story_tables.md +1 -1
  16. package/lib/docassemble/docassemble_api_REST.js +67 -1
  17. package/lib/docassemble/docassemble_api_interface.js +225 -18
  18. package/lib/docassemble/server_install.js +23 -9
  19. package/lib/docassemble/setup.js +33 -20
  20. package/lib/docassemble/takedown.js +27 -7
  21. package/lib/run_cucumber.js +83 -33
  22. package/lib/scope.js +222 -82
  23. package/lib/steps.js +206 -62
  24. package/lib/utils/files.js +8 -6
  25. package/lib/utils/log.js +477 -84
  26. package/lib/utils/reports.js +14 -5
  27. package/lib/utils/session_vars.js +25 -18
  28. package/lib/utils/time.js +44 -0
  29. package/npm-shrinkwrap.json +635 -193
  30. package/package.json +8 -8
  31. package/setup.py +1 -1
  32. package/tests/log_codes/check_codes.sh +163 -108
  33. package/tests/log_codes/log_code_expected_instances.txt +213 -0
  34. package/tests/unit_tests/getAllFields.test.js +5 -0
  35. package/tests/unit_tests/getMatchingRows.test.js +5 -0
  36. package/tests/unit_tests/log.test.js +20 -0
  37. package/tests/unit_tests/normalizeTable.test.js +5 -0
  38. package/tests/log_codes/deleted_codes.json +0 -8
@@ -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 log = require(`../utils/log`);
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
- log.info({ type: `setup`, code: `ALK0046`, pre: `Starting to upload this package to `
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
- // 403 is invalid API key, but I'm not sure how to output
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
- 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);
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
- type: `setup`,
54
- code: `ALK0048`,
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 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
6
 
7
7
  const takedown = async () => {
8
- /* In the docassemble testing account identified by the
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({ type: `takedown`, code: `ALK0177`, pre: `Trying to remove the docassemble Project from the testing account.` });
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.success({ type: `takedown`, code: `ALK0178`, pre: `Test takedown has finished successfully!` });
20
+ log.info({ code: `ALK0178`, context: `takedown`, },
21
+ `Test takedown finished successfully!`
22
+ );
19
23
  } 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
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();
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const fs = require('fs');
4
+ const path = require(`path`);
4
5
  const cucumber_api = require('@cucumber/cucumber/api');
5
6
 
6
- const log = require('./utils/log'); // These always log in the console
7
+ const Log = require('./utils/log');
7
8
  const session_vars = require('./utils/session_vars');
8
9
 
9
10
  const SUMMARY_FILENAME = `cucumber-report.txt`;
10
11
 
12
+
11
13
  function build_config( command_args ) {
12
14
  // Turn all the paths to the sources folders into paths to the feature files
13
15
  let sources_paths = session_vars.get_sources_paths();
@@ -52,11 +54,14 @@ function build_config( command_args ) {
52
54
  }; // Ends build_config()
53
55
 
54
56
 
55
- (async function main() {
57
+ async function main() {
56
58
  /** Create the cucumber config, run the tests, create and
57
59
  * manipluate the output. */
60
+
58
61
  const environment = { cwd: process.cwd() };
59
- log.info({ type: `run`, code: `ALK0049`, pre: `environment`, data: environment });
62
+ log.info({ code: `ALK0049`, context: `pre_run environment` },
63
+ environment
64
+ );
60
65
 
61
66
  // We'll use the user info to construct the possible paths to /sources
62
67
  let id = session_vars.get_user_id();
@@ -64,8 +69,9 @@ function build_config( command_args ) {
64
69
  let project = session_vars.get_user_project_name();
65
70
 
66
71
  // process.argv is a list of strings of commands and args.
67
- // If using `npm run cucumber`, use `--` before `--sources=./foo`
68
- let argv = require(`minimist`)( process.argv.slice(2), {
72
+ // If using `npm run cucumber` (as opposed to the bin commands),
73
+ // use `--` before `--sources=./foo`
74
+ const argv = require(`minimist`)( process.argv.slice(2), {
69
75
  default: {
70
76
  sources: [
71
77
  `./docassemble/*/data/sources`, // In GitHub folder
@@ -84,35 +90,45 @@ function build_config( command_args ) {
84
90
  let one_dir_exists = session_vars.set_sources_paths( sources_list );
85
91
  if ( !one_dir_exists ) {
86
92
  // If we don't throw, it'll be more confusing when no tests run
87
- let msg = `ALKiln can't find your "sources" folder(s). See above for details.`;
88
- let code = `ALK0050`
89
- log.error({ type: `run`, code: code, pre: msg });
90
- throw new ReferenceError(`🤕 ${ code } run ERROR: ${ msg }`);
93
+ log.throw({ code: `ALK0050`, context: `pre_run`,
94
+ error: new ReferenceError(
95
+ `ALKiln can't find your "sources" folder(s). See above for details.`
96
+ ),
97
+ });
91
98
  }
92
99
 
93
100
  const { runConfiguration } = await cucumber_api.loadConfiguration({
94
101
  provided: build_config( argv ),
95
102
  }, environment);
96
-
97
- log.info({ type: `run`, code: `ALK0051`, pre: `runConfiguration`, data: runConfiguration });
98
-
99
- var path = require(`path`);
100
- var codeDir = path.dirname(require.main.filename);
101
- log.info({ type: `run`, code: `ALK0052`, pre: `working directory`, data: codeDir });
103
+ log.info({ code: `ALK0051`, context: `pre_run config`, },
104
+ runConfiguration
105
+ );
106
+
107
+ const codeDir = path.dirname(require.main.filename);
108
+ log.info({ code: `ALK0052`, context: `pre_run directory`, },
109
+ codeDir, `\n\n`
110
+ );
102
111
  const support = await cucumber_api.loadSupport({ support: {
103
112
  requireModules: [ `${ codeDir }/index.js` ],
104
113
  requirePaths: [ `${ codeDir }/index.js` ],
105
114
  importPaths: [],
106
115
  }, sources: {paths: []}}, environment);
107
116
 
108
- log.info({ type: `run`, code: `ALK0053`, pre: `working directory`, data: codeDir });
109
- log.info({ type: `plain`, pre: `\n\n` });
110
-
117
+ // ====================
118
+ // Run
119
+ // ====================
111
120
  const { success } = await cucumber_api.runCucumber({...runConfiguration, support});
121
+ // ====================
122
+
112
123
  if ( success ) {
113
- log.success({ type: `run`, code: `ALK0054`, pre: `Tests succeeded!` });
124
+ log.success({ code: `ALK0054`, context: `post_run`, },
125
+ `Tests succeeded!`
126
+ );
114
127
  } else {
115
- log.error({ type: `run`, code: `ALK0055`, pre: `The test run ran into something unexpected. Look above for more details.` });
128
+ // Don't want to throw error here, so don't pass error object
129
+ log.warn({ code: `ALK0055`, context: `post_run`, },
130
+ `The tests ran into something unexpected. Look above for more details.`
131
+ );
116
132
  }
117
133
  // Custom exit code. May overlap with other systems.
118
134
  // Best info I've found via stack overflow: https://tldp.org/LDP/abs/html/exitcodes.html
@@ -122,30 +138,64 @@ function build_config( command_args ) {
122
138
  // This is hardcoded information from `provide_config` above.
123
139
  // This code isn't used for anything other than detecting and removing color codes.
124
140
  let summary_file_name = SUMMARY_FILENAME;
125
- fs.readFile(summary_file_name, 'utf8', (err, text) => {
126
- if (err) {
127
- log.error({ type: `internal run`, code: `ALK0056`, pre: `Failed to read cucumber report`, data: err });
141
+ fs.readFile(summary_file_name, 'utf8', (read_error, text) => {
142
+ if ( read_error ) {
143
+ // Something else will probably show an error that's more relevant
144
+ log.warn({ code: `ALK0056`, context: `post_run error`, },
145
+ `Failed to read cucumber report`, read_error
146
+ );
128
147
  return;
129
148
  }
130
149
 
131
150
  // Replace terminal color codes, if present
132
151
  // https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#colors--graphics-mode
133
152
  text = text.replace(/\x1b\[[0-9][0-9]?[0-9]?m/g, '');
134
-
135
- // Put it in the correct file in the correct folder
136
- let artifacts_path = session_vars.get_artifacts_path_name();
153
+ // Add to the debug file
137
154
  try {
138
- fs.appendFileSync( `${ artifacts_path }/${ log.debug_log_file }`, `\n\n${text}`);
155
+ // fs.appendFileSync( `${ artifacts_path }/${ log.debug_log_file }`, `\n\n${text}`);
156
+ log.debug({ code: `ALK0216`, context: `post_run`, },
157
+ `\n\n`, text
158
+ );
139
159
  } catch ( error ) {
140
- log.info({ type: `internal run`, code: `ALK0182`, pre: `Something probably went wrong earlier. Look above for more details, but here's more info just in case: ALKiln was unable to write to ${ artifacts_path }/${ log.debug_log_file }.`, data: error });
160
+ log.warn({ code: `ALK0182`, context: `post_run error`, },
161
+ `Something probably went wrong earlier. Look above for more details. Problem when writing to ${ log.path }/${ log.debug_log_filename }.`,
162
+ error
163
+ );
141
164
  }
165
+
166
+ // Add to the non-passed test output file
142
167
  try {
143
- // Add to a unexpected results file when tests themselves fail
168
+ // Save only non-passing test output to cut out cruft.
169
+ // cucumber only outputs non-success details anyway.
170
+ // Our reports only non-passing tests to this file.
144
171
  if ( exitCode === 50 ) {
145
- fs.appendFileSync( `${ artifacts_path }/${ log.unexpected_filename }`, `\n\n${ text }` );
172
+ // fs.appendFileSync( `${ log.path }/${ Log.unexpected_filename }`, `\n\n${ text }` );
173
+ log.unexpected({ text });
146
174
  }
147
- } catch ( error ) {
148
- log.info({ type: `internal run`, code: `ALK0181`, pre: `Something probably went wrong earlier. Look above for more details, but here's more info just in case: ALKiln was unable to write to ${ artifacts_path }/${ log.unexpected_filename }.`, data: error });
175
+ } catch ( unexpected_file_error ) {
176
+ console.warn(
177
+ `🔎 ALK0181 internal WARNING: Something probably went wrong earlier. Problem when writing to ${ log.path }/${ log.unexpected_filename }`,
178
+ unexpected_file_error
179
+ );
149
180
  }
181
+
182
+ return;
150
183
  });
151
- })();
184
+ }
185
+
186
+
187
+ // 1. session_vars - make sure all the required env vars exist
188
+ session_vars.validateEnvironment();
189
+
190
+ // 2. Prepare logs
191
+ // process.argv is a list of strings of commands and args.
192
+ // If using `npm run cucumber` (as opposed to the bin commands),
193
+ // use `--` before `--sources=./foo`
194
+ const argv = require(`minimist`)( process.argv.slice(2) );
195
+ // The artifacts folder might be getting created for the first
196
+ // time right here. The tests themselves should avoid creating
197
+ // their own file.
198
+ const log = new Log({ path: argv.path, context: `run` });
199
+
200
+ // 3. run
201
+ main();