@suffolklitlab/alkiln 5.12.0-delete6 → 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.
- package/.env.example +29 -0
- package/.github/workflows/github_server.yml +11 -9
- package/.github/workflows/log_code_tests.yml +0 -2
- package/.github/workflows/playground.yml +7 -5
- package/CHANGELOG.md +30 -5
- package/CONTRIBUTING.md +98 -83
- package/action.yml +66 -28
- package/action_for_github_server/action.yml +59 -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/lib/docassemble/docassemble_api_interface.js +63 -34
- 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 +81 -33
- package/lib/scope.js +152 -79
- package/lib/steps.js +84 -51
- 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 +6 -6
- 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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Leave pdfjs at its current version
|
|
2
|
+
|
|
3
|
+
## Context and Problem Statement
|
|
4
|
+
|
|
5
|
+
pdfjs has a security vulnerability (that does not affect us) where malicious PDFs can inject code into an unsuspecting project and cause havoc.
|
|
6
|
+
|
|
7
|
+
Our users are downloading and manipulating their own PDFs. We will assume they're not putting malicious code into their PDFs.
|
|
8
|
+
|
|
9
|
+
The update changes pdfjs .js files to be .mjs files. It might take some bother to configure our repo to use .mjs files.
|
|
10
|
+
|
|
11
|
+
## Considered Options
|
|
12
|
+
|
|
13
|
+
- Update pdfjs
|
|
14
|
+
- Leave pdfjs at its current version, 3.2.146
|
|
15
|
+
|
|
16
|
+
## Decision Outcome
|
|
17
|
+
|
|
18
|
+
Leave pdfjs at its current version, 3.2.146. The vulnerability is irrelevant for our situation and we don't have bandwidth to set up the configurations right now.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Shape and behavior of the report and log objects
|
|
2
|
+
|
|
3
|
+
## Context and scope
|
|
4
|
+
|
|
5
|
+
We have reports and logs we show to the user in the console and as artifacts. We have logs we use for development. cucumber also has logs we want to include in the above until we are confident we are handling all cases ourselves.
|
|
6
|
+
|
|
7
|
+
Right now, the system for logging is fractured and scattered - reports log to the console and save completely separately from other logs. Logs that are not from the report don't get saved anywhere. Some logs only get shown in debug mode, which can be frustrating and unhelpful.
|
|
8
|
+
|
|
9
|
+
## Goals
|
|
10
|
+
|
|
11
|
+
Overview:
|
|
12
|
+
|
|
13
|
+
- Unify the logging and report systems
|
|
14
|
+
- Clarify their flow
|
|
15
|
+
- Make log information more visible
|
|
16
|
+
|
|
17
|
+
Details:
|
|
18
|
+
|
|
19
|
+
- Log objects have statuses, icons, log codes (e.g. ALK0105), contextual info (e.g. `setup`, `takedown`, `invalid answer`), timestamps, descriptive text, and data (like full error traces).
|
|
20
|
+
- These are the broad purposes of various logs:
|
|
21
|
+
1. Setup and takedown messages.
|
|
22
|
+
2. Test progress (a compact way to see what's happening/happened in each test):
|
|
23
|
+
|
|
24
|
+
Test1: .............F--
|
|
25
|
+
|
|
26
|
+
Test 2: ..
|
|
27
|
+
3. A pretty report at the end with details about each test. It has sections, like "failed" and "passed", headings, etc.
|
|
28
|
+
4. cucumber's various console logs
|
|
29
|
+
5. Lots of other informational logs for internal development and debugging purposes.
|
|
30
|
+
I want to do different things with different logs:
|
|
31
|
+
- During the tests, always log items 1, 2, 3, and 4 to the console.
|
|
32
|
+
- During the tests, save items 2, 3, and 4 to a log as they come with all the info in the log objects - `report_log.txt`/`running_report.txt`/`report_run.txt` maybe. If we have to stop the tests early because of an infinite loop or something, this will at least show some information.
|
|
33
|
+
- At the end of the tests, format items 2, 3, and 4, often with only part of the log object info, in a file called `report.txt`.
|
|
34
|
+
- During the tests, save all of the items to a `verbose_log.txt` as they happen.
|
|
35
|
+
- In debug mode, log all that stuff to the console while the tests are running.
|
|
36
|
+
Right now, a few of the logs, like for the test progress (item 2), are printed with `stdout` inline while all others are logged with `console.log`.
|
|
37
|
+
- Logs should accept multiple arguments to match console.log/etc. behavior.
|
|
38
|
+
|
|
39
|
+
Note: The progress logs printed to the console have color codes. We also may want a plain text version without any colors to save in the report log and show in the Playground[^1] "console" and/or a version converted to HTML that does have styles. The latter may be for something easier to digest in a browser and/or to show visually in the Playground version of the tests.
|
|
40
|
+
|
|
41
|
+
Questions:
|
|
42
|
+
- Should `log` throw errors? Otherwise everywhere we need to error, we need to use `log` and `throw`, but I am unable to find a way to remove the current function from an error stack/trace.
|
|
43
|
+
- How do we capture "errors" that are more subtle? Keep the word "error" in the "context"/"types" list? For example, expected errors:
|
|
44
|
+
- Invalid answers on the form that are then assessed as valid behavior?
|
|
45
|
+
- `AbortError`s of promises that should indeed have been aborted.
|
|
46
|
+
- Should we allow "in-between"s for all parts of the log? All together: pre-everything (new lines, dividers, etc), icon/context/etc., pre-logs, logs (the actual messages to print), pre-data, data, post-data? We can default to nothing for all of those.
|
|
47
|
+
- How do we differentiate between methods that log to the console vs. methods that just store data?
|
|
48
|
+
|
|
49
|
+
[^1]: Don't go down this rabbit hole. Broadly - with the "Playground" version, users see the results as a web page instead of in the GitHub job console or in the artifacts. The users run the tests on their own server. This has to do with the platform we built ALKiln for - [docassemble](https://docassemble.org/). It gives users a faster iteration cycle.
|
|
50
|
+
|
|
51
|
+
## Non/anti-goals
|
|
52
|
+
|
|
53
|
+
- Spend a month on this
|
|
54
|
+
- Create a complex and heavy system to try to abstract absolutely everything
|
|
55
|
+
|
|
56
|
+
## The actual design
|
|
57
|
+
|
|
58
|
+
This design still seems a little complex and potentially too coupled with reports.
|
|
59
|
+
|
|
60
|
+
### System-context diagram
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
logic code -> logger -> report -----------> console
|
|
64
|
+
^ |-> console |-> stdout/progress
|
|
65
|
+
cucumber ---| |-> running report |-> final report.txt
|
|
66
|
+
|-> verbose log
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
logic code -> logger ------> report ------> final report.txt
|
|
71
|
+
^ |-> console
|
|
72
|
+
cucumber ---| |-> stdout/inline/progress
|
|
73
|
+
|-> running report
|
|
74
|
+
|-> verbose log
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|------------------------------------<|
|
|
79
|
+
v |
|
|
80
|
+
logic code -> logger -> report -----------> format prettily
|
|
81
|
+
^ |-> console
|
|
82
|
+
cucumber ---| |-> running report
|
|
83
|
+
|-> verbose log
|
|
84
|
+
|-> stdout/progress
|
|
85
|
+
|-> final report.txt
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### APIs
|
|
89
|
+
|
|
90
|
+
Everything saves to the "verbose"/"debug" log. Aside from that:
|
|
91
|
+
|
|
92
|
+
`log.info/warning/success/error` methods log to console. This includes, e.g, setup, takedown which show up in GitHub workflow job logs.
|
|
93
|
+
|
|
94
|
+
`log.report` saves to the running report then uses a report obj focused on cosmetics that has `.heading/table/header/error/etc` methods. Maybe a `.stdout/inlne` method, which then prints to the console immediately.
|
|
95
|
+
|
|
96
|
+
`log.verbose/debug` (name?) - Only save to verbose/debug log with log codes, etc.
|
|
97
|
+
|
|
98
|
+
### Data storage
|
|
99
|
+
|
|
100
|
+
- `report.txt` - final pretty output for the user with headings, etc.
|
|
101
|
+
- Each Scenario's `report.txt` - pretty output in each test's folder.
|
|
102
|
+
- `running_report_log.txt` (name?) - ugly, but still sparse, giving the user some info about what happened during the tests without overwhelming them.
|
|
103
|
+
- `verbose.txt` (name? `debug`?) - very ugly and full of all the information from everywhere else and more. Useful for internal development and troubleshooting. Includes setup and takedown.
|
|
104
|
+
|
|
105
|
+
It may be complex to store setup and takedown output in the verbose/debug file. `console.Console` cannot append to a file[^2], so we would have to figure out a work-around. One approach could be to always first copy from the existing verbose file and paste those contents back into the file as the first log. That may take setting up some fallbacks to avoid errors.
|
|
106
|
+
|
|
107
|
+
[^2]: `fs.appendFile()` only takes strings and doesn't log exactly like the console. I want to log exactly like the console to make it easy to search for words I and others see in the console output.
|
|
108
|
+
|
|
109
|
+
### Code and pseudo-code
|
|
110
|
+
|
|
111
|
+
For capturing console output, look into how to get the `stdin` for capturing various console output. https://stackoverflow.com/a/54202970:
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const stdin = process.openStdin()
|
|
115
|
+
|
|
116
|
+
process.stdout.write('Enter name: ')
|
|
117
|
+
|
|
118
|
+
stdin.addListener('data', text => {
|
|
119
|
+
const name = text.toString().trim()
|
|
120
|
+
console.log('Your name is: ' + name)
|
|
121
|
+
|
|
122
|
+
stdin.pause() // stop reading
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Degree of constraint
|
|
127
|
+
|
|
128
|
+
I think this can basically be greenfield (designed from scratch). We do have a current system, but I think we can easily convert our existing code to a new system.
|
|
129
|
+
|
|
130
|
+
## Alternatives considered
|
|
131
|
+
|
|
132
|
+
- The `report` object saves to the running report and then sends that same information to the `log` object. Also prints the final report. This includes `stdout` logs. `log` remains otherwise the same as described above.
|
|
133
|
+
- `log` handles `stdout` logs and leaves them out of the report.
|
|
134
|
+
- For report content, `log` would call to `report`, which would do pretty formatting and then hand the format text back to `log` to be saved and/or printed to the console. I'm not sure how `log` could then know what to do with the output - leave out the codes/etc. when it logs to the console and/or saves to the final report.txt.
|
|
135
|
+
- Avoid the complexity of storing setup and takedown output in the verbose/debug file. In GitHub, they're in the GitHub console. Locally, we see the results immediately. On the other hand, storing them ourselves lets us look for information in just one place.
|
|
136
|
+
|
|
137
|
+
## Cross-cutting concerns
|
|
138
|
+
|
|
139
|
+
_Security, privacy, observability, etc._
|
|
140
|
+
|
|
141
|
+
The same ones we've already dealt with for our current logs.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Use response data to detect sign-in success
|
|
2
|
+
|
|
3
|
+
## Context and Problem Statement
|
|
4
|
+
|
|
5
|
+
Should we update to the newest version of puppeteer, [22.15.0](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/CHANGELOG.md#22150-2024-07-31)?
|
|
6
|
+
|
|
7
|
+
See https://github.com/SuffolkLITLab/ALKiln/issues/930.
|
|
8
|
+
|
|
9
|
+
## Considered Options
|
|
10
|
+
|
|
11
|
+
- Update to 22.15.0
|
|
12
|
+
- Update to 22.12.0, which is the lowest version that would fix our current problems
|
|
13
|
+
- Stay with 20.8.2
|
|
14
|
+
|
|
15
|
+
See pros and cons
|
|
16
|
+
|
|
17
|
+
## Decision Outcome
|
|
18
|
+
|
|
19
|
+
Update puppeteer from 20.8.2 to 22.15.0
|
|
20
|
+
|
|
21
|
+
## Pros and Cons of the Options
|
|
22
|
+
|
|
23
|
+
### Update at all {#update}
|
|
24
|
+
|
|
25
|
+
**Pros:**
|
|
26
|
+
|
|
27
|
+
- Makes the current fix possible
|
|
28
|
+
|
|
29
|
+
**Cons:**
|
|
30
|
+
|
|
31
|
+
- Change in the middle of a complex PR
|
|
32
|
+
- [A few breaking changes](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/CHANGELOG.md#2200-2024-02-05), which includes for us at the very least:
|
|
33
|
+
- "Removes the deprecated `$x` (replace with `$$`) and `waitForXpath` (replace with `waitForSelector`)." We need to add [extra syntax to the start of our selector strings](https://github.com/puppeteer/puppeteer/pull/11782): "xpath//."
|
|
34
|
+
- Replace any `page.waitForTimeout` with cucumber's version or ours.
|
|
35
|
+
|
|
36
|
+
### Update to to 22.15.0
|
|
37
|
+
|
|
38
|
+
**Pros:**
|
|
39
|
+
|
|
40
|
+
- Has all the most recent bug fixes and features
|
|
41
|
+
|
|
42
|
+
**Cons:**
|
|
43
|
+
|
|
44
|
+
- Exposes us to possible unknown new bugs
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Update to to 22.12.0
|
|
48
|
+
|
|
49
|
+
This is the lowest version that would fix our problem
|
|
50
|
+
|
|
51
|
+
**Pros:**
|
|
52
|
+
|
|
53
|
+
- Avoids possibly unknown new bugs
|
|
54
|
+
|
|
55
|
+
**Cons:**
|
|
56
|
+
|
|
57
|
+
- Doesn't have fixes to already known bugs
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Stay with 20.8.2
|
|
61
|
+
|
|
62
|
+
Opposite of first entry ["Update at all"](#update).
|
|
@@ -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
|
|
|
@@ -61,6 +61,10 @@ const time = require('../utils/time');
|
|
|
61
61
|
let da_i = {};
|
|
62
62
|
module.exports = da_i;
|
|
63
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
|
+
|
|
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({
|
|
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
|
+
);
|
|
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({
|
|
109
|
+
log.info({ code: `ALK0167`, context: `da api`, },
|
|
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({
|
|
120
|
+
log.info({ code: `ALK0168`, context: `da api`, },
|
|
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.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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: `da api` },
|
|
127
|
+
`Checked if the server was busy and ran into a different error`,
|
|
128
|
+
error
|
|
129
|
+
);
|
|
123
130
|
}
|
|
124
131
|
|
|
125
132
|
throw error;
|
|
@@ -232,8 +239,12 @@ da_i.get_api_key_access_status = async function ({ timeout = null, api_key = nul
|
|
|
232
239
|
} // ends try
|
|
233
240
|
} // ends auth_data.codes only has the first code
|
|
234
241
|
|
|
235
|
-
log.
|
|
236
|
-
|
|
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
|
+
);
|
|
237
248
|
|
|
238
249
|
return auth_data;
|
|
239
250
|
}; // Ends da_i.get_api_key_access_status()
|
|
@@ -247,16 +258,20 @@ da_i.delete_project = async function ( delete_options ) {
|
|
|
247
258
|
let { timeout } = delete_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
248
259
|
|
|
249
260
|
let project_name = session_vars.get_project_name()
|
|
250
|
-
log.info({
|
|
261
|
+
log.info({ code: `ALK0170`, context: `da api`, },
|
|
262
|
+
`Trying to delete Project ${ project_name }`
|
|
263
|
+
);
|
|
251
264
|
|
|
252
265
|
try {
|
|
253
266
|
let response = await _da_REST.delete_project( timeout );
|
|
254
|
-
log.info({
|
|
267
|
+
log.info({ code: `ALK0171`, context: `da api`, },
|
|
268
|
+
`Deleted Project "${ project_name }"`
|
|
269
|
+
);
|
|
255
270
|
} catch ( error ) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
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;
|
|
260
275
|
}
|
|
261
276
|
|
|
262
277
|
}; // Ends da_i.delete_project()
|
|
@@ -280,7 +295,9 @@ da_i.quietly_try_to_delete_interviews = async function ({ interviews = {}, api_k
|
|
|
280
295
|
});
|
|
281
296
|
responses.push( sub_responses );
|
|
282
297
|
} else {
|
|
283
|
-
log.
|
|
298
|
+
log.debug({ code: `ALK0191`, context: `da api` },
|
|
299
|
+
`There is no interview to delete.`
|
|
300
|
+
);
|
|
284
301
|
}
|
|
285
302
|
}
|
|
286
303
|
return responses;
|
|
@@ -295,9 +312,9 @@ da_i.quietly_delete_one_interview = async function ( timeout, { interview = {},
|
|
|
295
312
|
let responses = [];
|
|
296
313
|
for ( let api_key of api_keys ) {
|
|
297
314
|
try {
|
|
298
|
-
log.
|
|
299
|
-
|
|
300
|
-
|
|
315
|
+
log.debug({ code: `ALK0188`, context: `da api` },
|
|
316
|
+
`Trying to delete the interview with the id ${ interview.uid } and an API key.`
|
|
317
|
+
);
|
|
301
318
|
|
|
302
319
|
// Actual work:
|
|
303
320
|
let response = await _da_REST.delete_interview( timeout, {
|
|
@@ -306,13 +323,15 @@ da_i.quietly_delete_one_interview = async function ( timeout, { interview = {},
|
|
|
306
323
|
});
|
|
307
324
|
responses.push( response );
|
|
308
325
|
|
|
309
|
-
log.
|
|
310
|
-
|
|
311
|
-
|
|
326
|
+
log.debug({ code: `ALK0189`, context: `da api` },
|
|
327
|
+
`No error when trying to delete interview ${ interview.uid } at ${ interview.i }.`
|
|
328
|
+
);
|
|
312
329
|
} catch ( error ) {
|
|
313
330
|
error.interview = interview;
|
|
314
|
-
|
|
315
|
-
|
|
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
|
+
);
|
|
316
335
|
}
|
|
317
336
|
} // ends for api keys
|
|
318
337
|
return responses;
|
|
@@ -347,7 +366,9 @@ da_i.get_interview = async function ({ interview = {}, api_keys = [], options =
|
|
|
347
366
|
if ( interview && interview.uid ) {
|
|
348
367
|
for ( let api_key of api_keys ) {
|
|
349
368
|
try {
|
|
350
|
-
log.
|
|
369
|
+
log.debug({ code: `ALK0192`, context: `da api` },
|
|
370
|
+
`Trying to get the interview with the id ${ interview.uid } and an API key.`
|
|
371
|
+
);
|
|
351
372
|
|
|
352
373
|
// Actual work:
|
|
353
374
|
let response = await _da_REST.get_interview( timeout, {
|
|
@@ -356,20 +377,28 @@ da_i.get_interview = async function ({ interview = {}, api_keys = [], options =
|
|
|
356
377
|
});
|
|
357
378
|
|
|
358
379
|
if ( response && response.data && response.data.items && response.data.items[0] && response.data.items[0].session ) {
|
|
359
|
-
log.
|
|
380
|
+
log.debug({ code: `ALK0193`, context: `da api` },
|
|
381
|
+
`Status ${ response.status }. Got ${ response.data.items[0].session }.`
|
|
382
|
+
);
|
|
360
383
|
return response.data.items[0];
|
|
361
384
|
} else {
|
|
362
|
-
log.
|
|
385
|
+
log.debug({ code: `ALK0194`, context: `da api` },
|
|
386
|
+
`Status ${ response.status }. Cannot find ${ interview.uid }`
|
|
387
|
+
);
|
|
363
388
|
}
|
|
364
389
|
|
|
365
390
|
} catch ( error ) {
|
|
366
391
|
error.interview = interview;
|
|
367
|
-
|
|
368
|
-
|
|
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
|
+
);
|
|
369
396
|
}
|
|
370
397
|
} // ends for api_keys
|
|
371
398
|
} else {
|
|
372
|
-
log.
|
|
399
|
+
log.debug({ code: `ALK0196`, context: `da api` },
|
|
400
|
+
`There is no interview to get.`
|
|
401
|
+
);
|
|
373
402
|
}
|
|
374
403
|
|
|
375
404
|
return null;
|
|
@@ -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();
|