@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/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
- // Exiting the custom timeout happens in scope.tapElement() if needed
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
- // Exiting the custom timeout happens in scope.tapElement() where we can
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
- // Exiting the custom timeout happens in scope.tapElement() if needed
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$/i, { timeout: -1 }, async ( elemSelector ) => {
759
- // Exiting the custom timeout happens in scope.tapElement() if needed
760
- await scope.tapElementBySelector( scope, elemSelector, 2000 );
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 wait ([0-9]+) second(?:s)?/i, { timeout: -1 }, async ( elemSelector, waitTime ) => {
764
- // Exiting the custom timeout happens in scope.tapElement() if needed
765
- await scope.tapElementBySelector( scope, elemSelector, waitTime * 1000 )
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
- // Exiting the custom timeout happens in scope.tapElement() if needed
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
- // exiting the custom timeout happens in scope.tapElement() if needed
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
- // exiting the custom timeout happens in scope.tapElement() if needed
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.tapElement()`? When someone clicks on a link to
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( `ALKiln ${ type } debug: ${ pre }` );
49
- if ( data ) { console.log( data ); }
50
- if ( post ) { console.log( post ); }
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suffolklitlab/alkiln",
3
- "version": "5.7.0",
3
+ "version": "5.8.1-feat2columns1",
4
4
  "description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {