@suffolklitlab/alkiln 5.10.3 → 5.11.0

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
@@ -186,7 +186,7 @@ Given(/I start the interview at "([^"]+)"/, {timeout: -1}, async (file_name) =>
186
186
  // TODO: Move this to the `download` Step and only do it once per scenario
187
187
  // Allow developer to save download files
188
188
  let custom_download_behavior_timeout = new Promise(async ( resolve, reject ) => {
189
- let page_timeout = setTimeout(function() {reject( `Took too long to set download behavior.` ); }, scope.timeout);
189
+ let page_timeout = setTimeout(function() {reject( `🤕 ALK0057 ERROR: Took too long to set download behavior.` ); }, scope.timeout);
190
190
  // self-invoke an anonymous async function so we don't have to
191
191
  // abstract the details of resolving and rejecting.
192
192
  (async function() {
@@ -263,10 +263,11 @@ Given(/I go to "([^"]+)"/i, {timeout: -1}, async ( url ) => {
263
263
  let result = await wrapPromiseWithTimeout(
264
264
  scope.page.goto( url, { waitUntil: 'domcontentloaded', timeout: scope.timeout }),
265
265
  scope.timeout,
266
- `It took to long to get to "${ url }"`
266
+ // TODO: Turn this into a function
267
+ `🤕 ALK0058 ERROR: It took to long to get to "${ url }"`
267
268
  );
268
269
 
269
- reports.addToReport(scope, { type: `info`, value: `Successfully went to "${ url }"` });
270
+ reports.addToReport(scope, { type: `info`, code: `ALK0059`, value: `Successfully went to "${ url }"` });
270
271
  return result;
271
272
  });
272
273
 
@@ -355,7 +356,10 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
355
356
  + `too long to try to reach it (over ${ scope.timeout/1000/60 } min). The `
356
357
  + `test got stuck on "${ id }".`
357
358
  let error = non_reload_report_msg;
358
- await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
359
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
360
+ code: `ALK0060`,
361
+ message: non_reload_report_msg,
362
+ }, error });
359
363
  }; // Ends on_page_timeout()
360
364
  let page_timeout_id = setTimeout(on_page_timeout, scope.timeout);
361
365
 
@@ -376,9 +380,11 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
376
380
  from_story_table: true,
377
381
  });
378
382
 
379
- if ( session_vars.get_debug() ) {
380
- console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
381
- }
383
+ log.debug({
384
+ type: `info`,
385
+ code: `ALK0061`,
386
+ pre: `Rows, including special rows:, ${JSON.stringify( ensured_var_data )}`,
387
+ });
382
388
 
383
389
  // THIS FUNCTION ACTUALLY MATTERS
384
390
  // Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
@@ -388,7 +394,7 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
388
394
  resolve();
389
395
  } catch ( err ) {
390
396
  let err_msg = `Error occurred when tried to answer fields on question "${ id }".`
391
- reports.addToReport( scope, { type: `error`, value: err_msg });
397
+ reports.addToReport( scope, { type: `error`, code: `ALK0062`, value: err_msg });
392
398
  // Throw error instead?
393
399
  reject( err );
394
400
  } finally {
@@ -418,13 +424,13 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
418
424
 
419
425
  // Add full used table to report so it can be copied if needed.
420
426
  // TODO: Should we/How do we get this in the final scenario report instead of here?
421
- reports.addToReport( scope, { type: `note`, value: `\n${ ' '.repeat(2) }Rows that got set:` });
422
- reports.addToReport( scope, { type: `step`, value: `${ ' '.repeat(4) }And I get to the question id "${ target_id }" with this data:` });
423
- reports.addToReport(scope, { type: `row`, value: `${ ' '.repeat(6) }| var | value | trigger |`, });
427
+ reports.addToReport( scope, { type: `note info`, code: `ALK0063`, value: `\n${ ' '.repeat(2) }Rows that got set:` });
428
+ reports.addToReport( scope, { type: `step info`, code: `ALK0064`, value: `${ ' '.repeat(4) }And I get to the question id "${ target_id }" with this data:` });
429
+ reports.addToReport(scope, { type: `row info`, code: `ALK0065`, value: `${ ' '.repeat(6) }| var | value | trigger |`, });
424
430
  let at_least_one_row_was_NOT_used = false;
425
431
  for ( let row of sorted_rows ) {
426
432
  if ( row.times_used > 0 ) {
427
- reports.addToReport(scope, { type: `row`, value: row.report_str, });
433
+ reports.addToReport(scope, { type: `row info`, code: `ALK0066`, value: row.report_str, });
428
434
  } else {
429
435
  at_least_one_row_was_NOT_used = true;
430
436
  }
@@ -432,135 +438,19 @@ When(/^(?:the user gets)?(?:I get)? to ?(?:the)?(?: ?question)?(?: id)? "([^"]+)
432
438
 
433
439
  // Add unused rows if needed
434
440
  if ( at_least_one_row_was_NOT_used ) {
435
- reports.addToReport( scope, { type: `note`, value: `${ ' '.repeat(2) }Unused rows:` });
441
+ reports.addToReport( scope, { type: `note info`, code: `ALK0067`, value: `${ ' '.repeat(2) }Unused rows:` });
436
442
  for ( let row of sorted_rows ) {
437
443
  if ( row.times_used === 0 ) {
438
- reports.addToReport(scope, { type: `row`, value: row.report_str, });
444
+ reports.addToReport(scope, { type: `row info`, code: `ALK0068`, value: row.report_str, });
439
445
  }
440
446
  }
441
447
  } else {
442
- reports.addToReport(scope, { type: `note`, value: `${ ' '.repeat(2) }All rows were used` });
448
+ reports.addToReport(scope, { type: `note info`, code: `ALK0069`, value: `${ ' '.repeat(2) }All rows were used` });
443
449
  }
444
450
 
445
- reports.addToReport(scope, { type: `note`, value: `` });
451
+ reports.addToReport(scope, { type: `plain`, value: `` });
446
452
  });
447
453
 
448
- // When(/^foo id "([^"]+)"/, {timeout: -1}, async (target_id, raw_var_data) => {
449
- // /* NO CUCUMBER TIMEOUT. Must handle timeout ourselves:
450
- // * https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/timeouts.md#disable-timeouts
451
- // * Iterate in here to keep timeout reasonable */
452
-
453
- // // Note: Why do we not just stop when we've used all the vars in the table or
454
- // // reach the last var? Vars are not required to be given in sequence and pages that
455
- // // have non-button fields don't usually have a var assigned to the 'continue' button.
456
- // // Alternative: require vars even for 'continue' pages. Then in loop require at least one var
457
- // // to be found on a page before hitting 'continue'. That requires detecting navigation because
458
- // // pages with fields will not have a var for the continue button, so there will
459
- // // still have to be some automatic continuing.
460
- // // It also seems harsh, but more reliable.
461
- // // Ask developers what they'd like.
462
-
463
-
464
- // let supported_table = await scope.normalizeTable( scope, { raw_var_data });
465
-
466
- // let { question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id );
467
- // // Until we reach the target page, hit an error, or time out (take too long)
468
- // while ( !id_matches ) {
469
- // let custom_timeout = new Promise(function( resolve, reject ) {
470
-
471
- // // Set up the timeout that avoids infinite loops
472
- // let on_page_timeout = async function() {
473
-
474
- // let non_reload_report_msg = `The target id was "${ target_id }", but it took `
475
- // + `too long to try to reach it (over ${ scope.timeout/1000/60 } min). The `
476
- // + `test got stuck on "${ id }".`
477
- // let error = non_reload_report_msg;
478
- // await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
479
- // }; // Ends on_page_timeout()
480
- // let page_timeout_id = setTimeout(on_page_timeout, scope.timeout);
481
-
482
- // // self-invoke an anonymous async function so we don't have to
483
- // // abstract the details of resolving and rejecting.
484
- // // If we need to call recursively, signature function might look like:
485
- // // func( scope, { resolve, reject, supported_table, page_timeout_id })
486
- // // Maybe list of timeout and/or interval ids in state that can all be cleared at once?
487
- // (async function() {
488
- // try {
489
- // let { question_has_id, id, id_matches } = await scope.examinePageID( scope );
490
-
491
- // // Add special rows. Basically, do weirder things.
492
- // // TODO: Remove from_story_table - no longer needed if only called from in here
493
- // let ensured_var_data = await scope.ensureSpecialRows( scope, {
494
- // var_data: supported_table,
495
- // from_story_table: true,
496
- // });
497
-
498
- // if ( session_vars.get_debug() ) {
499
- // console.log( `Rows, including special rows:`, JSON.stringify( ensured_var_data ));
500
- // }
501
-
502
- // // Some errors happen in there to be closer to the relevant code. We'd have to try/catch anyway.
503
- // let error = await scope.setFields(scope, { var_data: ensured_var_data, id, ensure_navigation: true });
504
- // if ( error.was_found ) { await scope.throwPageError( scope, { id: id }); }
505
- // resolve();
506
- // } catch ( err ) {
507
- // let err_msg = `Error occurred when tried to answer fields on question "${ id }".`
508
- // reports.addToReport( scope, { type: `error`, value: err_msg });
509
- // // Throw error instead?
510
- // reject( err );
511
- // } finally {
512
- // clearTimeout( page_timeout_id ); // prevent temporary hang at end of tests
513
- // }
514
- // })();
515
- // }); // ends custom_timeout for setFields
516
-
517
- // await custom_timeout;
518
-
519
- // // Prep for next loop
520
- // ({ question_has_id, id, id_matches } = await scope.examinePageID( scope, target_id ));
521
-
522
- // } // ends while !id_matches
523
- // // Can anything unsatisfactory get through here?
524
-
525
- // // Add report strings from supported table, not an altered one
526
- // for ( let row of supported_table ) {
527
- // row.report_str = `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row }) }`;
528
- // }
529
- // // Sort into alphabetical order, as is recommended for writing story tables
530
- // let sorted_rows = supported_table.sort( function ( row1, row2 ) {
531
- // if( row1.report_str < row2.report_str ) { return -1; }
532
- // if( row1.report_str > row2.report_str ) { return 1; }
533
- // return 0;
534
- // });
535
-
536
- // // Add full used table to report so it can be copied if needed.
537
- // // TODO: Should we/How do we get this in the final scenario report instead of here?
538
- // reports.addToReport( scope, { type: `note`, value: `\n${ ' '.repeat(2) }Rows that got set:` });
539
- // reports.addToReport( scope, { type: `step`, value: `${ ' '.repeat(4) }And I get to the question id "${ target_id }" with this data:` });
540
- // reports.addToReport(scope, { type: `row`, value: `${ ' '.repeat(6) }| var | value | trigger |`, });
541
- // let at_least_one_row_was_NOT_used = false;
542
- // for ( let row of sorted_rows ) {
543
- // if ( row.times_used > 0 ) {
544
- // reports.addToReport(scope, { type: `row`, value: row.report_str, });
545
- // } else {
546
- // at_least_one_row_was_NOT_used = true;
547
- // }
548
- // }
549
-
550
- // // Add unused rows if needed
551
- // if ( at_least_one_row_was_NOT_used ) {
552
- // reports.addToReport( scope, { type: `note`, value: `${ ' '.repeat(2) }Unused rows:` });
553
- // for ( let row of sorted_rows ) {
554
- // if ( row.times_used === 0 ) {
555
- // reports.addToReport(scope, { type: `row`, value: row.report_str, });
556
- // }
557
- // }
558
- // } else {
559
- // reports.addToReport(scope, { type: `note`, value: `${ ' '.repeat(2) }All rows were used` });
560
- // }
561
-
562
- // reports.addToReport(scope, { type: `note`, value: `` });
563
- // });
564
454
 
565
455
  //#####################################
566
456
  //#####################################
@@ -609,15 +499,15 @@ Then(/the (?:question|page|screen) id should be "([^"]+)"/i, { timeout: -1 }, as
609
499
  // No question id exists
610
500
  let no_id_msg = `Did not find any question id.`;
611
501
  if ( !question_has_id ) {
612
- reports.addToReport( scope, { type: `error`, value: no_id_msg });
502
+ reports.addToReport( scope, { type: `error`, code: `ALK0070`, value: no_id_msg });
613
503
  }
614
504
  expect( question_has_id , no_id_msg ).to.be.true;
615
505
 
616
506
  // Wrong question id
617
507
  let no_match_msg = `The question id was supposed to be "${ question_id }"`
618
- + `, but it's actually "${ id }".`;
508
+ + `, but it is actually "${ id }".`;
619
509
  if ( !id_matches ) {
620
- reports.addToReport( scope, { type: `error`, value: no_match_msg });
510
+ reports.addToReport( scope, { type: `error`, code: `ALK0071`, value: no_match_msg });
621
511
  }
622
512
  expect( id_matches, no_match_msg ).to.be.true;
623
513
 
@@ -630,7 +520,7 @@ Then(/I ?(?:should)? see the phrase "([^"]+)"/i, async ( phrase ) => { // √
630
520
  const bodyText = await scope.page.$eval('body', elem => elem.innerText);
631
521
 
632
522
  let msg = `The text "${ phrase }" SHOULD be on this page, but it's NOT.`;
633
- if ( !bodyText.includes( phrase )) { reports.addToReport(scope, { type: `error`, value: msg }); }
523
+ if ( !bodyText.includes( phrase )) { reports.addToReport(scope, { type: `error`, code: `ALK0072`, value: msg }); }
634
524
  expect( bodyText, msg ).to.contain( phrase );
635
525
 
636
526
  await scope.afterStep(scope);
@@ -644,7 +534,7 @@ Then(/I should not see the phrase "([^"]+)"/i, async ( phrase ) => { // √
644
534
  const bodyText = await scope.page.$eval('body', elem => elem.innerText);
645
535
 
646
536
  let msg = `The text "${ phrase }" should NOT be on this page, but it IS here.`;
647
- if ( bodyText.includes( phrase )) { reports.addToReport(scope, { type: `error`, value: msg }); }
537
+ if ( bodyText.includes( phrase )) { reports.addToReport(scope, { type: `error`, code: `ALK0073`, value: msg }); }
648
538
  expect( bodyText, msg ).not.to.contain( phrase );
649
539
 
650
540
  await scope.afterStep(scope);
@@ -654,7 +544,7 @@ Then('an element should have the id {string}', async ( id ) => { // √
654
544
  const element = await scope.page.$('#' + id);
655
545
 
656
546
  let msg = `No element on this page has the ID "${ id }".`;
657
- if ( !element ) { reports.addToReport(scope, { type: `error`, value: msg }); }
547
+ if ( !element ) { reports.addToReport(scope, { type: `error`, code: `ALK0074`, value: msg }); }
658
548
  expect( element, msg ).to.exist;
659
549
 
660
550
  await scope.afterStep(scope);
@@ -709,7 +599,7 @@ Then(/I (don't|can't|don’t|can’t|cannot|do not) continue/, async (unused) =>
709
599
  * Can other things trigger navigation? Re: other inputs things
710
600
  * like 'Enter' acting like a click is a test for docassemble */
711
601
  let msg = `The page should have stopped the user from continuing, but the user was able to continue.`;
712
- if ( scope.navigated ) { reports.addToReport(scope, { type: `error`, value: msg }); }
602
+ if ( scope.navigated ) { reports.addToReport(scope, { type: `error`, code: `ALK0075`, value: msg }); }
713
603
  expect( scope.navigated, msg ).to.be.false;
714
604
 
715
605
  await scope.afterStep(scope);
@@ -720,12 +610,12 @@ Then('I will be told an answer is invalid', async () => { // √
720
610
  let { was_found, error_handlers } = await scope.checkForError( scope );
721
611
 
722
612
  let no_error_msg = `No error message was found on the page`;
723
- if ( !was_found ) { reports.addToReport(scope, { type: `error`, value: no_error_msg }); }
613
+ if ( !was_found ) { reports.addToReport(scope, { type: `error`, code: `ALK0076`, value: no_error_msg }); }
724
614
  expect( was_found, no_error_msg ).to.be.true;
725
615
 
726
616
  let was_user_error = error_handlers.complex_user_error !== undefined || error_handlers.simple_user_error !== undefined;
727
- let not_user_error_msg = `The error was a system error, not an invalid user answer. Check for the picture of the page's error if the step did not use any secret variables.`;
728
- if ( !was_user_error ) { reports.addToReport(scope, { type: `error`, value: not_user_error_msg }); }
617
+ let not_user_error_msg = `The error was a system error, not an invalid user answer. Check for the picture of the page's error if the Step did not use any secret variables.`;
618
+ if ( !was_user_error ) { reports.addToReport(scope, { type: `error`, code: `ALK0077`, value: not_user_error_msg }); }
729
619
  expect( was_user_error, not_user_error_msg ).to.be.true;
730
620
 
731
621
  await scope.afterStep(scope);
@@ -736,7 +626,7 @@ Then('I arrive at the next page', async () => { // √
736
626
  * Can other things trigger navigation? Re: other inputs things
737
627
  * like 'Enter' acting like a click is a test for docassemble */
738
628
  let msg = `User did not arrive at the next page.`
739
- if ( !scope.navigated ) { reports.addToReport(scope, { type: `error`, value: msg }); }
629
+ if ( !scope.navigated ) { reports.addToReport(scope, { type: `error`, code: `ALK0078`, value: msg }); }
740
630
  expect( scope.navigated, msg ).to.be.true;
741
631
  await scope.afterStep(scope);
742
632
  });
@@ -747,7 +637,7 @@ Then('I should see the link {string}', async ( linkText ) => { // √
747
637
  let [link] = await scope.page.$x(`//a[contains(text(), "${linkText}")]`);
748
638
 
749
639
  let msg = `Cannot find a link with the text "${ linkText }".`;
750
- if ( !link ) { reports.addToReport(scope, { type: `error`, value: msg }); }
640
+ if ( !link ) { reports.addToReport(scope, { type: `error`, code: `ALK0079`, value: msg }); }
751
641
  expect( link, msg ).to.exist;
752
642
 
753
643
  await scope.afterStep(scope);
@@ -758,7 +648,7 @@ Then('I should see the link to {string}', async ( url ) => { // √
758
648
  let link = await scope.page.$(`*[href="${ url }"]`);
759
649
 
760
650
  let msg = `Cannot find a link to "${ url }".`;
761
- if ( !link ) { reports.addToReport(scope, { type: `error`, value: msg }); }
651
+ if ( !link ) { reports.addToReport(scope, { type: `error`, code: `ALK0080`, value: msg }); }
762
652
  expect(link, msg ).to.exist;
763
653
 
764
654
  await scope.afterStep(scope);
@@ -774,7 +664,7 @@ Then(/the "([^"]+)" link leads to "([^"]+)"/, async (linkText, expected_url) =>
774
664
  let actual_url = await prop_obj.jsonValue();
775
665
 
776
666
  let msg = `Cannot find a link with the text "${ linkText }" leading to ${ expected_url }.`;
777
- if ( actual_url !== expected_url ) { reports.addToReport(scope, { type: `error`, value: msg }); }
667
+ if ( actual_url !== expected_url ) { reports.addToReport(scope, { type: `error`, code: `ALK0081`, value: msg }); }
778
668
  expect( actual_url ).to.equal( expected_url );
779
669
 
780
670
  await scope.afterStep(scope);
@@ -793,7 +683,7 @@ Then(/the "([^"]+)" link opens in (a new window|the same window)/, async (linkTe
793
683
  || ( !should_open_a_new_window && !opens_a_new_window );
794
684
 
795
685
  let msg = `The link "${ linkText }" does NOT open in ${ which_window }.`;
796
- if ( !hasCorrectWindowTarget ) { reports.addToReport(scope, { type: `error`, value: msg }); }
686
+ if ( !hasCorrectWindowTarget ) { reports.addToReport(scope, { type: `error`, code: `ALK0082`, value: msg }); }
797
687
  expect( hasCorrectWindowTarget, msg ).to.be.true;
798
688
 
799
689
  await scope.afterStep(scope);
@@ -828,6 +718,7 @@ Then(/(?:the )?text(?: in)?(?: the)?(?: JSON)?(?: var)?(?:iable)?(?: )?"([^"]+)"
828
718
  if ( actual_value !== expected_value ) {
829
719
  reports.addToReport( scope, {
830
720
  type: `error`,
721
+ code: `ALK0083`,
831
722
  value: `The variable "${ var_name }" was not equal to the expected `
832
723
  + `value on the "${ scope.page_id }" screen. Check `
833
724
  + `${ json_path } to see the page's JSON variables.`
@@ -925,7 +816,11 @@ When(/I check the page for (?:accessibility|a11y) issues/i, {timeout: -1}, async
925
816
  scope.checkForA11y(scope),
926
817
  scope.timeout
927
818
  )
928
- let msg = `Found potential accessibility issues on the ${ scope.page_id } screen. Details in ${ axe_filepath }.`;
819
+
820
+ let msg = `Found potential accessibility issues on the "${ scope.page_id }" screen. Details in ${ axe_filepath }.`;
821
+ if ( !passed ) {
822
+ reports.addToReport( scope, { type: `error`, code: `ALK0084`, value: msg });
823
+ }
929
824
  expect( passed, msg ).to.be.true;
930
825
  });
931
826
 
@@ -955,7 +850,8 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
955
850
  scope.paths.random_screenshots = random_input_path;
956
851
  fs.mkdirSync( scope.paths.random_screenshots );
957
852
  reports.addToReport( scope, {
958
- type: 'row',
853
+ type: 'row info',
854
+ code: `ALK0085`,
959
855
  value: `Testing interview with random input (in ${ random_input_path })`
960
856
  });
961
857
 
@@ -996,6 +892,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
996
892
  if ( !has_content ) {
997
893
  reports.addToReport( scope, {
998
894
  type: `error`,
895
+ code: `ALK0086`,
999
896
  value: no_content_err
1000
897
  });
1001
898
  reject( no_content_err );
@@ -1003,7 +900,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
1003
900
  } else {
1004
901
  let timeout_message = `The page with an id of "${ id }" took too long`
1005
902
  + ` to fill with random answers (over ${ scope.timeout/1000/60 } min).`
1006
- reports.addToReport( scope, { type: `error`, value: timeout_message });
903
+ reports.addToReport( scope, { type: `error`, code: `ALK0087`, value: timeout_message });
1007
904
  reject( timeout_message );
1008
905
  }
1009
906
 
@@ -1050,6 +947,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
1050
947
  has_thrown = true;
1051
948
  reports.addToReport( scope, {
1052
949
  type: `error`,
950
+ code: `ALK0088`,
1053
951
  value: no_content_err
1054
952
  });
1055
953
  reject( no_content_err );
@@ -1079,6 +977,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
1079
977
  if ( !has_content ) {
1080
978
  reports.addToReport( scope, {
1081
979
  type: `error`,
980
+ code: `ALK0089`,
1082
981
  value: no_content_err
1083
982
  });
1084
983
  reject( no_content_err );
@@ -1087,7 +986,7 @@ When(/I answer randomly for at most ([0-9]+) (?:page(?:s)?|screen(?:s)?)/, { tim
1087
986
  } else {
1088
987
  let err_msg = `The page with the question id "${ id }" errored when trying to fill`
1089
988
  + ` it with random answers: ${ error.name }`
1090
- reports.addToReport( scope, { type: `error`, value: err_msg });
989
+ reports.addToReport( scope, { type: `error`, code: `ALK0090`, value: err_msg });
1091
990
  reject( error );
1092
991
  } // ends if !has_content
1093
992
 
@@ -1287,8 +1186,7 @@ After(async function(scenario) {
1287
1186
 
1288
1187
  // Log errors
1289
1188
  if ( scenario.result.message ) {
1290
- log.debug({ type: `error`, pre: scenario.result.message });
1291
- // log.debug({ type: `error`, pre: scenario.result.message, verbose: true });
1189
+ log.debug({ type: `info`, code: `ALK0091`, pre: `cucumber error: ${ scenario.result.message }` }); //, verbose: true });
1292
1190
  }
1293
1191
 
1294
1192
  let changeable_test_status = scenario.result.status;
@@ -1298,7 +1196,8 @@ After(async function(scenario) {
1298
1196
  changeable_test_status = `FAILED`;
1299
1197
  reports.addToReport(scope, {
1300
1198
  type: `error`,
1301
- value: `Accessibility standards weren't met. See information above.`
1199
+ code: `ALK0092`,
1200
+ value: `Accessibility standards tests failed. See information above.`
1302
1201
  });
1303
1202
  }
1304
1203
 
@@ -1307,6 +1206,7 @@ After(async function(scenario) {
1307
1206
  changeable_test_status = `FAILED`;
1308
1207
  reports.addToReport(scope, {
1309
1208
  type: `error`,
1209
+ code: `ALK0093`,
1310
1210
  value: `PDF comparison failed ${ scope.failed_pdf_compares.length } time(s)\n---\n${ msg }\n---\n`
1311
1211
  });
1312
1212
  }
@@ -1315,15 +1215,18 @@ After(async function(scenario) {
1315
1215
  reports.setReportScenarioStatus( scope, { status: changeable_test_status });
1316
1216
 
1317
1217
  if (changeable_test_status !== `PASSED`) {
1318
- if ( session_vars.get_debug() ) {
1319
- console.log( `Non-passed status occurred while running test:`, changeable_test_status );
1320
- }
1218
+ log.debug({
1219
+ type: `error`,
1220
+ code: `ALK0094`,
1221
+ pre: `Non-passed status occurred while running test: ${changeable_test_status}`,
1222
+ });
1321
1223
 
1322
1224
  if ( scope.page ) {
1323
1225
 
1324
1226
  if ( !!scope.disable_error_screenshot ) {
1325
1227
  reports.addToReport(scope, {
1326
- type: `row`,
1228
+ type: `row info`,
1229
+ code: `ALK0095`,
1327
1230
  value: `For security, ALKiln will avoid creating a picture of the page for this error. It's possible a secret is being used on this screen.`
1328
1231
  });
1329
1232
  } else {
@@ -1347,7 +1250,7 @@ After(async function(scenario) {
1347
1250
 
1348
1251
  // This has to come after the security message or security message doesn't print. Not sure why.
1349
1252
  if (changeable_test_status === `FAILED`) {
1350
- reports.addToReport(scope, { type: `outcome`, value: `**-- Scenario Failed --**` });
1253
+ reports.addToReport(scope, { type: `outcome failure info`, code: `ALK0096`, value: `**-- Scenario Failed --**` });
1351
1254
  }
1352
1255
 
1353
1256
  } // ends if not passed
@@ -1407,11 +1310,14 @@ After(async function(scenario) {
1407
1310
  // TODO: Should a more specific message about signing out get into the report no matter what?
1408
1311
  // If so, what should the message be in order to not get confused with these other messages?
1409
1312
  let non_reload_report_msg = `It took too long to sign out in preparation for the next test.`;
1410
- await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
1313
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
1314
+ code: `ALK0097`,
1315
+ message: non_reload_report_msg,
1316
+ }, error });
1411
1317
  } else {
1412
1318
  // Throw any non-timeout error
1413
1319
  let err_msg = `Error occurred when ALKiln tried to sign out in preparation for the next test.`
1414
- reports.addToReport( scope, { type: `error`, value: err_msg });
1320
+ reports.addToReport( scope, { type: `error`, code: `ALK0098`, value: err_msg });
1415
1321
  throw error;
1416
1322
  } // ends if error is timeout error
1417
1323
 
@@ -1419,13 +1325,22 @@ After(async function(scenario) {
1419
1325
 
1420
1326
  } // ends if scope.page
1421
1327
 
1328
+ // INTERNAL WARNING: TODO: A console.log here prevents the try/catch from
1329
+ // throwing an error. Why is that? Does it somehow make sure that scope.page
1330
+ // gets destroyed?
1331
+
1332
+ // console.log('This stops try/catch from throwing an error in some cases.');
1333
+
1334
+ // More internal testing stuff
1422
1335
  if ( changeable_test_status === `FAILED` ) {
1423
1336
  // If the result object status wasn't failure and we still want
1424
1337
  // the tests to fail, as with a11y tests, we can't mess with the
1425
1338
  // cucumber result.status object because it will cause unwanted
1426
1339
  // errors. We have to throw an error here instead.
1427
1340
  if ( scenario.result.status !== `FAILED` ) {
1428
- throw new Error(`The test failed. See the report above for more information.`);
1341
+ let msg = `The test unexpectedly didn't fail. Scenario status: ${scenario.result.status}.`
1342
+ reports.addToReport( scope, { type: `error`, code: `ALK0099`, value: msg });
1343
+ throw new Error(msg);
1429
1344
  }
1430
1345
  } else {
1431
1346
  // Some internal test failures should be ok
@@ -1434,6 +1349,11 @@ After(async function(scenario) {
1434
1349
  // https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/api_reference.md#setdefinitionfunctionwrapperwrapper
1435
1350
  scenario.result.status = changeable_test_status;
1436
1351
  }
1352
+ // Ends more internal testing stuff
1353
+
1354
+ // WARNING: TODO: console.log can prevent a sign-out error. What race condition is going on?
1355
+ log.debug({ type: `cucumber`, code: `ALK0100`, verbose: true, pre: `Scenario AfterStep() message`, data: scenario.result.message });
1356
+
1437
1357
  });
1438
1358
 
1439
1359
  AfterAll(async function() {
package/lib/utils/log.js CHANGED
@@ -1,64 +1,87 @@
1
1
  const fs = require('fs');
2
2
  const session_vars = require( './session_vars' );
3
3
 
4
+ // ? 🌈 💡 🔎 🤕 🐞
5
+
4
6
  let log = {};
5
7
  module.exports = log;
6
8
 
7
- let create_msg_start = function ( types, pre='' ) {
8
- let parts = [ `ALKiln`, ...types ];
9
- let start = parts.join(` `);
10
- return `${ start }: ${ pre }`;
9
+ let create_msg_start = function ( types, pre='', code=`? ALK0000` ) {
10
+ // ? - unknown (fallback)
11
+ let types_str = types.join(` `);
12
+ if ( types_str.includes(`plain`) ) {
13
+ return pre;
14
+ } else {
15
+ return `${ code } ${ types_str }: ${ pre }`;
16
+ }
11
17
  };
12
18
 
13
- log.info = function ({ type='', pre='', data='', post='' }) {
14
- /* Log info msg with the given information and strings, prepended with `ALKiln`.
15
- * `type` is often something like 'setup', 'takedown', etc. */
16
- let start = create_msg_start([ type ], pre );
19
+ // Where is this used?
20
+ log.success = function ({ type='', pre='', data='', post='', code=`ALK0000` }) {
21
+ /** Log success msg with the given information and strings, prepended with `ALKiln`.
22
+ * `type` is often something like 'setup', 'takedown', etc. */
23
+ // √ - info (fallback)
24
+ let start = create_msg_start([ type, `SUCCESS` ], pre, `🌈 ${code}` );
17
25
  // Log them each on a separate line
18
26
  console.info( `${ start }` );
19
27
  if ( data ) { console.info( data ); }
20
28
  if ( post ) { console.info( post ); }
21
29
  };
22
30
 
23
- log.warn = function ({ type='', pre='', data='', post='' }) {
24
- /* Log warning msg with the given information and strings, prepended with `ALKiln`.
25
- * `type` is often something like 'setup', 'takedown', etc. */
26
- let start = create_msg_start([ type, `WARNING` ], pre );
31
+ // Where is this used?
32
+ log.info = function ({ type='', pre='', data='', post='', code=`ALK0000` }) {
33
+ /** Log info msg with the given information and strings, prepended with `ALKiln`.
34
+ * `type` is often something like 'setup', 'takedown', etc. */
35
+ // & - info (fallback)
36
+ let start = create_msg_start([ type, `INFO` ], pre, `💡 ${code}` );
37
+ // Log them each on a separate line
38
+ console.info( `${ start }` );
39
+ if ( data ) { console.info( data ); }
40
+ if ( post ) { console.info( post ); }
41
+ };
42
+
43
+ // Where is this used?
44
+ log.warn = function ({ type='', pre='', data='', post='', code=`ALK0000` }) {
45
+ /** Log warning msg with the given information and strings, prepended with `ALKiln`.
46
+ * `type` is often something like 'setup', 'takedown', etc. */
47
+ // ! - warning (fallback)
48
+ let start = create_msg_start([ type, `WARNING` ], pre, `🔎 ${code}` );
27
49
  // Log them each on a separate line
28
50
  console.warn( `${ start }` );
29
51
  if ( data ) { console.warn( data ); }
30
52
  if ( post ) { console.warn( post ); }
31
53
  };
32
54
 
33
- log.error = function ({ type='', pre='', data='', post='' }) {
34
- /* Log error msg with the given information and strings, prepended with `ALKiln`.
35
- * `type` is often something like 'setup', 'takedown', etc. */
36
- let start = create_msg_start([ type, `ERROR` ], pre );
55
+ // Where is this used?
56
+ log.error = function ({ type='', pre='', data='', post='', code=`ALK0000` }) {
57
+ /** Log error msg with the given information and strings, prepended with `ALKiln`.
58
+ * `type` is often something like 'setup', 'takedown', etc. */
59
+ // X - error (fallback)
60
+ let start = create_msg_start([ type, `ERROR` ], pre, `🤕 ${code}` );
37
61
  // Log them each on a separate line with extra new lines around the whole thing
38
62
  console.error( `\n${ start }` );
39
63
  if ( data ) { console.error( data ); }
40
64
  if ( post ) { console.error( post, `\n` ); }
41
65
  };
42
66
 
43
- log.debug = function ({ type='', pre='', data='', post='', verbose=false }) {
44
- /* If debugging is turned on, log a message that includes `ALKiln` and `debug` */
45
- if ( session_vars.get_debug() || verbose ) {
46
- let start = create_msg_start([ type, 'debug' ], pre );
47
- let full = `\n${ start }`;
67
+ log.debug = function ({ type='', pre='', data='', post='', verbose=false, code=`ALK0000` }) {
68
+ /** If debugging is turned on, log a message that includes `ALKiln` and `debug` */
69
+ // @ - debug (fallback)
70
+ let start = create_msg_start([ type, `DEBUG` ], pre, `🐞 ${ code }` );
71
+ let full = `\n${ start }`;
72
+ if ( data ) { full += `\n${ data }`; }
73
+ if ( post ) { full += `\n${ post }`; }
74
+
75
+ // TODO: Make a verbose log instead of adding to the debug one and always add to it
76
+ if ( verbose ) {
77
+ log.add_to_debug_log( full );
78
+ }
79
+
80
+ if ( session_vars.get_debug() ) {
48
81
  // Log them each on a separate line
49
82
  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
- }
83
+ console.log( data );
84
+ console.log( post );
62
85
  }
63
86
  };
64
87