@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/.github/workflows/github_server.yml +45 -23
- package/.github/workflows/log_code_tests.yml +27 -0
- package/.github/workflows/playground.yml +38 -19
- package/.github/workflows/unit_tests.yml +2 -2
- package/CHANGELOG.md +31 -0
- package/action.yml +31 -54
- package/action_for_github_server/action.yml +61 -67
- package/lib/cucumber_8_shim.js +2 -1
- package/lib/docassemble/docassemble_api_REST.js +2 -2
- package/lib/docassemble/docassemble_api_interface.js +12 -8
- package/lib/docassemble/server_install.js +3 -2
- package/lib/docassemble/setup.js +5 -3
- package/lib/docassemble/takedown.js +4 -4
- package/lib/run_cucumber.js +21 -13
- package/lib/scope.js +126 -74
- package/lib/steps.js +82 -162
- package/lib/utils/log.js +56 -33
- package/lib/utils/reports.js +77 -20
- package/lib/utils/session_vars.js +12 -19
- package/package.json +4 -3
- package/tests/log_codes/check_codes.sh +138 -0
- package/tests/log_codes/deleted_codes.json +8 -0
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, {
|
|
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, {
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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, {
|
|
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, {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
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
|
-
|
|
1575
|
-
|
|
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
|
-
|
|
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, {
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
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
|
|
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(
|
|
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, {
|
|
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
|
-
|
|
2974
|
-
|
|
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 {
|