@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/scope.js CHANGED
@@ -228,7 +228,7 @@ module.exports = {
228
228
  let error_text_prop = await error_elem.getProperty( 'textContent' );
229
229
  let system_error_text = await error_text_prop.jsonValue();
230
230
 
231
- reports.addToReport(scope, { type: `error`, value: system_error_text });
231
+ reports.addToReport(scope, { type: `error`, code: `ALK0101`, value: system_error_text });
232
232
  throw system_error_text;
233
233
  };
234
234
 
@@ -289,7 +289,7 @@ module.exports = {
289
289
  * `click_promise can be any kind of Promise, including a Promise.all()
290
290
  */
291
291
  let msg = `Cannot find the element to tap.`;
292
- if ( !elem ) { reports.addToReport(scope, { type: `error`, value: msg }); }
292
+ if ( !elem ) { reports.addToReport(scope, { type: `error`, code: `ALK0102`, value: msg }); }
293
293
  expect( elem, msg ).to.exist;
294
294
 
295
295
  // Get the text on the button or link for a potential error message later
@@ -312,11 +312,14 @@ module.exports = {
312
312
 
313
313
  if ( error.name === `TimeoutError` ) {
314
314
  let non_reload_report_msg = `After ALKiln tapped "${ tapperText }" it took too long to load the next page.`;
315
- await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
315
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
316
+ code: `ALK0103`,
317
+ message: non_reload_report_msg,
318
+ }, error });
316
319
  } else {
317
320
  // Throw any non-timeout error
318
321
  let err_msg = `An error occurred when ALKiln tried to tap "${ tapperText }".`
319
- reports.addToReport( scope, { type: `error`, value: err_msg });
322
+ reports.addToReport( scope, { type: `error`, code: `ALK0104`, value: err_msg });
320
323
  throw error;
321
324
  } // ends if error is timeout error
322
325
 
@@ -367,10 +370,10 @@ module.exports = {
367
370
  // actual_error: ,
368
371
  // }) {}, // Ends scope.handle_possible_timeout()
369
372
 
370
- handle_page_timeout_error: async function( scope, { non_reload_report_msg, error } ) {
373
+ handle_page_timeout_error: async function( scope, { non_reload_report_data, error } ) {
371
374
  /* For a page timeout error, handles server reload vs. other timeout errors
372
375
 
373
- @param options.non_reload_report_msg { str } Non-reload message to add to
376
+ @param options.non_reload_report_data { str } Non-reload message to add to
374
377
  the report as an error.
375
378
  @param options.error { object | str } Error to throw. It can be the actual
376
379
  error object or a string that will show up as a message in the error.
@@ -387,7 +390,8 @@ module.exports = {
387
390
  // Otherwise just throw the error
388
391
  reports.addToReport( scope, {
389
392
  type: `error`,
390
- value: non_reload_report_msg });
393
+ code: non_reload_report_data.code,
394
+ value: non_reload_report_data.message });
391
395
  throw error;
392
396
  }
393
397
  }, // Ends scope.handle_page_timeout_error()
@@ -447,7 +451,7 @@ module.exports = {
447
451
  + `${ Math.round( ms_till_server_timeout/1000 ) } seconds to respond. `
448
452
  + `If the server was just reloading and needed more time, try setting the `
449
453
  + `"SERVER_RELOAD_TIMEOUT_SECONDS" GitHub secret to a longer amount of time.`
450
- reports.addToReport( scope, { type: `error`, value: timeout_message });
454
+ reports.addToReport( scope, { type: `error`, code: `ALK0105`, value: timeout_message });
451
455
  }
452
456
 
453
457
  // Once server has responded, throw an error to end the test. After the first
@@ -467,8 +471,7 @@ module.exports = {
467
471
  let reload_failure_msg = `The test was unable to continue because it `
468
472
  + `took too long to reach the server. ALKiln will try this Scenario a total of `
469
473
  + `2 times. A full error will be printed for the second attempt.`;
470
- reports.addToReport( scope, { type: `error`, value: reload_failure_msg });
471
- // reports.addToReport( scope, { type: `error`, value: timeout_message });
474
+ reports.addToReport( scope, { type: `error`, code: `ALK0106`, value: reload_failure_msg });
472
475
  // clearTimeout( server_timeout_id );
473
476
  throw( reload_failure_msg );
474
477
  }, // Ends scope.throw_server_was_reloading_error()
@@ -541,7 +544,7 @@ module.exports = {
541
544
  let elem = await scope.page.$(`#${tab_id}`);
542
545
  let error_msg = `Couldn't find the tab with id "#${tab_id}" on the page, is there a typo?`;
543
546
  if ( !elem ) {
544
- reports.addToReport(scope, { type: `error`, value: error_msg });
547
+ reports.addToReport(scope, { type: `error`, code: `ALK0107`, value: error_msg });
545
548
  }
546
549
  expect( elem, error_msg ).to.exist;
547
550
  await scope.tapElementAndStayOnPage(scope, { elem });
@@ -552,7 +555,7 @@ module.exports = {
552
555
  /** Return if there were any violations and the file containing aXe output with more details of the checks */
553
556
  let { id } = await scope.examinePageID( scope, 'none to match' );
554
557
  if ( scope.page_id !== id ) {
555
- reports.addToReport(scope, { type: `page_id`, value: `${ id }`, });
558
+ reports.addToReport(scope, { type: `page_id info`, code: `ALK0108`, value: `${ id }`, });
556
559
  scope.page_id = id;
557
560
  }
558
561
  const axe = new AxePuppeteer(scope.page);
@@ -573,9 +576,9 @@ module.exports = {
573
576
  axe_path = await scope.getA11yPath( scope );
574
577
  fs.writeFileSync( axe_path, JSON.stringify( axe_result, null, 2 ));
575
578
  let msg = `Found potential accessibility issues on the ${ scope.page_id } screen. Details in ${ axe_path }.`;
576
- reports.addToReport( scope, { type: `error`, value: msg });
579
+ reports.addToReport( scope, { type: `error`, code: `ALK0109`, value: msg });
577
580
  } else {
578
- reports.addToReport(scope, { type: `info`, value: `Accessibility on ${ scope.page_id } passed!`})
581
+ reports.addToReport(scope, { type: `row info`, code: `ALK0110`, value: `Accessibility on ${ scope.page_id } passed!`})
579
582
  }
580
583
  return {
581
584
  passed: axe_result.violations.length == 0,
@@ -587,7 +590,7 @@ module.exports = {
587
590
  let elem = await scope.page.$(`${ selector }`);
588
591
  let error_msg = `Couldn't find "${ selector }" on the page, is there a typo?`;
589
592
  if ( !elem ) {
590
- reports.addToReport(scope, { type: `error`, value: error_msg });
593
+ reports.addToReport(scope, { type: `error`, code: `ALK0111`, value: error_msg });
591
594
  }
592
595
  expect( elem, error_msg ).to.exist;
593
596
  await scope.tapElementAndNavigate( scope, { elem, waitForTimeout });
@@ -597,7 +600,7 @@ module.exports = {
597
600
  let elem = await scope.page.$(`${ selector }`);
598
601
  let error_msg = `Couldn't find "${ selector }" on the page, is there a typo?`;
599
602
  if ( !elem ) {
600
- reports.addToReport(scope, { type: `error`, value: error_msg });
603
+ reports.addToReport(scope, { type: `error`, code: `ALK0112`, value: error_msg });
601
604
  }
602
605
  expect( elem, error_msg ).to.exist;
603
606
  await scope.tapElementAndStayOnPage(scope, { elem });
@@ -625,7 +628,8 @@ module.exports = {
625
628
  }
626
629
 
627
630
  reports.addToReport(scope,{
628
- type: `row`,
631
+ code: `ALK0113`,
632
+ type: `row info`,
629
633
  value: `Trying to load the interview at "${ interview_url }"`
630
634
  });
631
635
 
@@ -642,7 +646,10 @@ module.exports = {
642
646
  if ( error.name === `TimeoutError` ) {
643
647
 
644
648
  let non_reload_report_msg = `Timeout error occurred when ALKiln tried to go to the interview at ${ interview_url }`;
645
- await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
649
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
650
+ code: `ALK0114`,
651
+ message: non_reload_report_msg,
652
+ }, error });
646
653
  // TODO: Should this throw to avoid multiple error messages?
647
654
 
648
655
  // If the page didn't load because of any other reason
@@ -651,6 +658,7 @@ module.exports = {
651
658
  // Throw any non-timeout error
652
659
  reports.addToReport( scope, {
653
660
  type: `error`,
661
+ code: `ALK0115`,
654
662
  value: `Error occurred when ALKiln tried to go to the interview at ${ interview_url }`
655
663
  });
656
664
  throw( error );
@@ -661,10 +669,14 @@ module.exports = {
661
669
  let load_result = await scope.getLoadData( scope );
662
670
  // da page invalidation errors or timeout will show an error to the developer at the end
663
671
  if ( load_result.error ) {
664
- reports.addToReport(scope, { type: `error`, value: `On final attempt to load interview at "${ interview_url }", got "${ load_result.error }"` });
672
+ reports.addToReport(scope, {
673
+ type: `error`,
674
+ code: `ALK0116`,
675
+ value: `On final attempt to load interview at "${ interview_url }", got "${ load_result.error }"`
676
+ });
665
677
  expect( load_result.error ).to.equal( '' );
666
678
  } else {
667
- reports.addToReport(scope, { type: `info`, value: `Successfully found the interview at "${ interview_url }"` });
679
+ reports.addToReport(scope, { type: `row info`, code: `ALK0117`, value: `Successfully found the interview at "${ interview_url }"` });
668
680
  }
669
681
 
670
682
  return scope.page;
@@ -698,7 +710,8 @@ module.exports = {
698
710
  } else {
699
711
  reports.addToReport(scope, {
700
712
  type: `error`,
701
- value: `ALKiln got an error when it tried to load the interview page`,
713
+ code: `ALK0118`,
714
+ value: `ALKiln got an error when it tried to load the interview page.`,
702
715
  data: error
703
716
  });
704
717
  throw error;
@@ -738,7 +751,7 @@ module.exports = {
738
751
  if (!var_data && !raw_var_data) {
739
752
  let no_data_msg = `ALKiln Internal error: normalizeTable called w/o var_data or raw_var_data:` +
740
753
  ` open an issue at https://github.com/SuffolkLITLab/ALKiln/issues/new if you see this!`;
741
- reports.addToReport( scope, { type: `error`, value: no_data_msg });
754
+ reports.addToReport( scope, { type: `error`, code: `ALK0119`, value: no_data_msg });
742
755
  throw Error(no_data_msg);
743
756
  }
744
757
 
@@ -759,7 +772,7 @@ module.exports = {
759
772
  let bad_table_msg = `Your Story Table should have ${ more_or_less } than`
760
773
  + ` ${ row_raw.length } columns. Take another look at Story Table documentation at`
761
774
  + ` https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/alkiln/#story-tables.`
762
- reports.addToReport( scope, { type: `error`, value: bad_table_msg})
775
+ reports.addToReport( scope, { type: `error`, code: `ALK0120`, value: bad_table_msg})
763
776
  throw Error(bad_table_msg);
764
777
  }
765
778
 
@@ -786,7 +799,7 @@ module.exports = {
786
799
  + ` Check for a typo and check your workflow file.`
787
800
  + ` Read more about using GitHub secrets in your workflow file at`
788
801
  + ` https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/alkiln/#github-secrets.`
789
- reports.addToReport( scope, { type: `error`, value: not_in_env_msg });
802
+ reports.addToReport( scope, { type: `error`, code: `ALK0121`, value: not_in_env_msg });
790
803
  throw ReferenceError(not_in_env_msg);
791
804
  }
792
805
  } // ends if is secret var
@@ -812,9 +825,10 @@ module.exports = {
812
825
  } // ends for every row
813
826
 
814
827
  log.debug({
828
+ code: `ALK0122`,
815
829
  type: `info`,
816
830
  pre: `scope.normalizedTable():\n ${JSON.stringify( supported_table )}`
817
- })
831
+ });
818
832
 
819
833
  return supported_table;
820
834
  }, // Ends scope.normalizeTable()
@@ -894,6 +908,7 @@ module.exports = {
894
908
  } else {
895
909
  reports.addToReport(scope, {
896
910
  type: `error`,
911
+ code: `ALK0123`,
897
912
  value: `You cannot sign a signature page this way because the `
898
913
  + `interview's HTML is missing data. Use the "I sign" Step `
899
914
  + `instead. You can also read documentation about `
@@ -963,7 +978,11 @@ module.exports = {
963
978
  fields.push( field_data );
964
979
  } // ends for every node
965
980
 
966
- if ( session_vars.get_debug() ) { console.log( `page fields:\n${ JSON.stringify( fields )}`); }
981
+ log.debug({
982
+ code: `ALK0124`,
983
+ type: `info`,
984
+ pre: `page fields:\n${ JSON.stringify( fields )}`
985
+ });
967
986
  return fields;
968
987
  }, // Ends scope.getAllFields()
969
988
 
@@ -1003,7 +1022,7 @@ module.exports = {
1003
1022
  // Exceptions: Some specific fields can be duplicates without being dangerous
1004
1023
  if ( matching_nodes.length > 1 && !selector.includes(`[class="file-caption-name"]`) ) {
1005
1024
  let msg = `${ matching_nodes.length } items on this page matched the base64 encoded name '${ selector }'. You may be setting the same variable in multiple places on this page.`;
1006
- reports.addToReport(scope, { type: `warning`, value: msg });
1025
+ reports.addToReport(scope, { type: `warning`, code: `ALK0125`, value: msg });
1007
1026
  }
1008
1027
 
1009
1028
  return selector;
@@ -1013,7 +1032,11 @@ module.exports = {
1013
1032
  /* Return variable names and values combined in ways that can
1014
1033
  * try to match table rows. Tables can have two properties:
1015
1034
  * variable name and value. */
1016
- if ( session_vars.get_debug() ) { console.log(`scope.getPossibleTableRowMatchers() var_names:`, var_names, `values:`, values); }
1035
+ log.debug({
1036
+ code: `ALK0126`,
1037
+ type: `info`,
1038
+ pre: `scope.getPossibleTableRowMatchers() var_names: ${JSON.stringify(var_names)} values: ${JSON.stringify(values)}`
1039
+ });
1017
1040
  let possible_table_rows = [];
1018
1041
  for ( let var_name of var_names ) {
1019
1042
  // Inputs like textareas don't have values
@@ -1392,7 +1415,7 @@ module.exports = {
1392
1415
  + `variable or a generic object, but the page is missing `
1393
1416
  + `the ALKiln "trigger" variable's name. See `
1394
1417
  + `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/alkiln/#a-missing-trigger-variable.`;
1395
- reports.addToReport(scope, { type: `warning`, value: page_trigger_warning });
1418
+ reports.addToReport(scope, { type: `warning`, code: `ALK0127`, value: page_trigger_warning });
1396
1419
  }
1397
1420
 
1398
1421
  for ( let row_that_matches_this_field of rows_that_match_field_names ) {
@@ -1411,7 +1434,7 @@ module.exports = {
1411
1434
  + `column, but it is empty. The test might get unexpected results. See `
1412
1435
  + `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/alkiln/#trigger.`
1413
1436
  + `\nThe rows:\n${ row_as_story_table }`;
1414
- reports.addToReport(scope, { type: `warning`, value: row_trigger_warning });
1437
+ reports.addToReport(scope, { type: `warning`, code: `ALK0128`, value: row_trigger_warning });
1415
1438
 
1416
1439
  rows_without_a_trigger_name.push( row_that_matches_this_field );
1417
1440
  } else {
@@ -1451,6 +1474,7 @@ module.exports = {
1451
1474
  + `\nThis field's data:\n${ JSON.stringify( field )}`;
1452
1475
  reports.addToReport(scope, {
1453
1476
  type: `warning`,
1477
+ code: `ALK0129`,
1454
1478
  value: all_trigger_names_conflict_msg
1455
1479
  });
1456
1480
  }
@@ -1479,15 +1503,22 @@ module.exports = {
1479
1503
  }
1480
1504
  multiple_matches_msg += `\nThe matching rows:\n${ rows_as_story_table.join(`\n`) }`
1481
1505
  + `\nThis field's data:\n${ JSON.stringify( field )}`;
1482
- reports.addToReport(scope, { type: `warning`, value: multiple_matches_msg });
1506
+ reports.addToReport(scope, { type: `warning`, code: `ALK0130`, value: multiple_matches_msg });
1483
1507
  }
1484
1508
 
1485
- if ( session_vars.get_debug() ) {
1486
- console.log( `final_matching_rows:\n`, JSON.stringify( final_matching_rows ));
1487
- if ( final_matching_rows.length == 0) {
1488
- console.log(` field:\n`, JSON.stringify( field ) );
1489
- }
1509
+ log.debug({
1510
+ code: `ALK0131`,
1511
+ type: `info`,
1512
+ pre: `final_matching_rows:\n${JSON.stringify( final_matching_rows )}`
1513
+ });
1514
+ if ( final_matching_rows.length == 0) {
1515
+ log.debug({
1516
+ code: `ALK0132`,
1517
+ type: `info`,
1518
+ pre: `field:\n${JSON.stringify( field )}`
1519
+ });
1490
1520
  }
1521
+
1491
1522
  return final_matching_rows;
1492
1523
  }, // Ends scope.getMatchingRows()
1493
1524
 
@@ -1571,9 +1602,11 @@ module.exports = {
1571
1602
 
1572
1603
  get_handle_from_field: async function ( scope, { field }) {
1573
1604
  /** Get the element's puppeteer handle using the field's selector. */
1574
- if ( session_vars.get_debug() ) {
1575
- console.log(`scope.get_handle_from_field() field.selector:`, field.selector );
1576
- }
1605
+ log.debug({
1606
+ code: `ALK0133`,
1607
+ type: `info`,
1608
+ pre: `scope.get_handle_from_field() field.selector: ${JSON.stringify(field.selector)}`
1609
+ });
1577
1610
  let handle = await scope.page.evaluateHandle(( selector ) => {
1578
1611
  let elem = document.querySelector( selector );
1579
1612
  // If the element has a sibling that's a label, we need to
@@ -1664,6 +1697,7 @@ module.exports = {
1664
1697
  // Return field unused.
1665
1698
  reports.addToReport( scope, {
1666
1699
  type: `warning`,
1700
+ code: `ALK0134`,
1667
1701
  value: `Invalid date. Value given: "${ answer }".`
1668
1702
  });
1669
1703
  return false;
@@ -1882,6 +1916,7 @@ module.exports = {
1882
1916
  if ( to_find_names.length === 0 ) {
1883
1917
  reports.addToReport( scope, {
1884
1918
  type: `warning`,
1919
+ code: `ALK0135`,
1885
1920
  value: `Your Step is missing the names of which file(s) to use.`
1886
1921
  });
1887
1922
  return [];
@@ -1914,6 +1949,7 @@ module.exports = {
1914
1949
  if ( missing_files.length > 0 ) {
1915
1950
  reports.addToReport( scope, {
1916
1951
  type: `warning`,
1952
+ code: `ALK0136`,
1917
1953
  value: `ALKiln could not find "${ missing_files.join('", "') }" in the folder(s) at "${ sources_dirs.join('", "') }".`
1918
1954
  });
1919
1955
  }
@@ -1979,6 +2015,9 @@ module.exports = {
1979
2015
  const typing_cutoff = 300;
1980
2016
  const slice_value = -3;
1981
2017
 
2018
+ // Deleting preexisting text here is slower, but more clear and maintainable
2019
+ await handle.evaluate(( elem ) => { elem.value = ``; });
2020
+
1982
2021
  let is_ajax = await handle.evaluate(( elem, text, typing_cutoff, slice_value ) => {
1983
2022
  // For long strings or ajax comboboxes, set the value of the field to
1984
2023
  // most of the text. This will be faster in those cases.
@@ -2011,7 +2050,7 @@ module.exports = {
2011
2050
  * takes a while to load. */
2012
2051
  let canvas = await scope.page.waitForSelector( `#dasigcanvas` );
2013
2052
  let msg = `Could not find a signature field.`;
2014
- if ( !canvas ) { reports.addToReport(scope, { type: `error`, value: msg }); }
2053
+ if ( !canvas ) { reports.addToReport(scope, { type: `error`, code: `ALK0137`, value: msg }); }
2015
2054
  expect( canvas, msg ).to.exist;
2016
2055
 
2017
2056
  // Provides functionality to draw name arg on canvas
@@ -2079,12 +2118,12 @@ module.exports = {
2079
2118
  * @param ensure_all_vars_used {bool} [false] = Default false. If true, errors if any
2080
2119
  * object in var_data is not used during running of this function.
2081
2120
  */
2082
- if ( session_vars.get_debug() ) { console.log( `~~~~~~~~~~~~~~ scope.setFields() ~~~~~~~~~~~~~~` ); }
2121
+ log.debug({ type: `plain`, pre: `~~~~~~~~~~~~~~ scope.setFields() ~~~~~~~~~~~~~~` });
2083
2122
 
2084
2123
  // Only record the page id once for each page to which we navigate
2085
2124
  let { id } = await scope.examinePageID( scope, 'none to match' );
2086
2125
  if ( scope.page_id !== id ) {
2087
- reports.addToReport(scope, { type: `page_id`, value: `${ id }`, });
2126
+ reports.addToReport(scope, { type: `page_id info`, code: `ALK0138`, value: `${ id }`, });
2088
2127
  scope.page_id = id;
2089
2128
  }
2090
2129
 
@@ -2115,7 +2154,8 @@ module.exports = {
2115
2154
  something_new_was_set = true;
2116
2155
  field.was_set = true;
2117
2156
  reports.addToReport(scope, {
2118
- type: `row`,
2157
+ type: `row info`,
2158
+ code: `ALK0139`,
2119
2159
  value: `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row_used }) }`
2120
2160
  });
2121
2161
 
@@ -2142,7 +2182,8 @@ module.exports = {
2142
2182
  if ( row_used ) {
2143
2183
 
2144
2184
  reports.addToReport(scope, {
2145
- type: `row`,
2185
+ type: `row info`,
2186
+ code: `ALK0140`,
2146
2187
  value: `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row_used }) }`
2147
2188
  });
2148
2189
 
@@ -2187,7 +2228,7 @@ module.exports = {
2187
2228
  let msg = `In a linear Step all the values you give MUST be filled in, but ALKiln was unable `
2188
2229
  + `to find a field on the page "${id}" for the variable "${ original_row.var }" that `
2189
2230
  + `could be set to "${ original_row.value }". See this Scenario's HTML file for details.`;
2190
- reports.addToReport(scope, { type: `error`, value: msg });
2231
+ reports.addToReport(scope, { type: `error`, code: `ALK0141`, value: msg });
2191
2232
  expect( values_used_status, msg ).to.equal( '' );
2192
2233
  }
2193
2234
  }
@@ -2378,12 +2419,14 @@ module.exports = {
2378
2419
  // probably add a confusing message to the report, so mutating seems, sadly, more useful.
2379
2420
  var_datum.value = `False`; // The original value is still preserved
2380
2421
  // Warn the developer not to use `.there_is_another`.
2381
- reports.addToReport( scope, { type: `warning`,
2382
- value: 'The attribute `.there_is_another` is invalid in story table tests. Replace it with '
2383
- + '`.target_number` in your `var` and `trigger` columns. Set the `value` to the number of items in '
2384
- + `that list. This test will now set this row's \`value\` to \`False\`. See `
2385
- + `https://suffolklitlab.github.io/docassemble-AssemblyLine-documentation/docs/alkiln#there_is_another. `
2386
- + `The row data is\n${ JSON.stringify( var_datum.original )}` });
2422
+ reports.addToReport( scope, {
2423
+ type: `warning`,
2424
+ code: `ALK0142`,
2425
+ value: 'The attribute `.there_is_another` is invalid in story table tests. Replace it with '
2426
+ + '`.target_number` in your `var` and `trigger` columns. Set the `value` to the number of items in '
2427
+ + `that list. This test will now set this row's \`value\` to \`False\`. See `
2428
+ + `https://suffolklitlab.github.io/docassemble-AssemblyLine-documentation/docs/alkiln/writing/#there_is_another. `
2429
+ + `The row data is\n${ JSON.stringify( var_datum.original )}` });
2387
2430
  } // ends if it's a `target_number` row
2388
2431
  } // ends for each row
2389
2432
 
@@ -2412,10 +2455,10 @@ module.exports = {
2412
2455
  } else if ( value.match( /(true|yes|checked|check|selected|select)/i )) {
2413
2456
  if ( from_story_table && !row.artificial ) {
2414
2457
  if ( row.var.match( /\.there_is_another$/ ) ) {
2415
- reports.addToReport( scope, { type: `warning`, value: `The attribute \`.there_is_another\` is invalid in story table tests. Replace it with \`.target_number\` in your \`var\` column. Set the \`value\` to the number of items in that list. This test will now set this row's \`value\` to \`False\`. See https://suffolklitlab.github.io/docassemble-AssemblyLine-documentation/docs/alkiln#there_is_another-loop. The row data is\n${ JSON.stringify( row.original )}` });
2458
+ reports.addToReport( scope, { type: `warning`, code: `ALK0143`, value: `The attribute \`.there_is_another\` is invalid in story table tests. Replace it with \`.target_number\` in your \`var\` column. Set the \`value\` to the number of items in that list. This test will now set this row's \`value\` to \`False\`. See https://suffolklitlab.github.io/docassemble-AssemblyLine-documentation/docs/alkiln/writing/#there_is_another. The row data is\n${ JSON.stringify( row.original )}` });
2416
2459
  } else {
2417
2460
  // If `target_number` is set to True instead of a number
2418
- reports.addToReport( scope, { type: `warning`, value: `${ val_to_print } value is not a valid value for ${ row.var } here. This test will default to \`False\` to avoid problems.` });
2461
+ reports.addToReport( scope, { type: `warning`, code: `ALK0144`, value: `${ val_to_print } value is not a valid value for ${ row.var } here. This test will default to \`False\` to avoid problems.` });
2419
2462
  }
2420
2463
  return `False`;
2421
2464
  } else { return `True`; }
@@ -2423,7 +2466,7 @@ module.exports = {
2423
2466
  } else if ( isNaN( desired_num )) { // Story table loop will end
2424
2467
  // I can't figure out how to trigger this warning, so maybe we're
2425
2468
  // already handling everything we need to
2426
- reports.addToReport( scope, { type: `warning`, value: `${ val_to_print } value is not a valid value for ${ row.var } here. This test will default to \`False\` to avoid problems.` });
2469
+ reports.addToReport( scope, { type: `warning`, code: `ALK0145`, value: `${ val_to_print } value is not a valid value for ${ row.var } here. This test will default to \`False\` to avoid problems.` });
2427
2470
  return `False`;
2428
2471
 
2429
2472
  // Check that the number of elements in the list hits our desired number.
@@ -2479,7 +2522,7 @@ module.exports = {
2479
2522
  }
2480
2523
 
2481
2524
  let timeout_err_message = `The test tried to continue to the next page, but it took longer than ${ (scope.timeout/1000)/60 } min. Check the picture of this page. If a secret variable was used, there will be no picture.`
2482
- if ( timedOut ) { reports.addToReport(scope, { type: `error`, value: timeout_err_message }); }
2525
+ if ( timedOut ) { reports.addToReport(scope, { type: `error`, code: `ALK0146`, value: timeout_err_message }); }
2483
2526
  expect( timedOut, timeout_err_message ).to.be.false;
2484
2527
 
2485
2528
  clearTimeout( cont_timeout );
@@ -2523,13 +2566,13 @@ module.exports = {
2523
2566
  /* Throw a cucumber error with the error that appeared on the page. */
2524
2567
  if ( error_handlers.system_error !== undefined ) {
2525
2568
  let sys_err_message = `The test tried to continue to the next page after ${ id }, but there was a system error. Check the picture of this page.`
2526
- reports.addToReport(scope, { type: `error`, value: sys_err_message });
2569
+ reports.addToReport(scope, { type: `error`, code: `ALK0147`, value: sys_err_message });
2527
2570
  expect( was_system_error, sys_err_message ).to.be.false;
2528
2571
 
2529
2572
  } else {
2530
2573
  // If it wasn't a system error, it was a user error
2531
2574
  let user_err_message = `The test tried to continue to the next page after ${ id }, but the user got an error. Check the picture of this page.`
2532
- reports.addToReport(scope, { type: `error`, value: user_err_message });
2575
+ reports.addToReport(scope, { type: `error`, code: `ALK0148`, value: user_err_message });
2533
2576
  expect( true, user_err_message ).to.be.false;
2534
2577
  }
2535
2578
 
@@ -2607,7 +2650,8 @@ module.exports = {
2607
2650
 
2608
2651
  // In future, may be saved to artifact file
2609
2652
  reports.addToReport( scope, {
2610
- type: `json`,
2653
+ type: `json info`,
2654
+ code: `ALK0149`,
2611
2655
  value: JSON.stringify( data, null, 2 )
2612
2656
  });
2613
2657
  }, // Ends scope.steps.add_json_vars_to_report()
@@ -2622,7 +2666,7 @@ module.exports = {
2622
2666
  let response = await linkPage.goto( actual_url, { waitUntil: 'domcontentloaded' });
2623
2667
 
2624
2668
  let msg = `The "${ linkText }" link is broken.`;
2625
- if ( !response.ok() ) { reports.addToReport( scope, { type: `error`, value: msg }); }
2669
+ if ( !response.ok() ) { reports.addToReport( scope, { type: `error`, code: `ALK0150`, value: msg }); }
2626
2670
  expect( response.ok(), msg ).to.be.true;
2627
2671
 
2628
2672
  // This may cause problems if the linked page is the interview page
@@ -2674,7 +2718,7 @@ module.exports = {
2674
2718
  const [link] = await scope.page.$x(`//a[contains(text(), "${phrase}")]`);
2675
2719
 
2676
2720
  let msg = `The term "${ phrase }" seems to be missing.`;
2677
- if ( !link ) { reports.addToReport(scope, { type: `error`, value: msg }); }
2721
+ if ( !link ) { reports.addToReport(scope, { type: `error`, code: `ALK0151`, value: msg }); }
2678
2722
  expect( link, msg ).to.exist;
2679
2723
  await scope.tapElementAndStayOnPage(scope, { elem: link });
2680
2724
  await scope.page.waitForTimeout(10000);
@@ -2699,7 +2743,7 @@ module.exports = {
2699
2743
  let [elem] = await scope.page.$x(`//a[contains(@href, "${ filename }")]`);
2700
2744
 
2701
2745
  let msg = `"${ filename }" seems to be missing. Cannot find a link to that document.`;
2702
- if ( !elem ) { reports.addToReport(scope, { type: `error`, value: msg }); }
2746
+ if ( !elem ) { reports.addToReport(scope, { type: `error`, code: `ALK0152`, value: msg }); }
2703
2747
  expect( elem, msg ).to.exist;
2704
2748
 
2705
2749
  let failed_to_download = false;
@@ -2712,13 +2756,13 @@ module.exports = {
2712
2756
  const reader = new FileReader();
2713
2757
  reader.readAsBinaryString(await response.blob());
2714
2758
  reader.onload = () => resolve(reader.result);
2715
- reader.onerror = () => reject(`Error occurred on page when downloading ${ url }: ${ reader.error }`);
2759
+ reader.onerror = () => reject(`🤕 ALK0153 ERROR: Error occurred on page when downloading ${ url }: ${ reader.error }`);
2716
2760
  });
2717
2761
  }, elem);
2718
2762
  if (binaryStr !== '') {
2719
2763
  const fileData = Buffer.from(binaryStr, 'binary');
2720
2764
  fs.writeFileSync(`${ scope.paths.scenario }/${ filename }`, fileData);
2721
- reports.addToReport(scope, { type: `info`, value: `Downloaded ${ filename } (${ fileData.length } bytes) to ${ scope.paths.scenario }`});
2765
+ reports.addToReport(scope, { type: `row info`, code: `ALK0154`, value: `Downloaded ${ filename } (${ fileData.length } bytes) to ${ scope.paths.scenario }`});
2722
2766
  } else {
2723
2767
  failed_to_download = true;
2724
2768
  err_msg = `Couldn't download ${ filename }, binary data for download was empty`;
@@ -2729,7 +2773,7 @@ module.exports = {
2729
2773
  }
2730
2774
 
2731
2775
  if (failed_to_download) {
2732
- reports.addToReport(scope, { type: `warning`, value: `Could not download file using fetch (${ err_msg }). ALKiln will now fallback to the click download method` });
2776
+ reports.addToReport(scope, { type: `warning`, code: `ALK0155`, value: `Could not download file using fetch (${ err_msg }). ALKiln will now fallback to the click download method.` });
2733
2777
  scope.toDownload = filename;
2734
2778
  // Should this be using `scope.tapElement`?
2735
2779
  await elem.evaluate( elem => { return elem.click(); });
@@ -2742,7 +2786,7 @@ module.exports = {
2742
2786
  if (existing_paths.length == 0) {
2743
2787
  // The row wasn't used
2744
2788
  let msg = `Could not find the existing PDF at ${ existing_pdf_path }`;
2745
- reports.addToReport(scope, { type: `error`, value: msg });
2789
+ reports.addToReport(scope, { type: `error`, code: `ALK0156`, value: msg });
2746
2790
  scope.failed_pdf_compares.push(msg);
2747
2791
  // Return early since we couldn't find the PDF
2748
2792
  return;
@@ -2758,7 +2802,7 @@ module.exports = {
2758
2802
  return err_str + `- ${ part.value }\n`
2759
2803
  }, 'The new PDF removed: \n');
2760
2804
  let msg = `The PDFs were not the same.\n${ added_str }\n${removed_str}\n\n You can see the full PDFs at ${ full_existing_path } and ${ full_new_pdf_path}`;
2761
- reports.addToReport(scope, { type: `error`, value: msg });
2805
+ reports.addToReport(scope, { type: `error`, code: `ALK0157`, value: msg });
2762
2806
  scope.failed_pdf_compares.push(msg);
2763
2807
  }
2764
2808
  },
@@ -2793,6 +2837,7 @@ module.exports = {
2793
2837
 
2794
2838
  reports.addToReport(scope, {
2795
2839
  type: `warning`,
2840
+ code: `ALK0158`,
2796
2841
  value: `The name "${name_str}" has more than 4 parts, but 4 is the maximum allowed. The test will set the name to "${name_parts.join(" ")}".`
2797
2842
  });
2798
2843
  }
@@ -2875,10 +2920,13 @@ module.exports = {
2875
2920
  let err_msg = `Error occurred when ALKiln tried to go to "${ login_url }".`
2876
2921
  if ( error.name === `TimeoutError` ) {
2877
2922
  let non_reload_report_msg = `It took too long to load "${ login_url }"`;
2878
- await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
2923
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
2924
+ code: `ALK0159`,
2925
+ message: non_reload_report_msg,
2926
+ }, error });
2879
2927
  } else {
2880
2928
  // Throw any non-timeout error
2881
- reports.addToReport( scope, { type: `error`, value: err_msg });
2929
+ reports.addToReport( scope, { type: `error`, code: `ALK0160`, value: err_msg });
2882
2930
  throw error;
2883
2931
  } // ends if error is timeout error
2884
2932
 
@@ -2892,11 +2940,11 @@ module.exports = {
2892
2940
  // this is complex
2893
2941
  let email_msg = `The email address GitHub SECRET "${ email_secret_name }" doesn't exist. Check for a typo and check your workflow file.`
2894
2942
  if ( email === undefined ) {
2895
- reports.addToReport( scope, { type: `error`, value: email_msg })
2943
+ reports.addToReport( scope, { type: `error`, code: `ALK0161`, value: email_msg })
2896
2944
  }
2897
2945
  let password_msg = `The password GitHub SECRET "${ password_secret_name }" doesn't exist. Check for a typo and check your workflow file.`
2898
2946
  if ( password === undefined ) {
2899
- reports.addToReport( scope, { type: `error`, value: password_msg })
2947
+ reports.addToReport( scope, { type: `error`, code: `ALK0162`, value: password_msg })
2900
2948
  }
2901
2949
 
2902
2950
  expect( email, email_msg ).to.not.equal( undefined );
@@ -2909,7 +2957,8 @@ module.exports = {
2909
2957
  await scope.tapElementAndNavigate( scope, { elem });
2910
2958
 
2911
2959
  reports.addToReport( scope, {
2912
- type: `row`,
2960
+ type: `row info`,
2961
+ code: `ALK0163`,
2913
2962
  value: `Signed into ${ session_vars.get_da_server_url() }/user/sign-in successfully.`
2914
2963
  });
2915
2964
 
@@ -2970,9 +3019,11 @@ module.exports = {
2970
3019
  }
2971
3020
  if (field == null) {
2972
3021
  // Just skip it? Shouldn't happen but has before. Dig in more
2973
- if (session_vars.get_debug()) {
2974
- console.log(`A random button field choice was null. These were the fields to choose from:\n${ JSON.stringify(fields, null, 2) }`);
2975
- }
3022
+ log.debug({
3023
+ code: `ALK0164`,
3024
+ type: `info`,
3025
+ pre: `A random button field choice was null. These were the fields to choose from:\n${ JSON.stringify(fields, null, 2) }`,
3026
+ });
2976
3027
  return;
2977
3028
  }
2978
3029
  let handle = await scope.get_handle_from_field( scope, { field: field });
@@ -3074,6 +3125,7 @@ module.exports = {
3074
3125
  if ( type === `file` ) {
3075
3126
  reports.addToReport( scope, {
3076
3127
  type: `warning`,
3128
+ code: `ALK0165`,
3077
3129
  value: `Sorry, ALKiln's random input tests cannot yet handle "${ type }" fields.`
3078
3130
  });
3079
3131
  } else {