@suffolklitlab/alkiln 5.8.1 → 5.9.0-feat-url2
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 +11 -7
- package/.github/workflows/playground.yml +2 -2
- package/CHANGELOG.md +23 -1
- package/docs/expected_inernal_results.md +15 -0
- package/lib/cucumber_8_shim.js +1 -0
- package/lib/scope.js +270 -139
- package/lib/steps.js +191 -34
- package/lib/utils/log.js +16 -5
- package/lib/utils/session_vars.js +1 -1
- package/package.json +1 -1
- package/tests/unit_tests/fields.fixtures.js +477 -103
- package/tests/unit_tests/getAllFields.test.js +22 -8
- package/tests/unit_tests/getMatchingRows.test.js +44 -2
- package/tests/unit_tests/html.fixtures.js +66 -4
- package/tests/unit_tests/matches.fixtures.js +20 -2
- package/tests/unit_tests/tables.fixtures.js +22 -5
package/lib/steps.js
CHANGED
|
@@ -106,6 +106,12 @@ BeforeAll(async () => {
|
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
Before(async (scenario) => {
|
|
109
|
+
|
|
110
|
+
// Useful for those with a lot of tests
|
|
111
|
+
// Is unable to print the first Scenario name for some reason
|
|
112
|
+
console.log('');
|
|
113
|
+
process.stdout.write(`Scenario: ${ scenario.pickle.name }: `);
|
|
114
|
+
|
|
109
115
|
// Create browser, which can't be created in BeforeAll() where .driver doesn't exist for some reason
|
|
110
116
|
if (!scope.browser) {
|
|
111
117
|
if (session_vars.get_origin() === 'playground') {
|
|
@@ -171,12 +177,14 @@ Given(/I start the interview at "([^"]+)"/, {timeout: -1}, async (file_name) =>
|
|
|
171
177
|
// Load the right interview page
|
|
172
178
|
await scope.load( scope, file_name );
|
|
173
179
|
|
|
180
|
+
// TODO: Move this above loading? Put it in `Before()` instead?
|
|
174
181
|
// The page timeout is set in here too in case someone set a custom timeout
|
|
175
182
|
// before a page was loaded.
|
|
176
183
|
// The function itself won't really timeout here, so we don't need to wrap it in
|
|
177
184
|
// a custom timeout
|
|
178
185
|
await scope.page.setDefaultTimeout( scope.timeout ); // overrides outer default timeout
|
|
179
186
|
|
|
187
|
+
// TODO: Move this to the `download` Step and only do it once per scenario
|
|
180
188
|
// Allow developer to save download files
|
|
181
189
|
let custom_download_behavior_timeout = new Promise(async ( resolve, reject ) => {
|
|
182
190
|
let page_timeout = setTimeout(function() {reject( `Took too long to set download behavior.` ); }, scope.timeout);
|
|
@@ -230,6 +238,8 @@ Given(/I start the interview at "([^"]+)"/, {timeout: -1}, async (file_name) =>
|
|
|
230
238
|
} // ends if this is the file the developer expected
|
|
231
239
|
}); // ends page.on 'response'
|
|
232
240
|
|
|
241
|
+
// TODO: Wrap everything in this step in this timeout? Or is this Step's timeout different?
|
|
242
|
+
// Wait for navigation
|
|
233
243
|
let custom_afterStep_timeout = new Promise(async ( resolve, reject ) => {
|
|
234
244
|
let page_timeout = setTimeout(function() { reject(`\`afterStep()\` took too long.`); }, scope.timeout);
|
|
235
245
|
// self-invoke an anonymous async function so we don't have to
|
|
@@ -245,6 +255,22 @@ Given(/I start the interview at "([^"]+)"/, {timeout: -1}, async (file_name) =>
|
|
|
245
255
|
await custom_afterStep_timeout;
|
|
246
256
|
});
|
|
247
257
|
|
|
258
|
+
Given(/I go to "([^"]+)"/i, {timeout: -1}, async ( url ) => {
|
|
259
|
+
/** Navigate to an arbitrary url. What you do after that depends on you. There's
|
|
260
|
+
* a limited amount ALKiln can do on a non-docassemble page or a very customized
|
|
261
|
+
* docassemble page.
|
|
262
|
+
*
|
|
263
|
+
* @params {string} A valid url */
|
|
264
|
+
let result = await wrapPromiseWithTimeout(
|
|
265
|
+
scope.page.goto( url, { waitUntil: 'domcontentloaded', timeout: scope.timeout }),
|
|
266
|
+
scope.timeout,
|
|
267
|
+
`It took to long to get to "${ url }"`
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
reports.addToReport(scope, { type: `info`, value: `Successfully went to "${ url }"` });
|
|
271
|
+
return result;
|
|
272
|
+
});
|
|
273
|
+
|
|
248
274
|
Given(/I (?:sign|log) ?(?:in)?(?:on)?(?:to the server)? with(?: the email)? "([^"]+)" and(?: the password)? "([^"]+)"(?: SECRETs)?/i, {timeout: -1}, async ( email, password ) => {
|
|
249
275
|
/** Uses the names of environment variables (most often GitHub SECRETs) to
|
|
250
276
|
* log into an account on the user's server. Must be SECRETs to stay secure.
|
|
@@ -297,7 +323,9 @@ Given(/the max(?:imum)? sec(?:ond)?s for each step (?:in this scenario )?is (\d+
|
|
|
297
323
|
// Story
|
|
298
324
|
//#####################################
|
|
299
325
|
//#####################################
|
|
300
|
-
|
|
326
|
+
// TODO: Consider more permissive sentences:
|
|
327
|
+
// with(?: this data| these answers)?:?
|
|
328
|
+
// with(?:.*):?
|
|
301
329
|
When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)" with this data:?/, {timeout: -1}, async (target_id, raw_var_data) => {
|
|
302
330
|
/* NO CUCUMBER TIMEOUT. Must handle timeout ourselves:
|
|
303
331
|
* https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/timeouts.md#disable-timeouts
|
|
@@ -341,6 +369,7 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
341
369
|
try {
|
|
342
370
|
let { question_has_id, id, id_matches } = await scope.examinePageID( scope );
|
|
343
371
|
|
|
372
|
+
// THIS FUNCTION ACTUALLY MATTERS
|
|
344
373
|
// Add special rows. Basically, do weirder things.
|
|
345
374
|
// TODO: Remove from_story_table - no longer needed if only called from in here
|
|
346
375
|
let ensured_var_data = await scope.ensureSpecialRows( scope, {
|
|
@@ -352,8 +381,10 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
352
381
|
console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
|
|
353
382
|
}
|
|
354
383
|
|
|
384
|
+
// THIS FUNCTION ACTUALLY MATTERS
|
|
355
385
|
// Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
|
|
356
386
|
let error = await scope.setFields(scope, { var_data: ensured_var_data, id, ensure_navigation: true });
|
|
387
|
+
|
|
357
388
|
if ( error.was_found ) { await scope.throwPageError( scope, { id: id }); }
|
|
358
389
|
resolve();
|
|
359
390
|
} catch ( err ) {
|
|
@@ -415,6 +446,123 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
415
446
|
reports.addToReport(scope, { type: `note`, value: `` });
|
|
416
447
|
});
|
|
417
448
|
|
|
449
|
+
// When(/^foo id "([^"]+)"/, {timeout: -1}, async (target_id, raw_var_data) => {
|
|
450
|
+
// /* NO CUCUMBER TIMEOUT. Must handle timeout ourselves:
|
|
451
|
+
// * https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/timeouts.md#disable-timeouts
|
|
452
|
+
// * Iterate in here to keep timeout reasonable */
|
|
453
|
+
|
|
454
|
+
// // Note: Why do we not just stop when we've used all the vars in the table or
|
|
455
|
+
// // reach the last var? Vars are not required to be given in sequence and pages that
|
|
456
|
+
// // have non-button fields don't usually have a var assigned to the 'continue' button.
|
|
457
|
+
// // Alternative: require vars even for 'continue' pages. Then in loop require at least one var
|
|
458
|
+
// // to be found on a page before hitting 'continue'. That requires detecting navigation because
|
|
459
|
+
// // pages with fields will not have a var for the continue button, so there will
|
|
460
|
+
// // still have to be some automatic continuing.
|
|
461
|
+
// // It also seems harsh, but more reliable.
|
|
462
|
+
// // Ask developers what they'd like.
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
// let supported_table = await scope.normalizeTable( scope, { raw_var_data });
|
|
466
|
+
|
|
467
|
+
// let { question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id );
|
|
468
|
+
// // Until we reach the target page, hit an error, or time out (take too long)
|
|
469
|
+
// while ( !id_matches ) {
|
|
470
|
+
// let custom_timeout = new Promise(function( resolve, reject ) {
|
|
471
|
+
|
|
472
|
+
// // Set up the timeout that avoids infinite loops
|
|
473
|
+
// let on_page_timeout = async function() {
|
|
474
|
+
|
|
475
|
+
// let non_reload_report_msg = `The target id was "${ target_id }", but it took `
|
|
476
|
+
// + `too long to try to reach it (over ${ scope.timeout/1000/60 } min). The `
|
|
477
|
+
// + `test got stuck on "${ id }".`
|
|
478
|
+
// let error = non_reload_report_msg;
|
|
479
|
+
// await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
|
|
480
|
+
// }; // Ends on_page_timeout()
|
|
481
|
+
// let page_timeout_id = setTimeout(on_page_timeout, scope.timeout);
|
|
482
|
+
|
|
483
|
+
// // self-invoke an anonymous async function so we don't have to
|
|
484
|
+
// // abstract the details of resolving and rejecting.
|
|
485
|
+
// // If we need to call recursively, signature function might look like:
|
|
486
|
+
// // func( scope, { resolve, reject, supported_table, page_timeout_id })
|
|
487
|
+
// // Maybe list of timeout and/or interval ids in state that can all be cleared at once?
|
|
488
|
+
// (async function() {
|
|
489
|
+
// try {
|
|
490
|
+
// let { question_has_id, id, id_matches } = await scope.examinePageID( scope );
|
|
491
|
+
|
|
492
|
+
// // Add special rows. Basically, do weirder things.
|
|
493
|
+
// // TODO: Remove from_story_table - no longer needed if only called from in here
|
|
494
|
+
// let ensured_var_data = await scope.ensureSpecialRows( scope, {
|
|
495
|
+
// var_data: supported_table,
|
|
496
|
+
// from_story_table: true,
|
|
497
|
+
// });
|
|
498
|
+
|
|
499
|
+
// if ( session_vars.get_debug() ) {
|
|
500
|
+
// console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
|
|
501
|
+
// }
|
|
502
|
+
|
|
503
|
+
// // Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
|
|
504
|
+
// let error = await scope.setFields(scope, { var_data: ensured_var_data, id, ensure_navigation: true });
|
|
505
|
+
// if ( error.was_found ) { await scope.throwPageError( scope, { id: id }); }
|
|
506
|
+
// resolve();
|
|
507
|
+
// } catch ( err ) {
|
|
508
|
+
// let err_msg = `Error occurred when tried to answer fields on question "${ id }".`
|
|
509
|
+
// reports.addToReport( scope, { type: `error`, value: err_msg });
|
|
510
|
+
// // Throw error instead?
|
|
511
|
+
// reject( err );
|
|
512
|
+
// } finally {
|
|
513
|
+
// clearTimeout( page_timeout_id ); // prevent temporary hang at end of tests
|
|
514
|
+
// }
|
|
515
|
+
// })();
|
|
516
|
+
// }); // ends custom_timeout for setFields
|
|
517
|
+
|
|
518
|
+
// await custom_timeout;
|
|
519
|
+
|
|
520
|
+
// // Prep for next loop
|
|
521
|
+
// ({ question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id ));
|
|
522
|
+
|
|
523
|
+
// } // ends while !id_matches
|
|
524
|
+
// // Can anything unsatisfactory get through here?
|
|
525
|
+
|
|
526
|
+
// // Add report strings from supported table, not an altered one
|
|
527
|
+
// for ( let row of supported_table ) {
|
|
528
|
+
// row.report_str = `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row }) }`;
|
|
529
|
+
// }
|
|
530
|
+
// // Sort into alphabetical order, as is recommended for writing story tables
|
|
531
|
+
// let sorted_rows = supported_table.sort( function ( row1, row2 ) {
|
|
532
|
+
// if( row1.report_str < row2.report_str ) { return -1; }
|
|
533
|
+
// if( row1.report_str > row2.report_str ) { return 1; }
|
|
534
|
+
// return 0;
|
|
535
|
+
// });
|
|
536
|
+
|
|
537
|
+
// // Add full used table to report so it can be copied if needed.
|
|
538
|
+
// // TODO: Should we/How do we get this in the final scenario report instead of here?
|
|
539
|
+
// reports.addToReport( scope, { type: `note`, value: `\n${ ' '.repeat(2) }Rows that got set:` });
|
|
540
|
+
// reports.addToReport( scope, { type: `step`, value: `${ ' '.repeat(4) }And I get to the question id "${ target_id }" with this data:` });
|
|
541
|
+
// reports.addToReport(scope, { type: `row`, value: `${ ' '.repeat(6) }| var | value | trigger |`, });
|
|
542
|
+
// let at_least_one_row_was_NOT_used = false;
|
|
543
|
+
// for ( let row of sorted_rows ) {
|
|
544
|
+
// if ( row.times_used > 0 ) {
|
|
545
|
+
// reports.addToReport(scope, { type: `row`, value: row.report_str, });
|
|
546
|
+
// } else {
|
|
547
|
+
// at_least_one_row_was_NOT_used = true;
|
|
548
|
+
// }
|
|
549
|
+
// }
|
|
550
|
+
|
|
551
|
+
// // Add unused rows if needed
|
|
552
|
+
// if ( at_least_one_row_was_NOT_used ) {
|
|
553
|
+
// reports.addToReport( scope, { type: `note`, value: `${ ' '.repeat(2) }Unused rows:` });
|
|
554
|
+
// for ( let row of sorted_rows ) {
|
|
555
|
+
// if ( row.times_used === 0 ) {
|
|
556
|
+
// reports.addToReport(scope, { type: `row`, value: row.report_str, });
|
|
557
|
+
// }
|
|
558
|
+
// }
|
|
559
|
+
// } else {
|
|
560
|
+
// reports.addToReport(scope, { type: `note`, value: `${ ' '.repeat(2) }All rows were used` });
|
|
561
|
+
// }
|
|
562
|
+
|
|
563
|
+
// reports.addToReport(scope, { type: `note`, value: `` });
|
|
564
|
+
// });
|
|
565
|
+
|
|
418
566
|
//#####################################
|
|
419
567
|
//#####################################
|
|
420
568
|
// Passive/Observational
|
|
@@ -1122,8 +1270,8 @@ Given(/the Scenario report should not include/i, async ( report_text ) => {
|
|
|
1122
1270
|
|
|
1123
1271
|
});
|
|
1124
1272
|
|
|
1125
|
-
Given(/the final Scenario status should be "(
|
|
1126
|
-
|
|
1273
|
+
Given(/the final Scenario status should be "([^"]+)"/i, async ( expected_status ) => {
|
|
1274
|
+
/** WARNING: If a Step will fail, this Step must come first.
|
|
1127
1275
|
*
|
|
1128
1276
|
* Prepare to test that the Scenario completes with the correct status. */
|
|
1129
1277
|
scope.expected_status = expected_status.toUpperCase();
|
|
@@ -1138,6 +1286,12 @@ Given(/the final Scenario status should be "(passed|failed)"/i, async ( expected
|
|
|
1138
1286
|
|
|
1139
1287
|
After(async function(scenario) {
|
|
1140
1288
|
|
|
1289
|
+
// Log errors
|
|
1290
|
+
if ( scenario.result.message ) {
|
|
1291
|
+
log.debug({ type: `error`, pre: scenario.result.message });
|
|
1292
|
+
// log.debug({ type: `error`, pre: scenario.result.message, verbose: true });
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1141
1295
|
let changeable_test_status = scenario.result.status;
|
|
1142
1296
|
// The accessibility failures don't happen til the end, so the rest of the test can continue
|
|
1143
1297
|
if ( scope.check_all_for_a11y && !scope.passed_all_for_a11y) {
|
|
@@ -1199,39 +1353,46 @@ After(async function(scenario) {
|
|
|
1199
1353
|
|
|
1200
1354
|
} // ends if not passed
|
|
1201
1355
|
|
|
1202
|
-
//
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1356
|
+
// Add report text to Scenario folder after everything has been added to the report
|
|
1357
|
+
let current_report_obj = scope.report.get( scope.scenario_id );
|
|
1358
|
+
let scenario_report_obj = [ scope.scenario_id, current_report_obj ]; // Mimic how loop works with `Map`
|
|
1359
|
+
let report = reports.getPrintableScenario( scenario_report_obj );
|
|
1360
|
+
// Save the report as in the Scenario folder
|
|
1361
|
+
fs.writeFileSync( scope.paths.scenario_report, report );
|
|
1362
|
+
|
|
1363
|
+
// ---------------- Check internal test results of this framework ----------------
|
|
1364
|
+
|
|
1211
1365
|
if ( scope.expected_in_report && scope.expected_in_report.length > 0) {
|
|
1212
|
-
let
|
|
1366
|
+
let report_includes_all_expected_strings = await scope.reportIncludesAllExpected(
|
|
1367
|
+
scope,
|
|
1368
|
+
{ expected: scope.expected_in_report }
|
|
1369
|
+
);
|
|
1370
|
+
if ( !report_includes_all_expected_strings ) { changeable_test_status = `FAILED`; }
|
|
1213
1371
|
// Reset report values no matter what so they don't mess up future scenarios
|
|
1214
1372
|
scope.expected_in_report = null;
|
|
1215
|
-
let all_were_included = await scope.reportIncludesAllExpected( scope, { expected });
|
|
1216
|
-
|
|
1217
|
-
if ( all_were_included ) { changeable_test_status = `PASSED`; }
|
|
1218
|
-
else { changeable_test_status = `FAILED`; }
|
|
1219
1373
|
}
|
|
1220
1374
|
|
|
1221
1375
|
if (scope.expected_not_in_report && scope.expected_not_in_report.length > 0) {
|
|
1222
|
-
let
|
|
1376
|
+
let all_prohibited_strings_were_absent = await scope.reportDoesNotInclude(
|
|
1377
|
+
scope,
|
|
1378
|
+
{ not_expected: scope.expected_not_in_report }
|
|
1379
|
+
);
|
|
1380
|
+
if ( !all_prohibited_strings_were_absent ) { changeable_test_status = `FAILED`;}
|
|
1223
1381
|
// Reset report values no matter what so they don't mess up future scenarios
|
|
1224
1382
|
scope.expected_not_in_report = null;
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
if ( all_were_not_there ) {
|
|
1228
|
-
changeable_test_status = `PASSED`;
|
|
1229
|
-
} else {
|
|
1230
|
-
changeable_test_status = `FAILED`;
|
|
1231
|
-
}
|
|
1383
|
+
}
|
|
1232
1384
|
|
|
1385
|
+
// The default is 'passed', which won't need to get in here
|
|
1386
|
+
if ( scope.expected_status ) {
|
|
1387
|
+
// When internal tests should fail (to test our failure conditions), passing _is_ failing
|
|
1388
|
+
expect( changeable_test_status ).to.equal( scope.expected_status );
|
|
1389
|
+
// If the status was as expected, pass this Scenario
|
|
1390
|
+
changeable_test_status = `PASSED`;
|
|
1391
|
+
scope.expected_status = null; // reset for next Scenario
|
|
1233
1392
|
}
|
|
1234
1393
|
|
|
1394
|
+
// ---------------- Ends check internal test results of this framework ----------------
|
|
1395
|
+
|
|
1235
1396
|
// If there is a page open, then sign out and close it
|
|
1236
1397
|
if ( scope.page ) {
|
|
1237
1398
|
// Catch a possible reload error.
|
|
@@ -1259,23 +1420,19 @@ After(async function(scenario) {
|
|
|
1259
1420
|
|
|
1260
1421
|
} // ends if scope.page
|
|
1261
1422
|
|
|
1262
|
-
// Add report text to Scenario folder after everything has been added to the report
|
|
1263
|
-
let current_report_obj = scope.report.get( scope.scenario_id );
|
|
1264
|
-
let scenario_report_obj = [ scope.scenario_id, current_report_obj ]; // Mimic how loop works with `Map`
|
|
1265
|
-
let report = reports.getPrintableScenario( scenario_report_obj );
|
|
1266
|
-
// Save the report as in the Scenario folder
|
|
1267
|
-
fs.writeFileSync( scope.paths.scenario_report, report );
|
|
1268
|
-
|
|
1269
1423
|
if ( changeable_test_status === `FAILED` ) {
|
|
1270
1424
|
// If the result object status wasn't failure and we still want
|
|
1271
1425
|
// the tests to fail, as with a11y tests, we can't mess with the
|
|
1272
1426
|
// cucumber result.status object because it will cause unwanted
|
|
1273
1427
|
// errors. We have to throw an error here instead.
|
|
1274
1428
|
if ( scenario.result.status !== `FAILED` ) {
|
|
1275
|
-
throw new Error(`The test failed. See the report for more information.`);
|
|
1429
|
+
throw new Error(`The test failed. See the report above for more information.`);
|
|
1276
1430
|
}
|
|
1277
1431
|
} else {
|
|
1278
|
-
//
|
|
1432
|
+
// Some internal test failures should be ok
|
|
1433
|
+
// TODO: Look into setDefinitionFunctionWrapper to catch errors
|
|
1434
|
+
// of failing tests that should indeed be failing:
|
|
1435
|
+
// https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/api_reference.md#setdefinitionfunctionwrapperwrapper
|
|
1279
1436
|
scenario.result.status = changeable_test_status;
|
|
1280
1437
|
}
|
|
1281
1438
|
});
|
package/lib/utils/log.js
CHANGED
|
@@ -40,14 +40,25 @@ log.error = function ({ type='', pre='', data='', post='' }) {
|
|
|
40
40
|
if ( post ) { console.error( post, `\n` ); }
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
log.debug = function ({ type='', pre='', data='', post='' }) {
|
|
43
|
+
log.debug = function ({ type='', pre='', data='', post='', verbose=false }) {
|
|
44
44
|
/* If debugging is turned on, log a message that includes `ALKiln` and `debug` */
|
|
45
|
-
if ( session_vars.get_debug() ) {
|
|
45
|
+
if ( session_vars.get_debug() || verbose ) {
|
|
46
46
|
let start = create_msg_start([ type, 'debug' ], pre );
|
|
47
|
+
let full = `\n${ start }`;
|
|
47
48
|
// Log them each on a separate line
|
|
48
|
-
console.log(
|
|
49
|
-
if ( data ) {
|
|
50
|
-
|
|
49
|
+
console.log( `\n${ start }` );
|
|
50
|
+
if ( data ) {
|
|
51
|
+
full += `\n${ data }`;
|
|
52
|
+
console.log( data );
|
|
53
|
+
}
|
|
54
|
+
if ( post ) {
|
|
55
|
+
full += `\n${ post }`;
|
|
56
|
+
console.log( post );
|
|
57
|
+
}
|
|
58
|
+
// TODO: Make a verbose log instead of adding to the debug one and always add to it
|
|
59
|
+
if ( verbose ) {
|
|
60
|
+
log.add_to_debug_log( full );
|
|
61
|
+
}
|
|
51
62
|
}
|
|
52
63
|
};
|
|
53
64
|
|
|
@@ -294,7 +294,7 @@ session_vars.set_sources_paths = function ( paths ) {
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
console.info(
|
|
297
|
-
`ALKiln
|
|
297
|
+
`ALKiln SUCCESS: Did find "sources" file(s) at "${ existing_paths.join('", "') }".`
|
|
298
298
|
)
|
|
299
299
|
|
|
300
300
|
// Otherwise, store valid paths
|