@suffolklitlab/alkiln 5.13.0-logs3 → 5.13.1
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 +8 -8
- package/.github/workflows/playground.yml +3 -3
- package/CHANGELOG.md +1 -0
- package/action.yml +28 -70
- package/action_for_github_server/action.yml +29 -61
- package/lib/docassemble/docassemble_api_interface.js +34 -63
- package/lib/docassemble/server_install.js +9 -23
- package/lib/docassemble/setup.js +20 -33
- package/lib/docassemble/takedown.js +7 -27
- package/lib/run_cucumber.js +33 -81
- package/lib/scope.js +75 -61
- package/lib/steps.js +41 -70
- package/lib/utils/files.js +6 -8
- package/lib/utils/log.js +84 -477
- package/lib/utils/reports.js +4 -13
- package/lib/utils/session_vars.js +18 -25
- package/lib/utils/time.js +0 -44
- package/npm-shrinkwrap.json +19 -15
- package/package.json +2 -2
- package/tests/log_codes/check_codes.sh +1 -2
- package/tests/log_codes/log_code_expected_instances.txt +7 -11
- package/tests/unit_tests/getAllFields.test.js +0 -5
- package/tests/unit_tests/getMatchingRows.test.js +0 -5
- package/tests/unit_tests/normalizeTable.test.js +0 -5
- package/docs/decisions/006_which_log_level_to_pick_2024_09_5.md +0 -46
- package/docs/decisions/reports_and_logs_2024_08_11.md +0 -141
- package/tests/unit_tests/log.test.js +0 -20
package/lib/scope.js
CHANGED
|
@@ -13,13 +13,14 @@ const pdf_reader = require('./utils/pdf_reader');
|
|
|
13
13
|
const session_vars = require('./utils/session_vars');
|
|
14
14
|
const get_base_interview_url = require(`./docassemble/get_base_interview_url`);
|
|
15
15
|
const time = require('./utils/time');
|
|
16
|
-
|
|
16
|
+
const log = require('./utils/log');
|
|
17
17
|
const { waitForTimeout } = require('./utils/time');
|
|
18
18
|
const files = require('./utils/files' );
|
|
19
19
|
const da_api = require('./docassemble/docassemble_api_interface');
|
|
20
20
|
const wrapPromiseWithTimeout = require('./cucumber_8_shim');
|
|
21
21
|
const reports = require(`./utils/reports`);
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
let ordinal_to_integer = {
|
|
24
25
|
only: 0, first: 0, second: 1, third: 2, fourth: 3, fifth: 4,
|
|
25
26
|
sixth: 5, seventh: 6, eighth: 7, ninth: 8, tenth: 9,
|
|
@@ -83,16 +84,10 @@ let toBase64 = function ( utf8_str, exclude_padding=true) {
|
|
|
83
84
|
|
|
84
85
|
let proxies_regex = /(\bx\.)|(\bx\[)|(\[[ijklmn]\])/g;
|
|
85
86
|
let da_base64_regex = /^[A-Za-z0-9+/]+$/;
|
|
86
|
-
let log = null;
|
|
87
87
|
|
|
88
88
|
module.exports = {
|
|
89
89
|
trigger_not_needed_flag: `ALKiln: no trigger variable needed`,
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
set_log: function ({ log_obj }) {
|
|
93
|
-
log = log_obj;
|
|
94
|
-
},
|
|
95
|
-
|
|
96
91
|
getSafeScenarioBaseFilename: async function( scope, { scenario }) {
|
|
97
92
|
/** Return a string that's safe to be a filename. Include the Scenario
|
|
98
93
|
* description and tags.
|
|
@@ -697,7 +692,7 @@ module.exports = {
|
|
|
697
692
|
});
|
|
698
693
|
expect( load_result.error ).to.equal( '' );
|
|
699
694
|
} else {
|
|
700
|
-
reports.addToReport(scope, { type: `row info`, code: `ALK0117`, value: `Successfully found the interview` });
|
|
695
|
+
reports.addToReport(scope, { type: `row info`, code: `ALK0117`, value: `Successfully found the interview at "${ interview_url }"` });
|
|
701
696
|
}
|
|
702
697
|
|
|
703
698
|
return scope.page;
|
|
@@ -716,19 +711,19 @@ module.exports = {
|
|
|
716
711
|
if ( !scenario.interviews ) { scenario.interviews = {}; }
|
|
717
712
|
if ( !scenario.interviews[ vars.uid ] ) {
|
|
718
713
|
scenario.interviews[ vars.uid ] = vars;
|
|
719
|
-
log.debug({
|
|
720
|
-
|
|
721
|
-
|
|
714
|
+
log.debug({
|
|
715
|
+
code: `ALK0185`, type: `info`,
|
|
716
|
+
pre: `Saved new interview data. File path: ${ vars.i }. Session id: ${ vars.uid }.`
|
|
717
|
+
});
|
|
722
718
|
} else {
|
|
723
|
-
log.debug({
|
|
724
|
-
|
|
725
|
-
|
|
719
|
+
log.debug({
|
|
720
|
+
code: `ALK0186`, type: `info`,
|
|
721
|
+
pre: `Interview data already existed. File path: ${ vars.i }. Session id: ${ vars.uid }.`
|
|
722
|
+
});
|
|
726
723
|
}
|
|
727
724
|
return vars;
|
|
728
725
|
} else {
|
|
729
|
-
log.debug({ code: `ALK0187`,
|
|
730
|
-
`Found no interview data.`
|
|
731
|
-
);
|
|
726
|
+
log.debug({ code: `ALK0187`, type: `info`, pre: `Found no interview data.` });
|
|
732
727
|
return null;
|
|
733
728
|
}
|
|
734
729
|
}, // Ends scope.set_interview_session_data()
|
|
@@ -875,9 +870,11 @@ module.exports = {
|
|
|
875
870
|
supported_table.push( result );
|
|
876
871
|
} // ends for every row
|
|
877
872
|
|
|
878
|
-
log.debug({
|
|
879
|
-
`
|
|
880
|
-
|
|
873
|
+
log.debug({
|
|
874
|
+
code: `ALK0122`,
|
|
875
|
+
type: `info`,
|
|
876
|
+
pre: `scope.normalizedTable():\n ${JSON.stringify( supported_table )}`
|
|
877
|
+
});
|
|
881
878
|
|
|
882
879
|
return supported_table;
|
|
883
880
|
}, // Ends scope.normalizeTable()
|
|
@@ -1027,9 +1024,11 @@ module.exports = {
|
|
|
1027
1024
|
fields.push( field_data );
|
|
1028
1025
|
} // ends for every node
|
|
1029
1026
|
|
|
1030
|
-
log.debug({
|
|
1031
|
-
|
|
1032
|
-
|
|
1027
|
+
log.debug({
|
|
1028
|
+
code: `ALK0124`,
|
|
1029
|
+
type: `info`,
|
|
1030
|
+
pre: `page fields:\n${ JSON.stringify( fields )}`
|
|
1031
|
+
});
|
|
1033
1032
|
return fields;
|
|
1034
1033
|
}, // Ends scope.getAllFields()
|
|
1035
1034
|
|
|
@@ -1079,9 +1078,11 @@ module.exports = {
|
|
|
1079
1078
|
/* Return variable names and values combined in ways that can
|
|
1080
1079
|
* try to match table rows. Tables can have two properties:
|
|
1081
1080
|
* variable name and value. */
|
|
1082
|
-
log.debug({
|
|
1083
|
-
|
|
1084
|
-
|
|
1081
|
+
log.debug({
|
|
1082
|
+
code: `ALK0126`,
|
|
1083
|
+
type: `info`,
|
|
1084
|
+
pre: `scope.getPossibleTableRowMatchers() var_names: ${JSON.stringify(var_names)} values: ${JSON.stringify(values)}`
|
|
1085
|
+
});
|
|
1085
1086
|
let possible_table_rows = [];
|
|
1086
1087
|
for ( let var_name of var_names ) {
|
|
1087
1088
|
// Inputs like textareas don't have values
|
|
@@ -1556,13 +1557,17 @@ module.exports = {
|
|
|
1556
1557
|
reports.addToReport(scope, { type: `warning`, code: `ALK0130`, value: multiple_matches_msg });
|
|
1557
1558
|
}
|
|
1558
1559
|
|
|
1559
|
-
log.debug({
|
|
1560
|
-
`
|
|
1561
|
-
|
|
1560
|
+
log.debug({
|
|
1561
|
+
code: `ALK0131`,
|
|
1562
|
+
type: `info`,
|
|
1563
|
+
pre: `final_matching_rows:\n${JSON.stringify( final_matching_rows )}`
|
|
1564
|
+
});
|
|
1562
1565
|
if ( final_matching_rows.length == 0) {
|
|
1563
|
-
log.debug({
|
|
1564
|
-
`
|
|
1565
|
-
|
|
1566
|
+
log.debug({
|
|
1567
|
+
code: `ALK0132`,
|
|
1568
|
+
type: `info`,
|
|
1569
|
+
pre: `field:\n${JSON.stringify( field )}`
|
|
1570
|
+
});
|
|
1566
1571
|
}
|
|
1567
1572
|
|
|
1568
1573
|
return final_matching_rows;
|
|
@@ -1648,9 +1653,11 @@ module.exports = {
|
|
|
1648
1653
|
|
|
1649
1654
|
get_handle_from_field: async function ( scope, { field }) {
|
|
1650
1655
|
/** Get the element's puppeteer handle using the field's selector. */
|
|
1651
|
-
log.debug({
|
|
1652
|
-
`
|
|
1653
|
-
|
|
1656
|
+
log.debug({
|
|
1657
|
+
code: `ALK0133`,
|
|
1658
|
+
type: `info`,
|
|
1659
|
+
pre: `scope.get_handle_from_field() field.selector: ${JSON.stringify(field.selector)}`
|
|
1660
|
+
});
|
|
1654
1661
|
let handle = await scope.page.evaluateHandle(( selector ) => {
|
|
1655
1662
|
let elem = document.querySelector( selector );
|
|
1656
1663
|
// If the element has a sibling that's a label, we need to
|
|
@@ -2162,9 +2169,7 @@ module.exports = {
|
|
|
2162
2169
|
* @param ensure_all_vars_used {bool} [false] = Default false. If true, errors if any
|
|
2163
2170
|
* object in var_data is not used during running of this function.
|
|
2164
2171
|
*/
|
|
2165
|
-
log.debug({
|
|
2166
|
-
`scope.setFields()`
|
|
2167
|
-
);
|
|
2172
|
+
log.debug({ type: `plain`, pre: `~~~~~~~~~~~~~~ scope.setFields() ~~~~~~~~~~~~~~` });
|
|
2168
2173
|
|
|
2169
2174
|
// Only record the page id once for each page to which we navigate
|
|
2170
2175
|
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
@@ -2208,7 +2213,8 @@ module.exports = {
|
|
|
2208
2213
|
// Accumulate number of times this row was used. Esp important for `.target_number`
|
|
2209
2214
|
await scope.increment_row_use( scope, { row: row_used });
|
|
2210
2215
|
|
|
2211
|
-
|
|
2216
|
+
process.stdout.write(`\x1b[36m${ '*' }\x1b[0m`); // assumes var was set if no error occurred
|
|
2217
|
+
|
|
2212
2218
|
}
|
|
2213
2219
|
} // ends for every non-submit-button field on the page
|
|
2214
2220
|
} // ends while fields are still being set
|
|
@@ -2253,7 +2259,7 @@ module.exports = {
|
|
|
2253
2259
|
// }
|
|
2254
2260
|
|
|
2255
2261
|
did_navigate = true;
|
|
2256
|
-
|
|
2262
|
+
process.stdout.write(`\x1b[36m${ 'v' }\x1b[0m`); // pressed button successfully
|
|
2257
2263
|
break;
|
|
2258
2264
|
|
|
2259
2265
|
} // ends if row_used
|
|
@@ -2300,7 +2306,7 @@ module.exports = {
|
|
|
2300
2306
|
// }
|
|
2301
2307
|
|
|
2302
2308
|
did_navigate = true;
|
|
2303
|
-
|
|
2309
|
+
process.stdout.write(`\x1b[36m${ '>' }\x1b[0m`); // continued successfully
|
|
2304
2310
|
} // ends if !did_navigate && ensure_navigation
|
|
2305
2311
|
|
|
2306
2312
|
if ( did_navigate && scope.check_all_for_a11y ) {
|
|
@@ -3057,30 +3063,36 @@ module.exports = {
|
|
|
3057
3063
|
let redirect_promise = scope.page.waitForResponse(function ( response ) {
|
|
3058
3064
|
return response.status() === 302;
|
|
3059
3065
|
}, { signal: controller.signal })
|
|
3060
|
-
.catch((
|
|
3061
|
-
log.debug({
|
|
3062
|
-
`
|
|
3063
|
-
|
|
3066
|
+
.catch(( error ) => {
|
|
3067
|
+
log.debug({
|
|
3068
|
+
code: `ALK0204`, type: `info`,
|
|
3069
|
+
pre: `302 sign-in wait error: ${ error.name }`,
|
|
3070
|
+
data: error,
|
|
3071
|
+
});
|
|
3064
3072
|
});
|
|
3065
3073
|
|
|
3066
3074
|
// Invalid credentials, no navigation, no sign in
|
|
3067
3075
|
let wrong_sign_in_promise = scope.page.waitForResponse(function ( response ) {
|
|
3068
3076
|
return response.status() >= 200 && response.status() < 300 && response.url().includes(`/sign-in`);
|
|
3069
3077
|
}, { signal: controller.signal })
|
|
3070
|
-
.catch((
|
|
3071
|
-
log.debug({
|
|
3072
|
-
`
|
|
3073
|
-
|
|
3078
|
+
.catch(( error ) => {
|
|
3079
|
+
log.debug({
|
|
3080
|
+
code: `ALK0205`, type: `info`,
|
|
3081
|
+
pre: `200s sign-in wait error: ${ error.name }`,
|
|
3082
|
+
data: error,
|
|
3083
|
+
});
|
|
3074
3084
|
});
|
|
3075
3085
|
|
|
3076
3086
|
// System error
|
|
3077
3087
|
let error_promise = scope.page.waitForResponse(function ( response ) {
|
|
3078
3088
|
return response.status() >= 500 && response.status() < 600;
|
|
3079
3089
|
}, { signal: controller.signal })
|
|
3080
|
-
.catch((
|
|
3081
|
-
log.debug({
|
|
3082
|
-
`
|
|
3083
|
-
|
|
3090
|
+
.catch(( error ) => {
|
|
3091
|
+
log.debug({
|
|
3092
|
+
code: `ALK0206`, type: `info`,
|
|
3093
|
+
pre: `500s sign-in wait error: ${ error.name }`,
|
|
3094
|
+
data: error,
|
|
3095
|
+
});
|
|
3084
3096
|
});
|
|
3085
3097
|
|
|
3086
3098
|
let click_promise = elem.click(); // MUST complete
|
|
@@ -3099,9 +3111,10 @@ module.exports = {
|
|
|
3099
3111
|
// Clean up unresolved promises
|
|
3100
3112
|
controller.abort();
|
|
3101
3113
|
|
|
3102
|
-
log.debug({
|
|
3103
|
-
`
|
|
3104
|
-
|
|
3114
|
+
log.debug({
|
|
3115
|
+
code: `ALK0208`, type: `info`,
|
|
3116
|
+
pre: `Sign-in winner:`, data: winner,
|
|
3117
|
+
});
|
|
3105
3118
|
|
|
3106
3119
|
return winner;
|
|
3107
3120
|
},
|
|
@@ -3124,7 +3137,7 @@ module.exports = {
|
|
|
3124
3137
|
} else {
|
|
3125
3138
|
// Try to give a random answer for that element tag
|
|
3126
3139
|
await scope.set_random_input_for[ field.tag ]( scope, { field: field });
|
|
3127
|
-
|
|
3140
|
+
process.stdout.write(`\x1b[36m${ '*' }\x1b[0m`); // assumes var was set if no error occurred
|
|
3128
3141
|
}
|
|
3129
3142
|
|
|
3130
3143
|
} // End for all page fields
|
|
@@ -3160,10 +3173,11 @@ module.exports = {
|
|
|
3160
3173
|
}
|
|
3161
3174
|
if (field == null) {
|
|
3162
3175
|
// Just skip it? Shouldn't happen but has before. Dig in more
|
|
3163
|
-
log.debug({
|
|
3164
|
-
`
|
|
3165
|
-
|
|
3166
|
-
|
|
3176
|
+
log.debug({
|
|
3177
|
+
code: `ALK0164`,
|
|
3178
|
+
type: `info`,
|
|
3179
|
+
pre: `A random button field choice was null. These were the fields to choose from:\n${ JSON.stringify(fields, null, 2) }`,
|
|
3180
|
+
});
|
|
3167
3181
|
return;
|
|
3168
3182
|
}
|
|
3169
3183
|
let handle = await scope.get_handle_from_field( scope, { field: field });
|
package/lib/steps.js
CHANGED
|
@@ -5,7 +5,6 @@ const {
|
|
|
5
5
|
Given,
|
|
6
6
|
After,
|
|
7
7
|
Before,
|
|
8
|
-
AfterStep,
|
|
9
8
|
BeforeAll,
|
|
10
9
|
AfterAll,
|
|
11
10
|
setDefaultTimeout //,
|
|
@@ -19,7 +18,7 @@ const { v4: uuidv4 } = require('uuid');
|
|
|
19
18
|
|
|
20
19
|
// Ours
|
|
21
20
|
const scope = require('./scope');
|
|
22
|
-
const
|
|
21
|
+
const log = require('./utils/log');
|
|
23
22
|
const session_vars = require('./utils/session_vars');
|
|
24
23
|
const files = require('./utils/files' );
|
|
25
24
|
const reports = require(`./utils/reports`);
|
|
@@ -83,9 +82,7 @@ let click_with = {
|
|
|
83
82
|
pc: 'click',
|
|
84
83
|
};
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
BeforeAll(async function() {
|
|
85
|
+
BeforeAll(async () => {
|
|
89
86
|
scope.showif_timeout = 600;
|
|
90
87
|
// TODO: Do these really need to be maps? As sets, they may make the output
|
|
91
88
|
// more predictable to the user, but they add complexity.
|
|
@@ -98,29 +95,29 @@ BeforeAll(async function() {
|
|
|
98
95
|
// Store path names for files and docs created for the tests
|
|
99
96
|
scope.paths = {};
|
|
100
97
|
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// // Save its name in a file. `session_vars` can get it back later.
|
|
104
|
-
// // The value we are saving is used by at least run_cucumber.js.
|
|
98
|
+
// TODO: figure out how to test file and folder creation stuff,
|
|
99
|
+
// especially when setup is excluded from the flow.
|
|
105
100
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
101
|
+
// Make the folder to store all the files for this run of the tests
|
|
102
|
+
scope.paths.artifacts = files.make_artifacts_folder();
|
|
103
|
+
// Save its name in a file. `session_vars` can get it back later.
|
|
104
|
+
// The value we are saving is used by at least run_cucumber.js.
|
|
105
|
+
session_vars.save_artifacts_path_name( scope.paths.artifacts );
|
|
111
106
|
|
|
112
|
-
scope.paths.
|
|
113
|
-
scope.paths.report_log = `${ scope.paths.artifacts }/${ log.report_log_filename }`;
|
|
114
|
-
scope.paths.report = `${ scope.paths.artifacts }/${ log.report_filename }`;
|
|
107
|
+
scope.paths.report = `${ scope.paths.artifacts }/report.txt`;
|
|
115
108
|
scope.paths.failures = `${ scope.paths.artifacts }/${ log.unexpected_filename }`;
|
|
109
|
+
scope.paths.debug_log = `${ scope.paths.artifacts }/${ log.debug_log_file }`;
|
|
110
|
+
fs.writeFileSync( scope.paths.debug_log, "" );
|
|
116
111
|
|
|
117
112
|
reports.create( scope );
|
|
118
113
|
});
|
|
119
114
|
|
|
120
115
|
Before(async (scenario) => {
|
|
121
116
|
|
|
122
|
-
//
|
|
123
|
-
|
|
117
|
+
// Useful for those with a lot of tests
|
|
118
|
+
// Is unable to print the first Scenario name for some reason
|
|
119
|
+
console.log('');
|
|
120
|
+
process.stdout.write(`Scenario: ${ scenario.pickle.name }: `);
|
|
124
121
|
|
|
125
122
|
// Create browser, which can't be created in BeforeAll() where .driver doesn't exist for some reason
|
|
126
123
|
if (!scope.browser) {
|
|
@@ -399,9 +396,11 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
399
396
|
from_story_table: true,
|
|
400
397
|
});
|
|
401
398
|
|
|
402
|
-
log.debug({
|
|
403
|
-
`
|
|
404
|
-
|
|
399
|
+
log.debug({
|
|
400
|
+
type: `info`,
|
|
401
|
+
code: `ALK0061`,
|
|
402
|
+
pre: `Rows, including special rows:, ${JSON.stringify( ensured_var_data )}`,
|
|
403
|
+
});
|
|
405
404
|
|
|
406
405
|
// THIS FUNCTION ACTUALLY MATTERS
|
|
407
406
|
// Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
|
|
@@ -973,7 +972,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
|
|
|
973
972
|
} // ends if !has_content
|
|
974
973
|
|
|
975
974
|
if ( buttons_exist ) {
|
|
976
|
-
|
|
975
|
+
process.stdout.write(`\x1b[36m${ 'v' }\x1b[0m`); // pressed button
|
|
977
976
|
}
|
|
978
977
|
|
|
979
978
|
resolve();
|
|
@@ -1264,22 +1263,11 @@ Then(/I fail to delete (\d) detected interview(?:s)? and get no error __internal
|
|
|
1264
1263
|
//#####################################
|
|
1265
1264
|
//#####################################
|
|
1266
1265
|
|
|
1267
|
-
AfterStep(async function({ result }) {
|
|
1268
|
-
// TODO: Abstract this
|
|
1269
|
-
if ( result.status === `PASSED` ) { log.stdout({ records_only: true }, `.`); }
|
|
1270
|
-
else if ( result.status === `FAILED` ) { log.stdout({ records_only: true }, `F`); }
|
|
1271
|
-
else if ( result.status === `UNDEFINED` ) { log.stdout({ records_only: true }, `U`); }
|
|
1272
|
-
else if ( result.status === `SKIPPED` ) { log.stdout({ records_only: true }, `-`); }
|
|
1273
|
-
else if ( result.status === `PENDING` ) { log.stdout({ records_only: true }, `P`); }
|
|
1274
|
-
});
|
|
1275
|
-
|
|
1276
1266
|
After(async function(scenario) {
|
|
1277
1267
|
|
|
1278
1268
|
// Log errors
|
|
1279
1269
|
if ( scenario.result.message ) {
|
|
1280
|
-
log.debug({ code: `ALK0091`,
|
|
1281
|
-
scenario.result.message
|
|
1282
|
-
);
|
|
1270
|
+
log.debug({ type: `info`, code: `ALK0091`, pre: `cucumber error: ${ scenario.result.message }` }); //, verbose: true });
|
|
1283
1271
|
}
|
|
1284
1272
|
|
|
1285
1273
|
let changeable_test_status = scenario.result.status;
|
|
@@ -1308,9 +1296,11 @@ After(async function(scenario) {
|
|
|
1308
1296
|
reports.saveFinalScenarioData( scope, { status: changeable_test_status });
|
|
1309
1297
|
|
|
1310
1298
|
if (changeable_test_status !== `PASSED`) {
|
|
1311
|
-
log.debug({
|
|
1312
|
-
|
|
1313
|
-
|
|
1299
|
+
log.debug({
|
|
1300
|
+
type: `error`,
|
|
1301
|
+
code: `ALK0094`,
|
|
1302
|
+
pre: `Non-passed status occurred while running test: ${changeable_test_status}`,
|
|
1303
|
+
});
|
|
1314
1304
|
|
|
1315
1305
|
if ( scope.page ) {
|
|
1316
1306
|
|
|
@@ -1406,11 +1396,8 @@ After(async function(scenario) {
|
|
|
1406
1396
|
+ `Expected status: ${scope.expected_status}. `
|
|
1407
1397
|
+ `See the report for details.`;
|
|
1408
1398
|
let code = `ALK0099`;
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
);
|
|
1412
|
-
// Temp for debugging new log output
|
|
1413
|
-
expect( expected_status_err_msg ).to.equal(`🤕 ${ code } ERROR: ${ msg }`);
|
|
1399
|
+
log.debug({ type: `error`, code: code, pre: msg, })
|
|
1400
|
+
expected_status_err_msg = `🤕 ${ code } ERROR: ${ msg }`
|
|
1414
1401
|
}
|
|
1415
1402
|
}
|
|
1416
1403
|
scope.expected_status = null; // reset for next Scenario
|
|
@@ -1430,25 +1417,17 @@ After(async function(scenario) {
|
|
|
1430
1417
|
// Make sure that tests which ALKiln has calculated as failed
|
|
1431
1418
|
// cause a cucumber error later. Just changing the status to `FAILED`
|
|
1432
1419
|
// causes unhelpful cucumber errors. TODO: Add to internal docs.
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1420
|
+
log.debug({
|
|
1421
|
+
type: `error`,
|
|
1422
|
+
code: force_failure_code,
|
|
1423
|
+
pre: force_failure_msg
|
|
1424
|
+
});
|
|
1437
1425
|
// TODO: Look into setDefinitionFunctionWrapper to catch errors
|
|
1438
1426
|
// of failing tests that should indeed be failing:
|
|
1439
1427
|
// https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/api_reference.md#setdefinitionfunctionwrapperwrapper
|
|
1440
1428
|
need_to_force_failed_status = true;
|
|
1441
1429
|
}
|
|
1442
1430
|
|
|
1443
|
-
// Not sure if this is necessary
|
|
1444
|
-
if ( changeable_test_status === 'PASSED' ) {
|
|
1445
|
-
log.stdout({ records_only: true }, `.` );
|
|
1446
|
-
} else if ( changeable_test_status === `SKIPPED` ) {
|
|
1447
|
-
log.stdout({ records_only: true }, `-` );
|
|
1448
|
-
} else {
|
|
1449
|
-
log.stdout({ records_only: true }, changeable_test_status[0].toUpperCase() );
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
1431
|
let signout_succeeded = true;
|
|
1453
1432
|
let signout_error_msg = ``;
|
|
1454
1433
|
// If there is a page open, then sign out and close it
|
|
@@ -1502,10 +1481,9 @@ After(async function(scenario) {
|
|
|
1502
1481
|
// going to the wrong file). If it becomes a problem we can track it down later.
|
|
1503
1482
|
if ( visible_keys.length > 0 ) {
|
|
1504
1483
|
// Can an API key ever see an interview that it can't delete?
|
|
1505
|
-
log.
|
|
1506
|
-
`The API key can see ${ visible_keys.length } interviews that were not deleted
|
|
1507
|
-
|
|
1508
|
-
);
|
|
1484
|
+
log.info({ type: `internal warning`, code: `ALK0197`,
|
|
1485
|
+
pre: `The API key can see ${ visible_keys.length } interviews that were not deleted: ${ visible_keys.join( ', ' ) }`
|
|
1486
|
+
});
|
|
1509
1487
|
}
|
|
1510
1488
|
} catch ( error ) {
|
|
1511
1489
|
// Deleting interviews is nice, but not non-critical. Don't bother the
|
|
@@ -1515,9 +1493,7 @@ After(async function(scenario) {
|
|
|
1515
1493
|
// interview. If it becomes a problem we can track it down later.
|
|
1516
1494
|
// Consider add "internal" to docs: "If you see this, make an
|
|
1517
1495
|
// issue in ALKiln with your debug/verbose log"
|
|
1518
|
-
log.
|
|
1519
|
-
`Cleaning up interviews incomplete, but unimportant.`
|
|
1520
|
-
);
|
|
1496
|
+
log.info({ type: `internal warning`, code: `ALK0198`, pre: `Error while cleaning up interviews.`, data: error });
|
|
1521
1497
|
}
|
|
1522
1498
|
}
|
|
1523
1499
|
|
|
@@ -1536,16 +1512,11 @@ After(async function(scenario) {
|
|
|
1536
1512
|
throw new Error( `🤕 ${ force_failure_code } unreachable ERROR: ${ force_failure_msg }` );
|
|
1537
1513
|
|
|
1538
1514
|
} else if ( internal_errors.length > 0 ) {
|
|
1539
|
-
log.
|
|
1540
|
-
`There was no need to force failed status and yet there are error messages.`,
|
|
1541
|
-
internal_errors
|
|
1542
|
-
);
|
|
1515
|
+
log.info({ type: `internal error`, code: `ALK0203`, pre: `No need to force failed status and yet there are error messages. ${ errors.join( errors, '\n') }` });
|
|
1543
1516
|
}
|
|
1544
1517
|
|
|
1545
1518
|
// Find the race condition.
|
|
1546
|
-
log.debug({ code: `ALK0100`,
|
|
1547
|
-
`Scenario After() message:`, scenario.result.message
|
|
1548
|
-
);
|
|
1519
|
+
log.debug({ type: `cucumber`, code: `ALK0100`, verbose: true, pre: `Scenario AfterStep() message`, data: scenario.result.message });
|
|
1549
1520
|
|
|
1550
1521
|
});
|
|
1551
1522
|
|
package/lib/utils/files.js
CHANGED
|
@@ -22,20 +22,18 @@ files.readable_date = function() {
|
|
|
22
22
|
}; // Ends files.readable_date()
|
|
23
23
|
|
|
24
24
|
files.make_artifacts_folder = function (folder_name) {
|
|
25
|
-
/** Makes a folder in the root of the project
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
/** Makes a folder in the root of the project, either with the given name
|
|
26
|
+
* or with a default name.
|
|
27
|
+
*
|
|
28
|
+
* Works for local development as well, unlike action.yml or the workflow file.
|
|
29
|
+
*/
|
|
30
30
|
if (folder_name) {
|
|
31
31
|
folder_name = safe_filename( folder_name );
|
|
32
32
|
} else {
|
|
33
33
|
folder_name = `alkiln-${ files.readable_date() }`
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
// https://nodejs.org/docs/latest-v18.x/api/fs.html#fspromisesmkdirpath-options
|
|
38
|
-
fs.mkdirSync( folder_name, { recursive: true });
|
|
36
|
+
fs.mkdirSync( folder_name );
|
|
39
37
|
return folder_name;
|
|
40
38
|
}; // Ends files.make_artifacts_folder()
|
|
41
39
|
|