@suffolklitlab/alkiln 5.14.0 → 5.15.0-deps-2
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/.github/workflows/github_server.yml +1 -1
- package/.github/workflows/playground.yml +2 -1
- package/CHANGELOG.md +29 -0
- package/action.yml +26 -10
- package/action_for_github_server/action.yml +31 -27
- package/docs/4_environments.md +2 -2
- package/docs/artifacts_folder_name.md +121 -71
- package/lib/docassemble/server_install.js +0 -2
- package/lib/docassemble/setup.js +1 -3
- package/lib/docassemble/takedown.js +2 -2
- package/lib/globals.js +10 -0
- package/lib/run_cucumber.js +40 -53
- package/lib/scope.js +32 -0
- package/lib/setup/TestGenerator.js +1757 -0
- package/lib/setup/artifacts.js +20 -0
- package/lib/setup/generate.js +42 -0
- package/lib/setup/get_Gherkin_AST.js +26 -0
- package/lib/setup/validate.js +89 -0
- package/lib/steps.js +53 -19
- package/lib/utils/Log.js +302 -149
- package/lib/utils/get_error_stacks.js +16 -0
- package/lib/utils/pdf_reader.js +9 -2
- package/lib/utils/reports.js +43 -23
- package/lib/utils/session_vars.js +77 -57
- package/lib/utils/set_sources_paths.js +98 -0
- package/npm-shrinkwrap.json +739 -924
- package/package.json +17 -10
- package/tests/log_codes/check_codes.sh +17 -13
- package/tests/log_codes/log_code_expected_instances.txt +58 -0
- package/tests/unit_tests/constrained_random_answers/invalid.fixtures.js +178 -0
- package/tests/unit_tests/constrained_random_answers/invalid.test.js +251 -0
- package/tests/unit_tests/constrained_random_answers/valid.fixtures.js +957 -0
- package/tests/unit_tests/constrained_random_answers/valid.test.js +563 -0
- package/tests/unit_tests/log.test.js +17 -41
- package/_alkiln_meta/gherkin_parsed_example.json +0 -1546
- package/_alkiln_meta/shift_logs.js +0 -75
- /package/docs/{expected_inernal_results.md → expected_internal_results.md} +0 -0
|
@@ -56,8 +56,6 @@ const server_install = async () => {
|
|
|
56
56
|
session_vars.validateEnvironment();
|
|
57
57
|
|
|
58
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
59
|
const argv = require(`minimist`)(process.argv.slice(2));
|
|
62
60
|
const log = new Log({ path: argv.path, context, });
|
|
63
61
|
|
package/lib/docassemble/setup.js
CHANGED
|
@@ -54,7 +54,7 @@ const setup = async () => {
|
|
|
54
54
|
+ `dainstall this package on your server. See above for more details.`;
|
|
55
55
|
log.throw({ code: `ALK0047`, context,
|
|
56
56
|
before: `☝️ ☝️ ☝️ Error data ☝️ ☝️ ☝️\n`,
|
|
57
|
-
error: `Error while installing project` },
|
|
57
|
+
error: new Error(`Error while installing project on your docassemble server during GitHub+You™ tests`) },
|
|
58
58
|
install_err_msg
|
|
59
59
|
);
|
|
60
60
|
}
|
|
@@ -68,8 +68,6 @@ const setup = async () => {
|
|
|
68
68
|
session_vars.validateEnvironment();
|
|
69
69
|
|
|
70
70
|
// 2. Prepare logs
|
|
71
|
-
// Local devs: This will be separate from your test paths
|
|
72
|
-
// unless you pass a `path` argument into the cucumber run command
|
|
73
71
|
const argv = require(`minimist`)(process.argv.slice(2));
|
|
74
72
|
const log = new Log({ path: argv.path, context, });
|
|
75
73
|
|
|
@@ -40,8 +40,8 @@ const takedown = async () => {
|
|
|
40
40
|
session_vars.validateEnvironment();
|
|
41
41
|
|
|
42
42
|
// 2. Prepare logs
|
|
43
|
-
// Local devs: This will be separate from your test artifacts paths
|
|
44
|
-
//
|
|
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
45
|
const argv = require(`minimist`)( process.argv.slice(2) );
|
|
46
46
|
const log = new Log({ path: argv.path, context, });
|
|
47
47
|
|
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
|
+
// Discuss: Would this be clearer as a config file instead? If not, change name
|
|
10
|
+
// to `constants`?
|
package/lib/run_cucumber.js
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const fast_glob = require(`fast-glob`);
|
|
4
5
|
const path = require(`path`);
|
|
5
6
|
const cucumber_api = require('@cucumber/cucumber/api');
|
|
6
7
|
|
|
8
|
+
const globals = require(`./globals`);
|
|
7
9
|
const Log = require('./utils/Log');
|
|
8
10
|
const session_vars = require('./utils/session_vars');
|
|
11
|
+
const set_sources_paths = require(`./utils/set_sources_paths`);
|
|
9
12
|
|
|
10
13
|
const SUMMARY_FILENAME = `cucumber-report.txt`;
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
function build_config(
|
|
16
|
+
function build_config() {
|
|
17
|
+
/** Use the command line arguments to build the cucumberjs config object.
|
|
18
|
+
*
|
|
19
|
+
* @param {string?} - Arguments passed to the command line.
|
|
20
|
+
*
|
|
21
|
+
* @returns {object} - cucumberjs config object
|
|
22
|
+
* */
|
|
14
23
|
// Turn all the paths to the sources folders into paths to the feature files
|
|
15
24
|
let sources_paths = session_vars.get_sources_paths();
|
|
16
25
|
let feature_paths = [];
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
|
|
27
|
+
// Get all the paths for the right feature files (for cucumber to use)
|
|
28
|
+
for ( let sources_path of sources_paths ) {
|
|
29
|
+
let glob = fast_glob.sync(
|
|
30
|
+
`${ sources_path }/**/*.feature`,
|
|
31
|
+
// Ignore "generator" feature files that we used to generate actual tests
|
|
32
|
+
{ ignore: [`${ sources_path }/${ globals.generators_prefix }*.feature`] }
|
|
33
|
+
);
|
|
34
|
+
feature_paths.push( ...glob );
|
|
19
35
|
}
|
|
20
36
|
|
|
21
37
|
const config = {
|
|
@@ -26,9 +42,10 @@ function build_config( command_args ) {
|
|
|
26
42
|
retry: 1,
|
|
27
43
|
}
|
|
28
44
|
|
|
45
|
+
const cli_args = require(`minimist`)( process.argv.slice(2) );
|
|
29
46
|
// Normalize tag expressions, if there are any
|
|
30
47
|
// Joining and splitting handles both tags surrounded with `""` or those without `""`
|
|
31
|
-
let tags =
|
|
48
|
+
let tags = cli_args[`_`].join(` `).split(` `);
|
|
32
49
|
// If there was no tag expression, `tags` is ['']. Remove that item.
|
|
33
50
|
tags = tags.filter(function(entry) { return entry !== ""; })
|
|
34
51
|
if ( tags.length > 0 ) {
|
|
@@ -56,46 +73,12 @@ function build_config( command_args ) {
|
|
|
56
73
|
|
|
57
74
|
async function main() {
|
|
58
75
|
/** Create the cucumber config, run the tests, create and
|
|
59
|
-
*
|
|
76
|
+
* manipulate the output. */
|
|
60
77
|
|
|
61
78
|
const environment = { cwd: process.cwd() };
|
|
62
79
|
log.info({ code: `ALK0049`, context: `pre_run environment` },
|
|
63
80
|
environment
|
|
64
81
|
);
|
|
65
|
-
|
|
66
|
-
// We'll use the user info to construct the possible paths to /sources
|
|
67
|
-
let id = session_vars.get_user_id();
|
|
68
|
-
// `project` is the name in the server docassemble "Project" page
|
|
69
|
-
let project = session_vars.get_user_project_name();
|
|
70
|
-
|
|
71
|
-
// process.argv is a list of strings of commands and args.
|
|
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), {
|
|
75
|
-
default: {
|
|
76
|
-
sources: [
|
|
77
|
-
`./docassemble/*/data/sources`, // In GitHub folder
|
|
78
|
-
`/usr/share/docassemble/files/playgroundsources/${id}/${project}/*.feature`, // From playground without S3
|
|
79
|
-
`/tmp/playgroundsources/${id}/${project}/*.feature` // From playground with S3
|
|
80
|
-
],
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Make sure `sources` is always a list
|
|
85
|
-
let sources_list = argv.sources;
|
|
86
|
-
if ( typeof argv.sources === `string` ) {
|
|
87
|
-
sources_list = [ argv.sources ];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let one_dir_exists = session_vars.set_sources_paths( sources_list );
|
|
91
|
-
if ( !one_dir_exists ) {
|
|
92
|
-
// If we don't throw, it'll be more confusing when no tests run
|
|
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
|
-
});
|
|
98
|
-
}
|
|
99
82
|
|
|
100
83
|
const { runConfiguration } = await cucumber_api.loadConfiguration({
|
|
101
84
|
provided: build_config( argv ),
|
|
@@ -122,9 +105,9 @@ async function main() {
|
|
|
122
105
|
|
|
123
106
|
/** Write to files.
|
|
124
107
|
*
|
|
125
|
-
* Note:
|
|
126
|
-
* authors can focus on the info we give them, which they often miss
|
|
127
|
-
* the GitHub action.
|
|
108
|
+
* Note: Avoid adding to the purely report-focused files. Those are files
|
|
109
|
+
* where authors can focus on the info we give them, which they often miss
|
|
110
|
+
* in the GitHub action.
|
|
128
111
|
*/
|
|
129
112
|
|
|
130
113
|
if ( success ) {
|
|
@@ -134,7 +117,7 @@ async function main() {
|
|
|
134
117
|
} else {
|
|
135
118
|
// Don't want to throw error here, so don't pass error object
|
|
136
119
|
log.warn({ code: `ALK0055`, context: `post_run`, },
|
|
137
|
-
`The tests ran into something unexpected.
|
|
120
|
+
`The tests ran into something unexpected. See warnings and errors above.`
|
|
138
121
|
);
|
|
139
122
|
}
|
|
140
123
|
// Custom exit code. May overlap with other systems.
|
|
@@ -142,14 +125,12 @@ async function main() {
|
|
|
142
125
|
const exitCode = success ? 0 : 50;
|
|
143
126
|
process.exitCode = exitCode;
|
|
144
127
|
|
|
145
|
-
// This is hardcoded information from `provide_config` above.
|
|
146
|
-
// This code isn't used for anything other than detecting and removing color codes.
|
|
147
128
|
let summary_file_name = SUMMARY_FILENAME;
|
|
148
129
|
fs.readFile(summary_file_name, 'utf8', (read_error, text) => {
|
|
149
130
|
if ( read_error ) {
|
|
150
131
|
// Something else will probably show an error that's more relevant
|
|
151
132
|
log.warn({ code: `ALK0056`, context: `post_run error`, },
|
|
152
|
-
`Failed to read
|
|
133
|
+
`Failed to read the report of the 3rd party library, cucumberjs. There may be more information above or below.`, read_error
|
|
153
134
|
);
|
|
154
135
|
return;
|
|
155
136
|
}
|
|
@@ -184,7 +165,13 @@ async function main() {
|
|
|
184
165
|
try {
|
|
185
166
|
fs.readFileSync(`${ log.path }/${ log.unexpected_filename }`); // Does it have contents?
|
|
186
167
|
fs.appendFileSync(`${ log.path }/${ log.unexpected_filename }`, `\n\n\n\n\n` );
|
|
187
|
-
} catch ( ignore_err ) {
|
|
168
|
+
} catch ( ignore_err ) {
|
|
169
|
+
/* Missing "unexpected results" file is ok */
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// TODO: Is this meant to write to the debug file or is this debug info
|
|
173
|
+
// really supposed to be in the "unexpected results" file? Or are these
|
|
174
|
+
// comments old?
|
|
188
175
|
|
|
189
176
|
// Add the heading for debug content
|
|
190
177
|
fs.appendFileSync( `${ log.path }/${ log.unexpected_filename }`,
|
|
@@ -198,8 +185,8 @@ async function main() {
|
|
|
198
185
|
|
|
199
186
|
} catch ( writing_cucumber_error ) {
|
|
200
187
|
let code = `ALK0182`;
|
|
201
|
-
let context = `post_run
|
|
202
|
-
let msg = `Something probably went wrong earlier.
|
|
188
|
+
let context = `post_run`
|
|
189
|
+
let msg = `Something probably went wrong earlier. See warnings and errors above. Skipped writing to ${ log.path }/${ log.debug_log_filename }.`;
|
|
203
190
|
try {
|
|
204
191
|
log.warn({ code, context, }, msg, writing_cucumber_error );
|
|
205
192
|
} catch ( all_writing_error ) {
|
|
@@ -223,10 +210,10 @@ session_vars.validateEnvironment();
|
|
|
223
210
|
// If using `npm run cucumber` (as opposed to the bin commands),
|
|
224
211
|
// use `--` before `--sources=./foo`
|
|
225
212
|
const argv = require(`minimist`)( process.argv.slice(2) );
|
|
226
|
-
// The artifacts folder might be getting created for the first
|
|
227
|
-
// time right here. The tests themselves should avoid creating
|
|
228
|
-
// their own file.
|
|
229
213
|
const log = new Log({ path: argv.path, context: `run` });
|
|
230
214
|
|
|
231
|
-
// 3.
|
|
215
|
+
// 3. Prep the sources paths to find .feature files
|
|
216
|
+
let sources_paths = set_sources_paths({ log });
|
|
217
|
+
|
|
218
|
+
// 4. run
|
|
232
219
|
main();
|
package/lib/scope.js
CHANGED
|
@@ -2129,6 +2129,38 @@ module.exports = {
|
|
|
2129
2129
|
// await scope.page.mouse.move(1, 1); // Too big? Wait a while before drawing?
|
|
2130
2130
|
await scope.page.mouse.up();
|
|
2131
2131
|
},
|
|
2132
|
+
|
|
2133
|
+
get_page_id: async function ( scope ) {
|
|
2134
|
+
/** Return the current page's docassemble `question` block ID or `null`
|
|
2135
|
+
*
|
|
2136
|
+
* Note: The ID is already sanitized by docassemble.
|
|
2137
|
+
*
|
|
2138
|
+
* @param {object} scope - Tests state object
|
|
2139
|
+
* @param {object} scope.page - puppeteerjs page object
|
|
2140
|
+
*
|
|
2141
|
+
* @returns {null | string}
|
|
2142
|
+
* */
|
|
2143
|
+
let question_id_match = await scope.page.$eval(`body`, function (elem) {
|
|
2144
|
+
return elem.className.match(/question-([^ ]+)/);
|
|
2145
|
+
});
|
|
2146
|
+
if ( question_id_match !== null ) {
|
|
2147
|
+
return question_id_match[ 1 ];
|
|
2148
|
+
}
|
|
2149
|
+
return null;
|
|
2150
|
+
},
|
|
2151
|
+
|
|
2152
|
+
to_docassemble_sanitized_id: function ( risky_id ) {
|
|
2153
|
+
/** Return a version of `risky_id` that's sanitized the same way docassemble
|
|
2154
|
+
* sanitizes its IDs to turn them into HTML class names in python:
|
|
2155
|
+
* re.sub(r'[^A-Za-z0-9]+', '-', interview_status.question.id.lower())
|
|
2156
|
+
* (reference needed)
|
|
2157
|
+
*
|
|
2158
|
+
* @param {string} risky_id - The un-sanitized id
|
|
2159
|
+
*
|
|
2160
|
+
* @returns {string} - Sanitized id
|
|
2161
|
+
* */
|
|
2162
|
+
return risky_id.toLowerCase().replace(/[^A-Za-z0-9]+/g, '-');
|
|
2163
|
+
},
|
|
2132
2164
|
|
|
2133
2165
|
examinePageID: async function ( scope, question_id = '' ) {
|
|
2134
2166
|
/* Looks for a sanitized version of the question id as it's written
|