@suffolklitlab/alkiln 5.13.3 → 5.13.4

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 (37) hide show
  1. package/.github/workflows/github_server.yml +7 -7
  2. package/.github/workflows/playground.yml +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/action.yml +70 -28
  5. package/action_for_github_server/action.yml +61 -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 +320 -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 +3 -1
  12. package/docs/decisions/reports_and_logs_2024_08_11.md +161 -0
  13. package/docs/kinds_of_errors.md +26 -0
  14. package/lib/docassemble/docassemble_api_interface.js +77 -51
  15. package/lib/docassemble/server_install.js +32 -9
  16. package/lib/docassemble/setup.js +40 -25
  17. package/lib/docassemble/takedown.js +33 -10
  18. package/lib/parse.js +36 -0
  19. package/lib/run_cucumber.js +115 -36
  20. package/lib/scope.js +60 -75
  21. package/lib/steps.js +70 -42
  22. package/lib/utils/Log.js +982 -0
  23. package/lib/utils/files.js +18 -11
  24. package/lib/utils/get_sources_paths.js +162 -0
  25. package/lib/utils/parse.js +1 -0
  26. package/lib/utils/proccess_command_line_args.js +267 -0
  27. package/lib/utils/reports.js +64 -17
  28. package/lib/utils/session_vars.js +34 -21
  29. package/lib/utils/time.js +44 -0
  30. package/package.json +1 -1
  31. package/tests/log_codes/check_codes.sh +2 -1
  32. package/tests/log_codes/log_code_expected_instances.txt +33 -9
  33. package/tests/unit_tests/getAllFields.test.js +5 -0
  34. package/tests/unit_tests/getMatchingRows.test.js +5 -0
  35. package/tests/unit_tests/log.test.js +581 -0
  36. package/tests/unit_tests/normalizeTable.test.js +5 -0
  37. package/lib/utils/log.js +0 -96
@@ -3,19 +3,22 @@ const fg = require('fast-glob');
3
3
  const path = require('path');
4
4
  require('dotenv').config();
5
5
 
6
- /**
7
- * This code assumes that this module is run as part of a GitHub Action. If the
8
- * customer is running it as a CLI tool, then they won't get useful messages yet.
9
- */
10
-
11
- /* This file provides user info variables. E.g. server address. They're either
12
- * `process.env` vars or vars that have been built from `process.env` vars.
13
- * It is meant to avoid duplication, make testing easier, and leave room for
14
- * future manipulation. No other file should need to use `process.env`.
15
- *
16
- * We have a bunch of `.get_foo()` functions partly because it makes the code
17
- * much easier to test.
18
- */
6
+ /** WARNING: Avoid importing other project files into here. Every other
7
+ * file should be able to reference this one without worrying
8
+ * about circular references.
9
+ * */
10
+
11
+ /** This file provides user info variable getters and setters.
12
+ * E.g. server address. It often uses `process.env` vars or
13
+ * vars that have been built from `process.env` vars. It is
14
+ * meant to avoid duplication, make testing easier, and leave
15
+ * room for future manipulation.
16
+ *
17
+ * No other file should need to use `process.env`.
18
+ *
19
+ * We use `.get_foo()` functions partly because it makes the code
20
+ * easier to test.
21
+ * */
19
22
 
20
23
  const session_vars = {};
21
24
 
@@ -136,7 +139,7 @@ session_vars.save_project_name = function ( project_name ) {
136
139
  let file = fs.writeFileSync( runtime_config_path, JSON.stringify( json, null, 2 ) );
137
140
 
138
141
  if ( session_vars.get_debug() ) {
139
- console.log( `🐞 ALK0036 DEBUG: Stored name of Project "${ project_name }" locally.` );
142
+ console.debug( `🐛 ALK0036 DEBUG: Stored name of Project "${ project_name }" locally.` );
140
143
  }
141
144
  return file;
142
145
  }; // Ends save_project_name()
@@ -148,7 +151,7 @@ session_vars.get_project_name = function () {
148
151
  }
149
152
  let json = JSON.parse( fs.readFileSync( runtime_config_path ));
150
153
  let project_name = json[ project_name_key ] || null;
151
- if ( session_vars.get_debug() ) { console.log( `🐞 ALK0037 DEBUG: Project name from file is "${ project_name }".` ); }
154
+ if ( session_vars.get_debug() ) { console.debug( `🐛 ALK0037 DEBUG: Project name from file is "${ project_name }".` ); }
152
155
  return project_name;
153
156
  }; // Ends get_project_name()
154
157
 
@@ -172,7 +175,11 @@ session_vars.delete_project_name = function () {
172
175
  // const file_storing_artifact_path = `_alkiln_test_artifacts_dir_name.json`;
173
176
  const artifacts_path_key = `artifacts_path`;
174
177
  session_vars.save_artifacts_path_name = function ( path_name ) {
175
- /* Save a key with the name of the current artifacts folder in case it doesn't exist. */
178
+ /** Save a key with the name of the current artifacts folder
179
+ * in case it doesn't exist. Should we create the path in here
180
+ * if it doesn't exist? Should we reserve this file for getting
181
+ * and setting?
182
+ * */
176
183
  return session_vars.save_runtime_config_var({ key: artifacts_path_key, value: path_name });
177
184
  }; // Ends save_artifacts_path_name()
178
185
  session_vars.get_artifacts_path_name = function () {
@@ -181,20 +188,26 @@ session_vars.get_artifacts_path_name = function () {
181
188
  }; // Ends get_artifacts_path_name()
182
189
 
183
190
 
191
+ /** We use `da_install_method` for temp server vs. author's account (Playground)
192
+ * on author's server. For example, for deciding how to get the url of a
193
+ * server. See docs on 4 environments. TODO: Change `_method` to `_location`?
194
+ * */
184
195
  const install_method_key = `da_install_method`;
185
196
  session_vars.save_install_method = function ( install_method ) {
186
- /* Save a key with the name of the current artifacts folder in case it doesn't exist. */
197
+ /** Save a key with the name of the current artifacts folder in case it
198
+ * doesn't exist. */
187
199
  return session_vars.save_runtime_config_var({ key: install_method_key, value: install_method });
188
200
  }; // Ends save_install_method()
189
201
  session_vars.get_install_method = function () {
190
- /* Get the name of the current install method. */
202
+ /** Get the name of the current install method. */
191
203
  return session_vars.get_runtime_config_var( install_method_key );
192
204
  }; // Ends get_install_method()
193
205
 
194
206
 
195
207
  const repo_folder_key = `da_repo_folder_name`;
196
208
  session_vars.save_repo_folder_name = function (repo_folder_name) {
197
- /** Save a key with the name of the main package folder in the repository. */
209
+ /** Save a key with the name of the main package folder in the repository. For
210
+ * example, EvictionDefense in the docassemble-EvictionDefense folder. */
198
211
  return session_vars.save_runtime_config_var({ key: repo_folder_key, value: repo_folder_name });
199
212
  }; // Ends session_vars.save_repo_folder_name()
200
213
  session_vars.get_repo_folder_name = function () {
@@ -226,7 +239,7 @@ session_vars.save_runtime_config_var = function ({ key, value }) {
226
239
  let file = fs.writeFileSync( runtime_config_path, JSON.stringify( json, null, 2 ) );
227
240
 
228
241
  if ( session_vars.get_debug() ) {
229
- console.log( `🐞 ALK0040 DEBUG: Stored runtime config var "${key}" locally as "${value}".` );
242
+ console.debug( `🐛 ALK0040 DEBUG: Stored runtime config var "${key}" locally as "${value}".` );
230
243
  }
231
244
  return file;
232
245
  }; // Ends session_vars.save_runtime_config_var()
@@ -242,7 +255,7 @@ session_vars.get_runtime_config_var = function ( key ) {
242
255
  let json = JSON.parse( fs.readFileSync( runtime_config_path ));
243
256
  let value = json[ key ];
244
257
  if ( session_vars.get_debug() ) {
245
- console.log( `🐞 ALK0041 DEBUG: Runtime config var "${key}" is "${value}".` );
258
+ console.debug( `🐛 ALK0041 DEBUG: Runtime config var "${key}" is "${value}".` );
246
259
  }
247
260
 
248
261
  return value;
package/lib/utils/time.js CHANGED
@@ -24,3 +24,47 @@ time.waitForTimeout = function( milliseconds ) {
24
24
  setTimeout(resolve, milliseconds);
25
25
  });
26
26
  };
27
+ time.sleep = time.waitForTimeout;
28
+ time.wait = time.waitForTimeout;
29
+
30
+ time.filename_date = function() {
31
+ /** Return the current timestamp in a human-readable
32
+ * filename-safe format to match the workflow artifact
33
+ * date format.
34
+ * See https://stackoverflow.com/a/48729396/14144258 and https://stackoverflow.com/a/6040556/14144258
35
+ */
36
+ // let date = new Date(); // now
37
+ // let day = ("0" + date.getUTCDate()).slice(-2);
38
+ // let month = ("0" + (date.getUTCMonth() + 1)).slice(-2);
39
+ // let year = date.getUTCFullYear();
40
+ // let hours = ("0" + date.getUTCHours()).slice(-2);
41
+ // let mins = ("0" + date.getUTCMinutes()).slice(-2);
42
+ // let secs = ("0" + date.getUTCSeconds()).slice(-2);
43
+
44
+ let dt = time.get_time_parts();
45
+ let safe_date = `${ dt.y }-${ dt.mon }-${ dt.d } at ${ dt.h }h${ dt.min }m${ dt.s }sUTC`;
46
+ return safe_date;
47
+ }; // Ends time.filename_date()
48
+
49
+ time.log_date = function () {
50
+ /** Return the current timestamp in a human-readable
51
+ * more compact log format.
52
+ * See https://stackoverflow.com/a/48729396/14144258 and https://stackoverflow.com/a/6040556/14144258
53
+ */
54
+ let dt = time.get_time_parts();
55
+ let short_date = `${ dt.y }-${ dt.mon }-${ dt.d } ${ dt.h }:${ dt.min }:${ dt.s }UTC`;
56
+ return short_date;
57
+ }; // Ends time.log_date()
58
+
59
+ time.get_time_parts = function () {
60
+ /** Get all the parts of the date as numbers. */
61
+ let date = new Date(); // now
62
+ return ({
63
+ y: date.getUTCFullYear(),
64
+ mon: ("0" + (date.getUTCMonth() + 1)).slice(-2),
65
+ d: ("0" + date.getUTCDate()).slice(-2),
66
+ h: ("0" + date.getUTCHours()).slice(-2),
67
+ min: ("0" + date.getUTCMinutes()).slice(-2),
68
+ s: ("0" + date.getUTCSeconds()).slice(-2),
69
+ });
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suffolklitlab/alkiln",
3
- "version": "5.13.3",
3
+ "version": "5.13.4",
4
4
  "description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -55,7 +55,8 @@ fi
55
55
 
56
56
  # removed and are no longer used. Syntax used works with GitHub cli - [[:digit:]]
57
57
  # https://stackoverflow.com/a/6901221
58
- instances=$(find "$where_to_look" -type f ! -name "check_codes.sh" ! -name "CONTRIBUTING.md" ! -name "$expected_instances_file" ! -name "debug_log.txt" ! -name "cucumber-report.txt" ! -path "*/node_modules/*" ! -path "*/ALKilnTests/*" ! -path "*/alkiln-*/*" ! -path "*/_alkiln*/*" -print0 | xargs -0 -P 4 grep -0 -ro 'ALK[[:digit:]][[:digit:]][[:digit:]][[:digit:]]' | grep -v -- '--' )
58
+ # Exclude files and paths
59
+ instances=$(find "$where_to_look" -type f ! -name "CONTRIBUTING.md" ! -name "$expected_instances_file" ! -name "debug_log.txt" ! -name "cucumber-report.txt" ! -path "*/tests/*" ! -path "*/node_modules/*" ! -path "*/ALKilnTests/*" ! -path "*/alkiln-*/*" ! -path "*/_alkiln*/*" ! -path "*/docs/decisions/*" ! -path "*/\.*" -print0 | xargs -0 -P 4 grep -0 -ro 'ALK[[:digit:]][[:digit:]][[:digit:]][[:digit:]]' | grep -v -- '--' )
59
60
 
60
61
  if [[ "$loudness" != "0" ]]; then
61
62
  total_instances=$(echo "$instances" | wc -l)
@@ -4,7 +4,11 @@ Why we need duplicate codes sometimes: GitHub actions sometimes don't have ways
4
4
 
5
5
  The script that tests the log codes will ignore this file (or any file with this name), and any file with these names: check_codes.sh, debug_log.txt, cucumber-report.txt. It will also ignore files in folders with these names:, node_modules, ALKilnTests, alkiln-*, _alkiln*. That list might get updated, so for an up-to-date list, always check the file check_codes.sh where we use `--exclude=` and such.
6
6
 
7
- ALK0000:8
7
+ Reasons for deletion:
8
+ 0053 - duplicate log
9
+ 0173 - redundant
10
+
11
+ ALK0000:0
8
12
  ALK0001:1
9
13
  ALK0002:2
10
14
  ALK0003:2
@@ -22,7 +26,7 @@ ALK0014:1
22
26
  ALK0015:1
23
27
  ALK0016:1
24
28
  ALK0017:1
25
- ALK0018:2
29
+ ALK0018:1
26
30
  ALK0019:2
27
31
  ALK0020:1
28
32
  ALK0021:1
@@ -33,10 +37,10 @@ ALK0025:1
33
37
  ALK0026:2
34
38
  ALK0027:2
35
39
  ALK0028:3
36
- ALK0029:1
40
+ ALK0029:2
37
41
  ALK0030:2
38
- ALK0031:1
39
- ALK0032:1
42
+ ALK0031:2
43
+ ALK0032:2
40
44
  ALK0033:1
41
45
  ALK0034:1
42
46
  ALK0035:1
@@ -57,7 +61,7 @@ ALK0049:1
57
61
  ALK0050:1
58
62
  ALK0051:1
59
63
  ALK0052:1
60
- ALK0053:1
64
+ ALK0053:0
61
65
  ALK0054:1
62
66
  ALK0055:1
63
67
  ALK0056:1
@@ -177,7 +181,7 @@ ALK0169:1
177
181
  ALK0170:1
178
182
  ALK0171:1
179
183
  ALK0172:1
180
- ALK0173:1
184
+ ALK0173:0
181
185
  ALK0174:1
182
186
  ALK0175:1
183
187
  ALK0176:1
@@ -185,7 +189,7 @@ ALK0177:1
185
189
  ALK0178:1
186
190
  ALK0179:1
187
191
  ALK0180:1
188
- ALK0181:1
192
+ ALK0181:0
189
193
  ALK0182:1
190
194
  ALK0183:1
191
195
  ALK0184:2
@@ -206,4 +210,24 @@ ALK0198:1
206
210
  ALK0199:1
207
211
  ALK0200:1
208
212
  ALK0201:1
209
- ALK0202:1
213
+ ALK0202:1
214
+ ALK0203:1
215
+ ALK0204:1
216
+ ALK0205:1
217
+ ALK0206:1
218
+ ALK0207:1
219
+ ALK0208:1
220
+ ALK0209:1
221
+ ALK0210:1
222
+ ALK0211:1
223
+ ALK0212:1
224
+ ALK0213:1
225
+ ALK0214:1
226
+ ALK0215:1
227
+ ALK0216:1
228
+ ALK0217:1
229
+ ALK0218:1
230
+ ALK0219:1
231
+ ALK0220:1
232
+ ALK0221:1
233
+ ALK0222:1
@@ -7,6 +7,11 @@ chai.use(deepEqualInAnyOrder);
7
7
  const html = require('./html.fixtures.js');
8
8
  const fields = require('./fields.fixtures.js');
9
9
  const scope = require('../../lib/scope.js');
10
+
11
+ const Log = require(`../../lib/utils/Log.js`);
12
+ const log = new Log({ path: `_alkiln-misc_artifacts/all_fields_${ Date.now() }`, context: `unit_tests getAllFields` });
13
+ scope.set_log({ log_obj: log });
14
+
10
15
  const getAllFields = scope.getAllFields;
11
16
 
12
17
  chai.config.truncateThreshold = 0
@@ -6,6 +6,11 @@ const tables = require('./tables.fixtures.js');
6
6
  const fields = require('./fields.fixtures.js');
7
7
  const matches = require('./matches.fixtures.js');
8
8
  const scope = require('../../lib/scope.js');
9
+
10
+ const Log = require(`../../lib/utils/Log.js`);
11
+ const log = new Log({ path: `_alkiln-misc_artifacts/matching_rows_${ Date.now() }`, context: `unit_tests getMatchingRows` });
12
+ scope.set_log({ log_obj: log });
13
+
9
14
  const getMatchingRows = scope.getMatchingRows;
10
15
  // Match state var instantiated in steps.js. TODO: Add tests for such rows.
11
16
  scope.row_needs_trigger_flag = `ALKiln: no trigger variable needed`;