@suffolklitlab/alkiln 5.7.0 → 5.8.1-feat2columns1
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 +2 -2
- package/.github/workflows/playground.yml +2 -0
- package/CHANGELOG.md +22 -0
- package/action.yml +29 -14
- package/action_for_github_server/action.yml +37 -21
- package/lib/scope.js +370 -184
- package/lib/steps.js +147 -13
- package/lib/utils/log.js +16 -5
- package/package.json +1 -1
- package/tests/unit_tests/fields.fixtures.js +368 -86
- package/tests/unit_tests/getAllFields.test.js +13 -10
package/lib/steps.js
CHANGED
|
@@ -254,7 +254,7 @@ Given(/I (?:sign|log) ?(?:in)?(?:on)?(?:to the server)? with(?: the email)? "([^
|
|
|
254
254
|
* I sign on with the email "USER1_EMAIL" and the password "USER1_PASSWORD" SECRETs
|
|
255
255
|
* I log in with "USER1_EMAIL" and "USER1_PASSWORD"
|
|
256
256
|
*/
|
|
257
|
-
//
|
|
257
|
+
// `page` timeout will deal with custom timeout
|
|
258
258
|
// Couldn't test the timeout for tapping the button because there's not
|
|
259
259
|
// enough of a pause between initial navigation and pressing button.
|
|
260
260
|
await scope.steps.sign_in( scope, {
|
|
@@ -341,6 +341,7 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
341
341
|
try {
|
|
342
342
|
let { question_has_id, id, id_matches } = await scope.examinePageID( scope );
|
|
343
343
|
|
|
344
|
+
// THIS FUNCTION ACTUALLY MATTERS
|
|
344
345
|
// Add special rows. Basically, do weirder things.
|
|
345
346
|
// TODO: Remove from_story_table - no longer needed if only called from in here
|
|
346
347
|
let ensured_var_data = await scope.ensureSpecialRows( scope, {
|
|
@@ -352,8 +353,10 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
352
353
|
console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
|
|
353
354
|
}
|
|
354
355
|
|
|
356
|
+
// THIS FUNCTION ACTUALLY MATTERS
|
|
355
357
|
// Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
|
|
356
358
|
let error = await scope.setFields(scope, { var_data: ensured_var_data, id, ensure_navigation: true });
|
|
359
|
+
|
|
357
360
|
if ( error.was_found ) { await scope.throwPageError( scope, { id: id }); }
|
|
358
361
|
resolve();
|
|
359
362
|
} catch ( err ) {
|
|
@@ -415,6 +418,123 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
|
|
|
415
418
|
reports.addToReport(scope, { type: `note`, value: `` });
|
|
416
419
|
});
|
|
417
420
|
|
|
421
|
+
// When(/^foo id "([^"]+)"/, {timeout: -1}, async (target_id, raw_var_data) => {
|
|
422
|
+
// /* NO CUCUMBER TIMEOUT. Must handle timeout ourselves:
|
|
423
|
+
// * https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/timeouts.md#disable-timeouts
|
|
424
|
+
// * Iterate in here to keep timeout reasonable */
|
|
425
|
+
|
|
426
|
+
// // Note: Why do we not just stop when we've used all the vars in the table or
|
|
427
|
+
// // reach the last var? Vars are not required to be given in sequence and pages that
|
|
428
|
+
// // have non-button fields don't usually have a var assigned to the 'continue' button.
|
|
429
|
+
// // Alternative: require vars even for 'continue' pages. Then in loop require at least one var
|
|
430
|
+
// // to be found on a page before hitting 'continue'. That requires detecting navigation because
|
|
431
|
+
// // pages with fields will not have a var for the continue button, so there will
|
|
432
|
+
// // still have to be some automatic continuing.
|
|
433
|
+
// // It also seems harsh, but more reliable.
|
|
434
|
+
// // Ask developers what they'd like.
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
// let supported_table = await scope.normalizeTable( scope, { raw_var_data });
|
|
438
|
+
|
|
439
|
+
// let { question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id );
|
|
440
|
+
// // Until we reach the target page, hit an error, or time out (take too long)
|
|
441
|
+
// while ( !id_matches ) {
|
|
442
|
+
// let custom_timeout = new Promise(function( resolve, reject ) {
|
|
443
|
+
|
|
444
|
+
// // Set up the timeout that avoids infinite loops
|
|
445
|
+
// let on_page_timeout = async function() {
|
|
446
|
+
|
|
447
|
+
// let non_reload_report_msg = `The target id was "${ target_id }", but it took `
|
|
448
|
+
// + `too long to try to reach it (over ${ scope.timeout/1000/60 } min). The `
|
|
449
|
+
// + `test got stuck on "${ id }".`
|
|
450
|
+
// let error = non_reload_report_msg;
|
|
451
|
+
// await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
|
|
452
|
+
// }; // Ends on_page_timeout()
|
|
453
|
+
// let page_timeout_id = setTimeout(on_page_timeout, scope.timeout);
|
|
454
|
+
|
|
455
|
+
// // self-invoke an anonymous async function so we don't have to
|
|
456
|
+
// // abstract the details of resolving and rejecting.
|
|
457
|
+
// // If we need to call recursively, signature function might look like:
|
|
458
|
+
// // func( scope, { resolve, reject, supported_table, page_timeout_id })
|
|
459
|
+
// // Maybe list of timeout and/or interval ids in state that can all be cleared at once?
|
|
460
|
+
// (async function() {
|
|
461
|
+
// try {
|
|
462
|
+
// let { question_has_id, id, id_matches } = await scope.examinePageID( scope );
|
|
463
|
+
|
|
464
|
+
// // Add special rows. Basically, do weirder things.
|
|
465
|
+
// // TODO: Remove from_story_table - no longer needed if only called from in here
|
|
466
|
+
// let ensured_var_data = await scope.ensureSpecialRows( scope, {
|
|
467
|
+
// var_data: supported_table,
|
|
468
|
+
// from_story_table: true,
|
|
469
|
+
// });
|
|
470
|
+
|
|
471
|
+
// if ( session_vars.get_debug() ) {
|
|
472
|
+
// console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
|
|
473
|
+
// }
|
|
474
|
+
|
|
475
|
+
// // Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
|
|
476
|
+
// let error = await scope.setFields(scope, { var_data: ensured_var_data, id, ensure_navigation: true });
|
|
477
|
+
// if ( error.was_found ) { await scope.throwPageError( scope, { id: id }); }
|
|
478
|
+
// resolve();
|
|
479
|
+
// } catch ( err ) {
|
|
480
|
+
// let err_msg = `Error occurred when tried to answer fields on question "${ id }".`
|
|
481
|
+
// reports.addToReport( scope, { type: `error`, value: err_msg });
|
|
482
|
+
// // Throw error instead?
|
|
483
|
+
// reject( err );
|
|
484
|
+
// } finally {
|
|
485
|
+
// clearTimeout( page_timeout_id ); // prevent temporary hang at end of tests
|
|
486
|
+
// }
|
|
487
|
+
// })();
|
|
488
|
+
// }); // ends custom_timeout for setFields
|
|
489
|
+
|
|
490
|
+
// await custom_timeout;
|
|
491
|
+
|
|
492
|
+
// // Prep for next loop
|
|
493
|
+
// ({ question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id ));
|
|
494
|
+
|
|
495
|
+
// } // ends while !id_matches
|
|
496
|
+
// // Can anything unsatisfactory get through here?
|
|
497
|
+
|
|
498
|
+
// // Add report strings from supported table, not an altered one
|
|
499
|
+
// for ( let row of supported_table ) {
|
|
500
|
+
// row.report_str = `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row }) }`;
|
|
501
|
+
// }
|
|
502
|
+
// // Sort into alphabetical order, as is recommended for writing story tables
|
|
503
|
+
// let sorted_rows = supported_table.sort( function ( row1, row2 ) {
|
|
504
|
+
// if( row1.report_str < row2.report_str ) { return -1; }
|
|
505
|
+
// if( row1.report_str > row2.report_str ) { return 1; }
|
|
506
|
+
// return 0;
|
|
507
|
+
// });
|
|
508
|
+
|
|
509
|
+
// // Add full used table to report so it can be copied if needed.
|
|
510
|
+
// // TODO: Should we/How do we get this in the final scenario report instead of here?
|
|
511
|
+
// reports.addToReport( scope, { type: `note`, value: `\n${ ' '.repeat(2) }Rows that got set:` });
|
|
512
|
+
// reports.addToReport( scope, { type: `step`, value: `${ ' '.repeat(4) }And I get to the question id "${ target_id }" with this data:` });
|
|
513
|
+
// reports.addToReport(scope, { type: `row`, value: `${ ' '.repeat(6) }| var | value | trigger |`, });
|
|
514
|
+
// let at_least_one_row_was_NOT_used = false;
|
|
515
|
+
// for ( let row of sorted_rows ) {
|
|
516
|
+
// if ( row.times_used > 0 ) {
|
|
517
|
+
// reports.addToReport(scope, { type: `row`, value: row.report_str, });
|
|
518
|
+
// } else {
|
|
519
|
+
// at_least_one_row_was_NOT_used = true;
|
|
520
|
+
// }
|
|
521
|
+
// }
|
|
522
|
+
|
|
523
|
+
// // Add unused rows if needed
|
|
524
|
+
// if ( at_least_one_row_was_NOT_used ) {
|
|
525
|
+
// reports.addToReport( scope, { type: `note`, value: `${ ' '.repeat(2) }Unused rows:` });
|
|
526
|
+
// for ( let row of sorted_rows ) {
|
|
527
|
+
// if ( row.times_used === 0 ) {
|
|
528
|
+
// reports.addToReport(scope, { type: `row`, value: row.report_str, });
|
|
529
|
+
// }
|
|
530
|
+
// }
|
|
531
|
+
// } else {
|
|
532
|
+
// reports.addToReport(scope, { type: `note`, value: `${ ' '.repeat(2) }All rows were used` });
|
|
533
|
+
// }
|
|
534
|
+
|
|
535
|
+
// reports.addToReport(scope, { type: `note`, value: `` });
|
|
536
|
+
// });
|
|
537
|
+
|
|
418
538
|
//#####################################
|
|
419
539
|
//#####################################
|
|
420
540
|
// Passive/Observational
|
|
@@ -745,24 +865,32 @@ When(/I tap to continue/i, { timeout: -1 }, async () => {
|
|
|
745
865
|
// Any selectors for this seem somewhat precarious
|
|
746
866
|
// No data will cause an automatic continue when `ensure_navigation` is true
|
|
747
867
|
|
|
748
|
-
//
|
|
868
|
+
// `page` timeout will deal with custom timeout
|
|
749
869
|
// check if the server is reloading
|
|
750
870
|
await scope.setFields( scope, { var_data: [], ensure_navigation: true });
|
|
751
871
|
});
|
|
752
872
|
|
|
753
873
|
When(/I tap the "([^"]+)" tab/i, { timeout: -1 }, async ( tabId ) => {
|
|
754
|
-
//
|
|
874
|
+
// `page` timeout will deal with custom timeout
|
|
755
875
|
await scope.tapTab( scope, tabId );
|
|
756
876
|
});
|
|
757
877
|
|
|
758
|
-
When(/I tap the "([^"]+)" element
|
|
759
|
-
//
|
|
760
|
-
await scope.
|
|
878
|
+
When(/I tap the "([^"]+)" element(?: and go to (?:a new|the next) page)?$/i, { timeout: -1 }, async ( elemSelector ) => {
|
|
879
|
+
// `page` timeout will deal with custom timeout
|
|
880
|
+
await scope.tapSelectorToNavigate( scope, elemSelector, 2000 );
|
|
761
881
|
});
|
|
762
882
|
|
|
763
|
-
When(/I tap the "([^"]+)" element and
|
|
764
|
-
//
|
|
765
|
-
await scope.
|
|
883
|
+
When(/I tap the "([^"]+)" element and stay(?: on the same page)?$/i, { timeout: -1 }, async ( selector ) => {
|
|
884
|
+
// `page` timeout will deal with custom timeout
|
|
885
|
+
await scope.tapSelectorAndStay( scope, { selector });
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
When(/I tap the "([^"]+)" element and wait (?:for )?([0-9]+) second(?:s)?/i, { timeout: -1 }, async ( elemSelector, waitTime ) => {
|
|
889
|
+
// TODO: Why is it the developer can't just wait after the step?
|
|
890
|
+
// Also, this is always supposed to navigate, and that handles its own waiting.
|
|
891
|
+
|
|
892
|
+
// `page` timeout will deal with custom timeout
|
|
893
|
+
await scope.tapSelectorToNavigate( scope, elemSelector, waitTime * 1000 )
|
|
766
894
|
});
|
|
767
895
|
|
|
768
896
|
When(/I check the page for (?:accessibility|a11y) issues/i, {timeout: -1}, async () => {
|
|
@@ -967,7 +1095,7 @@ When(/I set the var(?:iable)? "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async (
|
|
|
967
1095
|
* 1. I set the var "benefits['SSI']" to "false"
|
|
968
1096
|
* 1. I set the variable "rent_interval" to "weekly"
|
|
969
1097
|
*/
|
|
970
|
-
//
|
|
1098
|
+
// `page` timeout will deal with custom timeout
|
|
971
1099
|
await scope.steps.set_regular_var( scope, var_name, answer )
|
|
972
1100
|
|
|
973
1101
|
});
|
|
@@ -975,7 +1103,7 @@ When(/I set the var(?:iable)? "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async (
|
|
|
975
1103
|
When(/I set the var(?:iable)? "([^"]+)" to ?(?:the)? ?(?:GitHub)? secret "([^"]+)"/i, { timeout: -1 }, async ( var_name, set_to_env_name ) => {
|
|
976
1104
|
/* Set a non-story table variable to a secrete value. Same as the above, but reads the value from `process.env` */
|
|
977
1105
|
// This could theoretically tap an element, so
|
|
978
|
-
//
|
|
1106
|
+
// `page` timeout will deal with custom timeout
|
|
979
1107
|
await scope.steps.set_secret_var( scope, var_name, set_to_env_name )
|
|
980
1108
|
});
|
|
981
1109
|
|
|
@@ -995,7 +1123,7 @@ Then(/I upload "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async ( filenames, var_
|
|
|
995
1123
|
|
|
996
1124
|
When('I tap the defined text link {string}', { timeout: -1 }, async ( phrase ) => {
|
|
997
1125
|
/** Tap a link that doesn't navigate. Depends on the language of the text. */
|
|
998
|
-
//
|
|
1126
|
+
// `page` timeout will deal with custom timeout
|
|
999
1127
|
await scope.steps.tap_term( scope, phrase );
|
|
1000
1128
|
});
|
|
1001
1129
|
|
|
@@ -1022,7 +1150,7 @@ When(/I download "([^"]+)"$/, { timeout: -1 }, async ( filename ) => {
|
|
|
1022
1150
|
* page load. Just stick to the name of the file.
|
|
1023
1151
|
*/
|
|
1024
1152
|
// TODO:
|
|
1025
|
-
// This should be using `scope.
|
|
1153
|
+
// This should be using `scope.tapElementAndStayOnPage()`? When someone clicks on a link to
|
|
1026
1154
|
// download a document, it sends a request to the server, which could be reloading
|
|
1027
1155
|
return wrapPromiseWithTimeout(
|
|
1028
1156
|
scope.steps.download( scope, filename ),
|
|
@@ -1130,6 +1258,12 @@ Given(/the final Scenario status should be "(passed|failed)"/i, async ( expected
|
|
|
1130
1258
|
|
|
1131
1259
|
After(async function(scenario) {
|
|
1132
1260
|
|
|
1261
|
+
// Log errors
|
|
1262
|
+
if ( scenario.result.message ) {
|
|
1263
|
+
log.debug({ type: `error`, pre: scenario.result.message });
|
|
1264
|
+
// log.debug({ type: `error`, pre: scenario.result.message, verbose: true });
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1133
1267
|
let changeable_test_status = scenario.result.status;
|
|
1134
1268
|
// The accessibility failures don't happen til the end, so the rest of the test can continue
|
|
1135
1269
|
if ( scope.check_all_for_a11y && !scope.passed_all_for_a11y) {
|
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
|
|