@suffolklitlab/alkiln 5.2.1 → 5.4.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/CHANGELOG.md +20 -0
- package/lib/scope.js +141 -220
- package/lib/steps.js +89 -49
- package/lib/utils/pdf_reader.js +113 -0
- package/lib/utils/reports.js +147 -0
- package/npm-shrinkwrap.json +757 -8
- package/package.json +4 -2
package/lib/scope.js
CHANGED
|
@@ -9,6 +9,7 @@ const safe_filename = require("sanitize-filename");
|
|
|
9
9
|
const faker = require('@faker-js/faker/locale/en').faker;
|
|
10
10
|
|
|
11
11
|
// Ours
|
|
12
|
+
const pdf_reader = require('./utils/pdf_reader');
|
|
12
13
|
const session_vars = require('./utils/session_vars');
|
|
13
14
|
const get_base_interview_url = require(`./docassemble/get_base_interview_url`);
|
|
14
15
|
const time = require('./utils/time');
|
|
@@ -17,6 +18,7 @@ const { waitForTimeout } = require('./utils/time');
|
|
|
17
18
|
const files = require('./utils/files' );
|
|
18
19
|
const server = require('./docassemble/docassemble_api_interface');
|
|
19
20
|
const wrapPromiseWithTimeout = require('./cucumber_8_shim');
|
|
21
|
+
const reports = require(`./utils/reports`);
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
let ordinal_to_integer = {
|
|
@@ -82,152 +84,10 @@ let toBase64 = function ( utf8_str, exclude_padding=true) {
|
|
|
82
84
|
|
|
83
85
|
let proxies_regex = /(\bx\.)|(\bx\[)|(\[[ijklmn]\])/g;
|
|
84
86
|
let da_base64_regex = /^[A-Za-z0-9+/]+$/;
|
|
85
|
-
let misc_artifacts_dir = `_alkiln-misc_artifacts`;
|
|
86
87
|
|
|
87
88
|
module.exports = {
|
|
88
89
|
trigger_not_needed_flag: `ALKiln: no trigger variable needed`,
|
|
89
90
|
|
|
90
|
-
addToReport: async function( scope, { type, value }) {
|
|
91
|
-
/* Add an item to a specific list in a scenario's report.
|
|
92
|
-
* Create report if necessary.
|
|
93
|
-
*
|
|
94
|
-
* The report has a key for each scenario and each of those
|
|
95
|
-
* keys should correspond to a list containing the relevant data. */
|
|
96
|
-
if ( session_vars.get_debug() ) { console.log(`Report:\ntype: ${ type }, value: ${ value }\n`) }
|
|
97
|
-
let scenario = await scope.makeSureReportPartsExist( scope );
|
|
98
|
-
scenario.lines.push({ type, value });
|
|
99
|
-
|
|
100
|
-
// TODO: Not sure how to use .add_to_debug_log() here considering possibly dynamic filepath
|
|
101
|
-
// log.add_to_debug_log(`Report:\ntype: ${ type }, value: ${ value }\n`);
|
|
102
|
-
|
|
103
|
-
// Ensure filepath for saving local unit test logs
|
|
104
|
-
if ( !scope.paths ) {
|
|
105
|
-
// TODO: would it be useful to put in existing artifacts folder if possible.
|
|
106
|
-
// Can this be usefully abstracted?
|
|
107
|
-
scope.paths = { debug_log: `${ misc_artifacts_dir }/unit_tests_logs-${ files.readable_date() }.txt` };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
fs.appendFileSync(scope.paths.debug_log, `\nReport:\ntype: ${ type }, value: ${ value }`);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
fs.mkdirSync( misc_artifacts_dir );
|
|
114
|
-
fs.appendFileSync(scope.paths.debug_log, `\nReport:\ntype: ${ type }, value: ${ value }`);
|
|
115
|
-
}
|
|
116
|
-
return scenario;
|
|
117
|
-
|
|
118
|
-
}, // Ends scope.addToReport()
|
|
119
|
-
|
|
120
|
-
makeSureReportPartsExist: async function( scope ) {
|
|
121
|
-
/* If a part of the report needs to exist right now, but doesn't exist,
|
|
122
|
-
* create it. */
|
|
123
|
-
if ( !scope.report ) { scope.report = new Map(); }
|
|
124
|
-
if ( !scope.scenario_id ) {
|
|
125
|
-
scope.scenario_id = `_report_${ Date.now() }`;
|
|
126
|
-
}
|
|
127
|
-
if ( !scope.report.get( scope.scenario_id )) {
|
|
128
|
-
scope.report.set( scope.scenario_id, {} )
|
|
129
|
-
scope.report.get( scope.scenario_id ).status = `in progress`;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
let scenario = scope.report.get( scope.scenario_id );
|
|
133
|
-
if ( !scenario.lines ) { scenario.lines = []; }
|
|
134
|
-
|
|
135
|
-
return scenario;
|
|
136
|
-
}, // Ends scope.makeSureReportPartsExist()
|
|
137
|
-
|
|
138
|
-
setReportScenarioStatus: async function( scope, { status=`PASSED` }) {
|
|
139
|
-
/* Add final status of scenario to scenario report object - passed, failed, etc. */
|
|
140
|
-
scope.report.get( scope.scenario_id ).status = status;
|
|
141
|
-
}, // Ends scope.setReportScenarioStatus()
|
|
142
|
-
|
|
143
|
-
convertToOriginalStoryTableRow: async function( scope, { row_data }) {
|
|
144
|
-
/* Returns the original data of row into a string formatted as a story table row.
|
|
145
|
-
* Should this show the actual row data that was used instead? That could
|
|
146
|
-
* be pretty confusing to most devs. */
|
|
147
|
-
let source_row = row_data.source || row_data;
|
|
148
|
-
let original = source_row.original;
|
|
149
|
-
let var_str = await scope.toTrimmedJSON( scope, { str: original.var });
|
|
150
|
-
let value_str = await scope.toTrimmedJSON( scope, { str: original.value });
|
|
151
|
-
let trigger_str = await scope.toTrimmedJSON( scope, { str: original.trigger });
|
|
152
|
-
if ( trigger_str === scope.trigger_not_needed_flag ) {
|
|
153
|
-
// This text was added by ALKiln itself. It's not part of the user's data
|
|
154
|
-
trigger_str = ``;
|
|
155
|
-
}
|
|
156
|
-
return `${ ' '.repeat(6) }| ${ var_str } | ${ value_str } | ${ trigger_str } |`;
|
|
157
|
-
}, // Ends scope.convertToOriginalStoryTableRows()
|
|
158
|
-
|
|
159
|
-
toTrimmedJSON: async function( scope, { str='' }) {
|
|
160
|
-
/* Turn into JSON string then trim quotes from the start and end. */
|
|
161
|
-
let json = JSON.stringify( str );
|
|
162
|
-
let trimmed = json.replace( /^"/, '' ).replace( /"$/, '' ).replace( /\\\\/g, `\\`);
|
|
163
|
-
return trimmed;
|
|
164
|
-
}, // Ends scope.toTrimmedJSON()
|
|
165
|
-
|
|
166
|
-
addReportHeading: async function (scope, { scenario }) {
|
|
167
|
-
/** Return printable heading based on Scenario name and tags.
|
|
168
|
-
* Allow characters from other languages.
|
|
169
|
-
*/
|
|
170
|
-
if ( session_vars.get_debug() ) { console.log( scenario.pickle.name ); }
|
|
171
|
-
|
|
172
|
-
// Collect all tag names
|
|
173
|
-
let tag_names = [];
|
|
174
|
-
for ( let tag of scenario.pickle.tags ) {
|
|
175
|
-
tag_names.push( tag.name );
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
let heading = `\n---------------\n`
|
|
179
|
-
+ `Scenario: ${ scenario.pickle.name }`;
|
|
180
|
-
|
|
181
|
-
if ( tag_names.length > 0 ) {
|
|
182
|
-
heading += `\nTags: ${ tag_names.join(' ') }`;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
heading += `\n---------------`;
|
|
186
|
-
|
|
187
|
-
await scope.addToReport( scope, {
|
|
188
|
-
type: `heading`,
|
|
189
|
-
value: heading,
|
|
190
|
-
});
|
|
191
|
-
}, // Ends scope.addReportHeading()
|
|
192
|
-
|
|
193
|
-
getPrintableReport: async function( scope ) {
|
|
194
|
-
/* Return a string generated from test report data. */
|
|
195
|
-
let report = `Assembly Line Kiln Automated Testing Report - ${ (new Date()).toUTCString() }\n`;
|
|
196
|
-
|
|
197
|
-
// First list failed scenarios, then non-passed scenarios, then passed scenarios
|
|
198
|
-
let failed_reports = ``;
|
|
199
|
-
let passed_reports = ``;
|
|
200
|
-
let other_reports = ``;
|
|
201
|
-
for ( let scenario of scope.report ) {
|
|
202
|
-
|
|
203
|
-
let report = await scope.getPrintableScenario( scope, { scenario });
|
|
204
|
-
let [ scenario_id, data ] = scenario;
|
|
205
|
-
if ( data.status === `FAILED` ) { failed_reports += report; }
|
|
206
|
-
else if ( data.status === `PASSED` ) { passed_reports += report; }
|
|
207
|
-
else { other_reports += report; }
|
|
208
|
-
} // ends for every scenario
|
|
209
|
-
|
|
210
|
-
if ( failed_reports !== `` ) { report += `\n\n===============================\n===============================\nFailed scenarios:\n${ failed_reports }`; }
|
|
211
|
-
if ( other_reports !== `` ) { report += `\n\n===============================\n===============================\nScenarios that did not pass:\n${ other_reports }`; }
|
|
212
|
-
if ( passed_reports !== `` ) { report += `\n\n===============================\n===============================\nPassed scenarios:\n${ passed_reports }`; }
|
|
213
|
-
|
|
214
|
-
return report;
|
|
215
|
-
}, // Ends scope.getPrintableReport()
|
|
216
|
-
|
|
217
|
-
getPrintableScenario: async function( scope, { scenario }) {
|
|
218
|
-
/* Return a string generated from scenario list of report items. */
|
|
219
|
-
let [ scenario_id, data ] = scenario;
|
|
220
|
-
let report = ``;
|
|
221
|
-
for ( let line of data.lines ) {
|
|
222
|
-
if ( line.type === `page_id` ) { report += `screen id: `; }
|
|
223
|
-
else if ( line.type === `outcome` ) { report += `\n`; }
|
|
224
|
-
else if ( line.type === `warning` ) { report += `WARNING: `; }
|
|
225
|
-
else if ( line.type === `error` ) { report += `\nERROR: ` }
|
|
226
|
-
report += `${ line.value }\n`;
|
|
227
|
-
}
|
|
228
|
-
return report;
|
|
229
|
-
}, // Ends scope.getPrintableScenario()
|
|
230
|
-
|
|
231
91
|
getSafeScenarioBaseFilename: async function( scope, { scenario }) {
|
|
232
92
|
/** Return a string that's safe to be a filename. Include the Scenario
|
|
233
93
|
* description and tags.
|
|
@@ -275,6 +135,15 @@ module.exports = {
|
|
|
275
135
|
return safe_name;
|
|
276
136
|
}, // Ends scope.getSafeScenarioFilename()
|
|
277
137
|
|
|
138
|
+
getA11yPath: async function( scope ) {
|
|
139
|
+
// Get a unique path for a json file
|
|
140
|
+
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
141
|
+
let short_id = `${ id }`.substring(0, 20);
|
|
142
|
+
// Need timestamp in case of a loop where the same page gets assessed for a11y multiple times
|
|
143
|
+
let a11y_path = path.join( scope.paths.scenario, `aXe_failure-${ short_id }-${ Date.now() }.json` );
|
|
144
|
+
return a11y_path;
|
|
145
|
+
},
|
|
146
|
+
|
|
278
147
|
getJSONFilename: async function( scope ) {
|
|
279
148
|
// Get a unique path for a json file
|
|
280
149
|
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
@@ -356,7 +225,7 @@ module.exports = {
|
|
|
356
225
|
let error_text_prop = await error_elem.getProperty( 'textContent' );
|
|
357
226
|
let system_error_text = await error_text_prop.jsonValue();
|
|
358
227
|
|
|
359
|
-
|
|
228
|
+
reports.addToReport(scope, { type: `error`, value: system_error_text });
|
|
360
229
|
throw system_error_text;
|
|
361
230
|
};
|
|
362
231
|
|
|
@@ -386,7 +255,7 @@ module.exports = {
|
|
|
386
255
|
// first in user-triggered cases - users used to be able to access this almost
|
|
387
256
|
// directly, but they can't anymore. Our functions should know to only pass good things.
|
|
388
257
|
let msg = `Cannot find the element to tap.`;
|
|
389
|
-
if ( !elem ) {
|
|
258
|
+
if ( !elem ) { reports.addToReport(scope, { type: `error`, value: msg }); }
|
|
390
259
|
|
|
391
260
|
expect( elem, msg ).to.exist;
|
|
392
261
|
|
|
@@ -425,7 +294,7 @@ module.exports = {
|
|
|
425
294
|
} else {
|
|
426
295
|
// Throw any non-timeout error
|
|
427
296
|
let err_msg = `Error occurred when ALKiln tried to tap "${ tapperText }".`
|
|
428
|
-
|
|
297
|
+
reports.addToReport( scope, { type: `error`, value: err_msg });
|
|
429
298
|
throw error;
|
|
430
299
|
} // ends if error is timeout error
|
|
431
300
|
|
|
@@ -517,7 +386,7 @@ module.exports = {
|
|
|
517
386
|
await scope.get_server_reload_promise( scope );
|
|
518
387
|
} else {
|
|
519
388
|
// Otherwise just throw the error
|
|
520
|
-
|
|
389
|
+
reports.addToReport( scope, {
|
|
521
390
|
type: `error`,
|
|
522
391
|
value: non_reload_report_msg });
|
|
523
392
|
throw error;
|
|
@@ -579,7 +448,7 @@ module.exports = {
|
|
|
579
448
|
+ `${ Math.round( ms_till_server_timeout/1000 ) } seconds to respond. `
|
|
580
449
|
+ `If the server was just reloading and needed more time, try setting the `
|
|
581
450
|
+ `"SERVER_RELOAD_TIMEOUT_SECONDS" GitHub secret to a longer amount of time.`
|
|
582
|
-
|
|
451
|
+
reports.addToReport( scope, { type: `error`, value: timeout_message });
|
|
583
452
|
}
|
|
584
453
|
|
|
585
454
|
// Once server has responded, throw an error to end the test. After the first
|
|
@@ -599,8 +468,8 @@ module.exports = {
|
|
|
599
468
|
let reload_failure_msg = `The test was unable to continue because the `
|
|
600
469
|
+ `server was reloading. ALKiln will try this Scenario a total of 2 times. An `
|
|
601
470
|
+ `error will still be printed for this attempt.`;
|
|
602
|
-
|
|
603
|
-
//
|
|
471
|
+
reports.addToReport( scope, { type: `error`, value: reload_failure_msg });
|
|
472
|
+
// reports.addToReport( scope, { type: `error`, value: timeout_message });
|
|
604
473
|
// clearTimeout( server_timeout_id );
|
|
605
474
|
throw( reload_failure_msg );
|
|
606
475
|
}, // Ends scope.throw_server_was_reloading_error()
|
|
@@ -673,7 +542,7 @@ module.exports = {
|
|
|
673
542
|
let elem = await scope.page.$(`#${tab_id}`);
|
|
674
543
|
let error_msg = `Couldn't find the tab with id "#${tab_id}" on the page, is there a typo?`;
|
|
675
544
|
if ( !elem ) {
|
|
676
|
-
|
|
545
|
+
reports.addToReport(scope, { type: `error`, value: error_msg });
|
|
677
546
|
}
|
|
678
547
|
expect( elem, error_msg ).to.exist;
|
|
679
548
|
await scope.tapElement( scope, elem, tab_id );
|
|
@@ -683,7 +552,7 @@ module.exports = {
|
|
|
683
552
|
/** Return if there were any violations and the file containing aXe output with more details of the checks */
|
|
684
553
|
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
685
554
|
if ( scope.page_id !== id ) {
|
|
686
|
-
|
|
555
|
+
reports.addToReport(scope, { type: `page_id`, value: `${ id }`, });
|
|
687
556
|
scope.page_id = id;
|
|
688
557
|
}
|
|
689
558
|
const axe = new AxePuppeteer(scope.page);
|
|
@@ -701,16 +570,15 @@ module.exports = {
|
|
|
701
570
|
let axe_path = null;
|
|
702
571
|
const passed = axe_result.violations.length == 0;
|
|
703
572
|
if (!passed) {
|
|
704
|
-
|
|
705
|
-
axe_path = `${ scope.paths.scenario }/${ axe_filename }`;
|
|
573
|
+
axe_path = await scope.getA11yPath( scope );
|
|
706
574
|
fs.writeFileSync( axe_path, JSON.stringify( axe_result, null, 2 ));
|
|
707
575
|
let msg = `Found potential accessibility issues on the ${ scope.page_id } screen. Details in ${ axe_path }.`;
|
|
708
|
-
|
|
576
|
+
reports.addToReport( scope, {
|
|
709
577
|
type: `error`,
|
|
710
578
|
value: msg
|
|
711
579
|
});
|
|
712
580
|
} else {
|
|
713
|
-
|
|
581
|
+
reports.addToReport(scope, { type: `info`, value: `Accessibility on ${ scope.page_id } passed!`})
|
|
714
582
|
}
|
|
715
583
|
return {
|
|
716
584
|
passed: axe_result.violations.length == 0,
|
|
@@ -722,7 +590,7 @@ module.exports = {
|
|
|
722
590
|
let elem = await scope.page.$(`${selector}`);
|
|
723
591
|
let error_msg = `Couldn't find "${selector}" on the page, is there a typo?`;
|
|
724
592
|
if ( !elem ) {
|
|
725
|
-
|
|
593
|
+
reports.addToReport(scope, { type: `error`, value: error_msg });
|
|
726
594
|
}
|
|
727
595
|
expect( elem, error_msg ).to.exist;
|
|
728
596
|
await scope.tapElement( scope, elem, '', waitForTimeout );
|
|
@@ -748,7 +616,7 @@ module.exports = {
|
|
|
748
616
|
interview_url = `${ base_url }${ file_name }`;
|
|
749
617
|
}
|
|
750
618
|
|
|
751
|
-
|
|
619
|
+
reports.addToReport(scope,{
|
|
752
620
|
type: `row`,
|
|
753
621
|
value: `Trying to load the interview at "${interview_url}"`
|
|
754
622
|
});
|
|
@@ -772,7 +640,7 @@ module.exports = {
|
|
|
772
640
|
} else {
|
|
773
641
|
|
|
774
642
|
// Throw any non-timeout error
|
|
775
|
-
|
|
643
|
+
reports.addToReport( scope, {
|
|
776
644
|
type: `error`,
|
|
777
645
|
value: `Error occurred when ALKiln tried to go to the interview url`
|
|
778
646
|
});
|
|
@@ -784,7 +652,7 @@ module.exports = {
|
|
|
784
652
|
let load_result = await scope.getLoadData( scope );
|
|
785
653
|
// Errors, or reaching timeout, causes an exception and is shown to the developer at the end
|
|
786
654
|
if ( load_result.error ) {
|
|
787
|
-
|
|
655
|
+
reports.addToReport(scope, { type: `error`, value: `On final attempt to load interview, got "${ load_result.error }"` });
|
|
788
656
|
expect( load_result.error ).to.equal( '' );
|
|
789
657
|
}
|
|
790
658
|
|
|
@@ -854,7 +722,7 @@ module.exports = {
|
|
|
854
722
|
if (!var_data && ! raw_var_data) {
|
|
855
723
|
let no_data_msg = `ALKiln Internal error: normalizeTable called w/o var_data or raw_var_data:` +
|
|
856
724
|
` open an issue at https://github.com/SuffolkLITLab/ALKiln/issues/new if you see this!`;
|
|
857
|
-
|
|
725
|
+
reports.addToReport( scope, { type: `error`, value: no_data_msg });
|
|
858
726
|
throw Error(no_data_msg);
|
|
859
727
|
}
|
|
860
728
|
|
|
@@ -869,7 +737,7 @@ module.exports = {
|
|
|
869
737
|
let bad_table_msg = `Your Story Table definition needs to be changed. The best practice`
|
|
870
738
|
+ ` is to make your table 3 columns wide with a first row in this format: "| var | value | trigger |".`
|
|
871
739
|
+ ` The first row of your table is actually "${ raw_array[0] }"`;
|
|
872
|
-
|
|
740
|
+
reports.addToReport( scope, { type: `error`, value: bad_table_msg})
|
|
873
741
|
throw Error(bad_table_msg);
|
|
874
742
|
} else if (row_raw.length == 2) {
|
|
875
743
|
var_data.push({var: row_raw[0], value: row_raw[1]});
|
|
@@ -889,7 +757,7 @@ module.exports = {
|
|
|
889
757
|
actual_var_value = process.env[row.flags.secret_name];
|
|
890
758
|
if ( actual_var_value === undefined ) {
|
|
891
759
|
let not_in_env_msg = `The GitHub SECRET "${ row.flags.secret_name }" doesn't exist. Check for a typo and check your workflow file.`;
|
|
892
|
-
|
|
760
|
+
reports.addToReport( scope, { type: `error`, value: not_in_env_msg })
|
|
893
761
|
throw ReferenceError(`Could not find "${row.flags.secret_name }": ${not_in_env_msg}.`)
|
|
894
762
|
}
|
|
895
763
|
}
|
|
@@ -941,7 +809,7 @@ module.exports = {
|
|
|
941
809
|
let encoded_trigger_var = $( trigger_elem ).data( `variable` ); // This should come out to 'None' at the very least
|
|
942
810
|
if ( !encoded_trigger_var ) {
|
|
943
811
|
// TODO: Add documentation and then link to it in this message.
|
|
944
|
-
|
|
812
|
+
reports.addToReport(scope, { type: `warning`, value: `You are missing an element containing the data for the page's trigger variable. Some fields, like loops with index variables, may not work correctly in these tests. See https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/#a-missing-trigger-variable.` });
|
|
945
813
|
encoded_trigger_var = toBase64( `None` );
|
|
946
814
|
}
|
|
947
815
|
let trigger = fromBase64( encoded_trigger_var );
|
|
@@ -1080,7 +948,7 @@ module.exports = {
|
|
|
1080
948
|
// Exceptions: Some specific fields can be duplicates without being dangerous
|
|
1081
949
|
if ( matching_nodes.length > 1 && !selector.includes(`[class="file-caption-name"]`) ) {
|
|
1082
950
|
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.`;
|
|
1083
|
-
|
|
951
|
+
reports.addToReport(scope, { type: `warning`, value: msg });
|
|
1084
952
|
}
|
|
1085
953
|
|
|
1086
954
|
return selector;
|
|
@@ -1359,7 +1227,7 @@ module.exports = {
|
|
|
1359
1227
|
+ `variable or a generic object, but the page does not `
|
|
1360
1228
|
+ `contain the trigger variable's name in its HTML. See `
|
|
1361
1229
|
+ `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/#a-missing-trigger-variable.`;
|
|
1362
|
-
|
|
1230
|
+
reports.addToReport(scope, { type: `warning`, value: page_trigger_warning });
|
|
1363
1231
|
}
|
|
1364
1232
|
|
|
1365
1233
|
for ( let row_that_matches_this_field of rows_that_match_field_names ) {
|
|
@@ -1373,13 +1241,13 @@ module.exports = {
|
|
|
1373
1241
|
// a useful message.
|
|
1374
1242
|
|
|
1375
1243
|
// First, make the row data more readable to humans.
|
|
1376
|
-
let row_as_story_table =
|
|
1244
|
+
let row_as_story_table = reports.convertToOriginalStoryTableRow( scope, { row_data: row_that_matches_this_field });
|
|
1377
1245
|
let row_trigger_warning = `This story table row needs a value in the "trigger" `
|
|
1378
1246
|
+ `column, but it is empty. The test might get unexpected results. See `
|
|
1379
1247
|
+ `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/#trigger.`
|
|
1380
1248
|
+ `\nThe row's data:\n${ row_as_story_table }`
|
|
1381
1249
|
+ `\nThis field's data:\n${ JSON.stringify( field )}`;
|
|
1382
|
-
|
|
1250
|
+
reports.addToReport(scope, { type: `warning`, value: row_trigger_warning });
|
|
1383
1251
|
rows_without_a_trigger_name.push( row_that_matches_this_field );
|
|
1384
1252
|
} else {
|
|
1385
1253
|
let triggers_match = await scope.matchNeutralizedQuotes( scope, { value1: page_trigger_name, value2: table_row_trigger_name });
|
|
@@ -1405,7 +1273,7 @@ module.exports = {
|
|
|
1405
1273
|
// First, make the row data more readable to humans.
|
|
1406
1274
|
let conflicts_as_story_table_rows = [];
|
|
1407
1275
|
for ( let row of rows_with_conflicting_trigger_names ) {
|
|
1408
|
-
let table_str =
|
|
1276
|
+
let table_str = reports.convertToOriginalStoryTableRow( scope, { row_data: row });
|
|
1409
1277
|
conflicts_as_story_table_rows.push( table_str );
|
|
1410
1278
|
}
|
|
1411
1279
|
|
|
@@ -1416,7 +1284,7 @@ module.exports = {
|
|
|
1416
1284
|
+ `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/#trigger.`
|
|
1417
1285
|
+ `\nThe data of row(s) with conflicting trigger name(s):\n${ conflicts_as_story_table_rows.join( `\n` )}`
|
|
1418
1286
|
+ `\nThis field's data:\n${ JSON.stringify( field )}`;
|
|
1419
|
-
|
|
1287
|
+
reports.addToReport(scope, {
|
|
1420
1288
|
type: `warning`,
|
|
1421
1289
|
value: all_trigger_names_conflict_msg
|
|
1422
1290
|
});
|
|
@@ -1433,7 +1301,7 @@ module.exports = {
|
|
|
1433
1301
|
// First, make the row data more readable to humans.
|
|
1434
1302
|
let rows_as_story_table = [];
|
|
1435
1303
|
for ( let row of final_matching_rows ) {
|
|
1436
|
-
let table_str =
|
|
1304
|
+
let table_str = reports.convertToOriginalStoryTableRow( scope, { row_data: row });
|
|
1437
1305
|
rows_as_story_table.push( table_str );
|
|
1438
1306
|
}
|
|
1439
1307
|
|
|
@@ -1443,7 +1311,7 @@ module.exports = {
|
|
|
1443
1311
|
+ `https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/#trigger.`
|
|
1444
1312
|
+ `\nThe matching rows:\n${ rows_as_story_table.join(`\n`) }`
|
|
1445
1313
|
+ `\nThis field's data:\n${ JSON.stringify( field )}`;
|
|
1446
|
-
|
|
1314
|
+
reports.addToReport(scope, { type: `warning`, value: multiple_matches_msg });
|
|
1447
1315
|
}
|
|
1448
1316
|
|
|
1449
1317
|
if ( session_vars.get_debug() ) {
|
|
@@ -1617,7 +1485,7 @@ module.exports = {
|
|
|
1617
1485
|
// If it doesn't have the right format
|
|
1618
1486
|
if ( answer === null || !answer.includes(`/`) ) {
|
|
1619
1487
|
// Return field unused.
|
|
1620
|
-
|
|
1488
|
+
reports.addToReport( scope, {
|
|
1621
1489
|
type: `warning`,
|
|
1622
1490
|
value: `Invalid date. Value given: "${ answer }".`
|
|
1623
1491
|
});
|
|
@@ -1812,22 +1680,15 @@ module.exports = {
|
|
|
1812
1680
|
return valid_date;
|
|
1813
1681
|
}, // Ends scope.today_to_date()
|
|
1814
1682
|
|
|
1815
|
-
|
|
1816
|
-
/* Try to upload one or more files to a file-type input field.
|
|
1817
|
-
* Does not submit, so no danger of timeout with server reload.
|
|
1818
|
-
*
|
|
1819
|
-
* Returns whether the row was used or not.
|
|
1820
|
-
*/
|
|
1821
|
-
|
|
1683
|
+
findFiles: async function( scope, {to_find_names}) {
|
|
1822
1684
|
// First make sure the list of files was defined. Don't remove spaces yet -
|
|
1823
1685
|
// allow a typo where someone forgot to include a space after a comma.
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
await scope.addToReport( scope, {
|
|
1686
|
+
if ( to_find_names.length === 0 ) {
|
|
1687
|
+
reports.addToReport( scope, {
|
|
1827
1688
|
type: `error`,
|
|
1828
|
-
value: `Your list of files to
|
|
1689
|
+
value: `Your list of files to find is empty.`
|
|
1829
1690
|
});
|
|
1830
|
-
return
|
|
1691
|
+
return [];
|
|
1831
1692
|
}
|
|
1832
1693
|
|
|
1833
1694
|
let dirs = [];
|
|
@@ -1850,24 +1711,23 @@ module.exports = {
|
|
|
1850
1711
|
}
|
|
1851
1712
|
|
|
1852
1713
|
if ( session_vars.get_debug() ) {
|
|
1853
|
-
console.log( `All discovered dirs to
|
|
1714
|
+
console.log( `All discovered dirs to find files from:`, dirs );
|
|
1854
1715
|
}
|
|
1855
1716
|
|
|
1856
1717
|
// Make sure sources directory exists and has files in it
|
|
1857
1718
|
if ( dirs.length === 0 ) {
|
|
1858
|
-
|
|
1719
|
+
reports.addToReport( scope, {
|
|
1859
1720
|
type: `warning`,
|
|
1860
1721
|
value: `The test files need to be in the "sources" directory, `
|
|
1861
1722
|
+ `but ALKiln couldn't find the directory or it was empty.`
|
|
1862
1723
|
});
|
|
1863
|
-
return
|
|
1724
|
+
return [];
|
|
1864
1725
|
}
|
|
1865
1726
|
|
|
1866
1727
|
// Get the full paths of all the files
|
|
1867
|
-
let dir = null;
|
|
1868
1728
|
let paths = [];
|
|
1869
1729
|
let missing_files = []; // For any user warnings
|
|
1870
|
-
for ( let name of
|
|
1730
|
+
for ( let name of to_find_names) {
|
|
1871
1731
|
|
|
1872
1732
|
let trimmed_name = name.trim();
|
|
1873
1733
|
let matching_paths = [];
|
|
@@ -1887,15 +1747,33 @@ module.exports = {
|
|
|
1887
1747
|
} // ends for each file
|
|
1888
1748
|
|
|
1889
1749
|
if ( missing_files.length > 0 ) {
|
|
1890
|
-
|
|
1750
|
+
reports.addToReport( scope, {
|
|
1891
1751
|
type: `warning`,
|
|
1892
1752
|
value: `ALKiln could not find "${ missing_files.join('", "') }" in any of these folders: "${ dirs.join('", "') }".`
|
|
1893
1753
|
});
|
|
1894
1754
|
}
|
|
1895
1755
|
|
|
1896
|
-
// If all files missing, return
|
|
1897
|
-
if ( missing_files.length ===
|
|
1898
|
-
return
|
|
1756
|
+
// If all files missing, return an empty array
|
|
1757
|
+
if ( missing_files.length === to_find_names.length ) {
|
|
1758
|
+
return [];
|
|
1759
|
+
}
|
|
1760
|
+
return paths;
|
|
1761
|
+
},
|
|
1762
|
+
|
|
1763
|
+
uploadFiles: async function ( scope, { handle, answer }) {
|
|
1764
|
+
/* Try to upload one or more files to a file-type input field.
|
|
1765
|
+
* Does not submit, so no danger of timeout with server reload.
|
|
1766
|
+
*
|
|
1767
|
+
* Returns whether the row was used or not.
|
|
1768
|
+
*/
|
|
1769
|
+
|
|
1770
|
+
// First make sure the list of files was defined. Don't remove spaces yet -
|
|
1771
|
+
// allow a typo where someone forgot to include a space after a comma.
|
|
1772
|
+
let to_find_names = answer.split(`,`);
|
|
1773
|
+
let paths = await scope.findFiles(scope, {to_find_names});
|
|
1774
|
+
if (paths.length == 0) {
|
|
1775
|
+
// The row wasn't used
|
|
1776
|
+
return false;
|
|
1899
1777
|
}
|
|
1900
1778
|
|
|
1901
1779
|
// Prepare to wait for upload to complete
|
|
@@ -1944,7 +1822,7 @@ module.exports = {
|
|
|
1944
1822
|
* takes a while to load. */
|
|
1945
1823
|
let canvas = await scope.page.waitForSelector( `#dasigcanvas` );
|
|
1946
1824
|
let msg = `Could not find a signature field.`;
|
|
1947
|
-
if ( !canvas ) {
|
|
1825
|
+
if ( !canvas ) { reports.addToReport(scope, { type: `error`, value: msg }); }
|
|
1948
1826
|
expect( canvas, msg ).to.exist;
|
|
1949
1827
|
|
|
1950
1828
|
// Provides functionality to draw name arg on canvas
|
|
@@ -2017,7 +1895,7 @@ module.exports = {
|
|
|
2017
1895
|
// Only record the page id once for each page to which we navigate
|
|
2018
1896
|
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
2019
1897
|
if ( scope.page_id !== id ) {
|
|
2020
|
-
|
|
1898
|
+
reports.addToReport(scope, { type: `page_id`, value: `${ id }`, });
|
|
2021
1899
|
scope.page_id = id;
|
|
2022
1900
|
}
|
|
2023
1901
|
|
|
@@ -2047,9 +1925,9 @@ module.exports = {
|
|
|
2047
1925
|
|
|
2048
1926
|
something_new_was_set = true;
|
|
2049
1927
|
field.was_set = true;
|
|
2050
|
-
|
|
1928
|
+
reports.addToReport(scope, {
|
|
2051
1929
|
type: `row`,
|
|
2052
|
-
value: `${
|
|
1930
|
+
value: `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row_used }) }`
|
|
2053
1931
|
});
|
|
2054
1932
|
|
|
2055
1933
|
// Accumulate number of times this row was used. Esp important for `.target_number`
|
|
@@ -2072,9 +1950,9 @@ module.exports = {
|
|
|
2072
1950
|
let row_used = await scope.setVariable( scope, { field, var_data, });
|
|
2073
1951
|
if ( row_used ) {
|
|
2074
1952
|
|
|
2075
|
-
|
|
1953
|
+
reports.addToReport(scope, {
|
|
2076
1954
|
type: `row`,
|
|
2077
|
-
value: `${
|
|
1955
|
+
value: `${ reports.convertToOriginalStoryTableRow(scope, { row_data: row_used }) }`
|
|
2078
1956
|
});
|
|
2079
1957
|
|
|
2080
1958
|
// Esp important for `.target_number`
|
|
@@ -2116,13 +1994,13 @@ module.exports = {
|
|
|
2116
1994
|
if ( row.source ) { source_row = row.source; }
|
|
2117
1995
|
let original_row = source_row.original;
|
|
2118
1996
|
let msg = `Did not find a field on this page for the variable "${ original_row.var }" that could be set to "${ original_row.value }"`;
|
|
2119
|
-
|
|
1997
|
+
reports.addToReport(scope, { type: `warning`, value: msg });
|
|
2120
1998
|
}
|
|
2121
1999
|
}
|
|
2122
2000
|
if ( num_unused_rows > 0 ) {
|
|
2123
2001
|
let { id } = await scope.examinePageID( scope, 'none to match' );
|
|
2124
2002
|
let msg = `Missing variable or variables on page "${id}"`;
|
|
2125
|
-
|
|
2003
|
+
reports.addToReport(scope, { type: `error`, value: msg });
|
|
2126
2004
|
expect( num_unused_rows, msg ).to.equal( 0 );
|
|
2127
2005
|
}
|
|
2128
2006
|
}
|
|
@@ -2312,7 +2190,7 @@ module.exports = {
|
|
|
2312
2190
|
// probably add a confusing message to the report, so mutating seems, sadly, more useful.
|
|
2313
2191
|
var_datum.value = `False`; // The original value is still preserved
|
|
2314
2192
|
// Warn the developer not to use `.there_is_another`.
|
|
2315
|
-
|
|
2193
|
+
reports.addToReport( scope, { type: `warning`,
|
|
2316
2194
|
value: 'The attribute `.there_is_another` is invalid in story table tests. Replace it with '
|
|
2317
2195
|
+ '`.target_number` in your `var` and `trigger` columns. Set the `value` to the number of items in '
|
|
2318
2196
|
+ `that list. This test will now set this row's \`value\` to \`False\`. See `
|
|
@@ -2346,10 +2224,10 @@ module.exports = {
|
|
|
2346
2224
|
} else if ( value.match( /(true|yes|checked|check|selected|select)/i )) {
|
|
2347
2225
|
if ( from_story_table && !row.artificial ) {
|
|
2348
2226
|
if ( row.var.match( /\.there_is_another$/ ) ) {
|
|
2349
|
-
|
|
2227
|
+
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/automated_integrated_testing#there_is_another-loop. The row data is\n${ JSON.stringify( row.original )}` });
|
|
2350
2228
|
} else {
|
|
2351
2229
|
// If `target_number` is set to True instead of a number
|
|
2352
|
-
|
|
2230
|
+
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.` });
|
|
2353
2231
|
}
|
|
2354
2232
|
return `False`;
|
|
2355
2233
|
} else { return `True`; }
|
|
@@ -2357,7 +2235,7 @@ module.exports = {
|
|
|
2357
2235
|
} else if ( isNaN( desired_num )) { // Story table loop will end
|
|
2358
2236
|
// I can't figure out how to trigger this warning, so maybe we're
|
|
2359
2237
|
// already handling everything we need to
|
|
2360
|
-
|
|
2238
|
+
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.` });
|
|
2361
2239
|
return `False`;
|
|
2362
2240
|
|
|
2363
2241
|
// Check that the number of elements in the list hits our desired number.
|
|
@@ -2408,7 +2286,7 @@ module.exports = {
|
|
|
2408
2286
|
}
|
|
2409
2287
|
|
|
2410
2288
|
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.`
|
|
2411
|
-
if ( timedOut ) {
|
|
2289
|
+
if ( timedOut ) { reports.addToReport(scope, { type: `error`, value: timeout_err_message }); }
|
|
2412
2290
|
expect( timedOut, timeout_err_message ).to.be.false;
|
|
2413
2291
|
|
|
2414
2292
|
clearTimeout( cont_timeout );
|
|
@@ -2452,13 +2330,13 @@ module.exports = {
|
|
|
2452
2330
|
/* Throw a cucumber error with the error that appeared on the page. */
|
|
2453
2331
|
if ( error_handlers.system_error !== undefined ) {
|
|
2454
2332
|
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.`
|
|
2455
|
-
|
|
2333
|
+
reports.addToReport(scope, { type: `error`, value: sys_err_message });
|
|
2456
2334
|
expect( was_system_error, sys_err_message ).to.be.false;
|
|
2457
2335
|
|
|
2458
2336
|
} else {
|
|
2459
2337
|
// If it wasn't a system error, it was a user error
|
|
2460
2338
|
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.`
|
|
2461
|
-
|
|
2339
|
+
reports.addToReport(scope, { type: `error`, value: user_err_message });
|
|
2462
2340
|
expect( true, user_err_message ).to.be.false;
|
|
2463
2341
|
}
|
|
2464
2342
|
|
|
@@ -2480,6 +2358,22 @@ module.exports = {
|
|
|
2480
2358
|
fullPage: fullPage,
|
|
2481
2359
|
});
|
|
2482
2360
|
|
|
2361
|
+
let html_path = path;
|
|
2362
|
+
if (path.endsWith(".jpg")) {
|
|
2363
|
+
html_path = html_path.substring(0, html_path.length - 4) + ".html";
|
|
2364
|
+
} else {
|
|
2365
|
+
html_path = html_path + ".html";
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
// Also save the HTML of the page
|
|
2369
|
+
await scope.page.content().then(content => {
|
|
2370
|
+
let server_url = session_vars.get_da_server_url();
|
|
2371
|
+
content = content.replaceAll(/"(\/static\/.*\.css\?v=[^"]+")/g, server_url + "$1");
|
|
2372
|
+
content = content.replaceAll(/"(\/static\/.*\.js\?v=[^"]+")/g, server_url + "$1");
|
|
2373
|
+
content = content.replaceAll(/"(\/packagestatic\/.*\.css\?v=[^"]+")/g, server_url + "$1");
|
|
2374
|
+
content = content.replaceAll(/"(\/packagestatic\/.*\.js\?v=[^"]+")/g, server_url + "$1");
|
|
2375
|
+
fs.writeFileSync(html_path, content)
|
|
2376
|
+
});
|
|
2483
2377
|
}, // Ends scope.take_a_screenshot()
|
|
2484
2378
|
|
|
2485
2379
|
|
|
@@ -2519,7 +2413,7 @@ module.exports = {
|
|
|
2519
2413
|
});
|
|
2520
2414
|
|
|
2521
2415
|
// In future, may be saved to artifact file
|
|
2522
|
-
|
|
2416
|
+
reports.addToReport( scope, {
|
|
2523
2417
|
type: `json`,
|
|
2524
2418
|
value: JSON.stringify( data, null, 2 )
|
|
2525
2419
|
});
|
|
@@ -2535,7 +2429,7 @@ module.exports = {
|
|
|
2535
2429
|
let response = await linkPage.goto( actual_url, { waitUntil: 'domcontentloaded' });
|
|
2536
2430
|
|
|
2537
2431
|
let msg = `The "${ linkText }" link is broken.`;
|
|
2538
|
-
if ( !response.ok() ) {
|
|
2432
|
+
if ( !response.ok() ) { reports.addToReport( scope, { type: `error`, value: msg }); }
|
|
2539
2433
|
expect( response.ok(), msg ).to.be.true;
|
|
2540
2434
|
|
|
2541
2435
|
// This may cause problems if the linked page is the interview page
|
|
@@ -2584,7 +2478,7 @@ module.exports = {
|
|
|
2584
2478
|
const [link] = await scope.page.$x(`//a[contains(text(), "${phrase}")]`);
|
|
2585
2479
|
|
|
2586
2480
|
let msg = `The term "${ phrase }" seems to be missing.`;
|
|
2587
|
-
if ( !link ) {
|
|
2481
|
+
if ( !link ) { reports.addToReport(scope, { type: `error`, value: msg }); }
|
|
2588
2482
|
expect( link, msg ).to.exist;
|
|
2589
2483
|
|
|
2590
2484
|
await scope.tapElement( scope, link );
|
|
@@ -2611,7 +2505,7 @@ module.exports = {
|
|
|
2611
2505
|
let [elem] = await scope.page.$x(`//a[contains(@href, "${ filename }")]`);
|
|
2612
2506
|
|
|
2613
2507
|
let msg = `"${ filename }" seems to be missing. Cannot find a link to that document.`;
|
|
2614
|
-
if ( !elem ) {
|
|
2508
|
+
if ( !elem ) { reports.addToReport(scope, { type: `error`, value: msg }); }
|
|
2615
2509
|
expect( elem, msg ).to.exist;
|
|
2616
2510
|
|
|
2617
2511
|
scope.toDownload = filename;
|
|
@@ -2620,6 +2514,32 @@ module.exports = {
|
|
|
2620
2514
|
await scope.detectDownloadComplete( scope );
|
|
2621
2515
|
}, // Ends scope.steps.download()
|
|
2622
2516
|
|
|
2517
|
+
compare_pdfs: async function (scope, {existing_pdf_path, new_pdf_path}) {
|
|
2518
|
+
let existing_paths = await scope.findFiles(scope, {to_find_names: [existing_pdf_path]});
|
|
2519
|
+
if (existing_paths.length == 0) {
|
|
2520
|
+
// The row wasn't used
|
|
2521
|
+
let msg = `Could not find the existing PDF at ${ existing_pdf_path }`;
|
|
2522
|
+
reports.addToReport(scope, { type: `error`, value: msg });
|
|
2523
|
+
scope.failed_pdf_compares.push(msg);
|
|
2524
|
+
// Return early since we couldn't find the PDF
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2527
|
+
let full_existing_path = existing_paths[0];
|
|
2528
|
+
let full_new_pdf_path = `${scope.paths.scenario}/${new_pdf_path}`;
|
|
2529
|
+
let diffs = await pdf_reader.compare_pdfs(full_existing_path, full_new_pdf_path);
|
|
2530
|
+
if (diffs) {
|
|
2531
|
+
let added_str = diffs.filter(part => part.added).reduce((err_str, part) => {
|
|
2532
|
+
return err_str + `- ${ part.value }\n`
|
|
2533
|
+
}, 'The new PDF added: \n');
|
|
2534
|
+
let removed_str = diffs.filter(part => part.removed).reduce((err_str, part) => {
|
|
2535
|
+
return err_str + `- ${ part.value }\n`
|
|
2536
|
+
}, 'The new PDF removed: \n');
|
|
2537
|
+
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}`;
|
|
2538
|
+
reports.addToReport(scope, { type: `error`, value: msg });
|
|
2539
|
+
scope.failed_pdf_compares.push(msg);
|
|
2540
|
+
}
|
|
2541
|
+
},
|
|
2542
|
+
|
|
2623
2543
|
set_al_name: async ( scope, var_base, name_str ) => {
|
|
2624
2544
|
/** Given a variable name and a space-separated string, fills the
|
|
2625
2545
|
* appropriate fields on an Assembly Line name question.
|
|
@@ -2647,7 +2567,7 @@ module.exports = {
|
|
|
2647
2567
|
name_parts_slice.push(name_parts_last);
|
|
2648
2568
|
name_parts = name_parts_slice;
|
|
2649
2569
|
|
|
2650
|
-
|
|
2570
|
+
reports.addToReport(scope, {
|
|
2651
2571
|
type: `warning`,
|
|
2652
2572
|
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(" ")}".`
|
|
2653
2573
|
});
|
|
@@ -2733,7 +2653,7 @@ module.exports = {
|
|
|
2733
2653
|
await scope.handle_page_timeout_error( scope, { non_reload_report_msg, error });
|
|
2734
2654
|
} else {
|
|
2735
2655
|
// Throw any non-timeout error
|
|
2736
|
-
|
|
2656
|
+
reports.addToReport( scope, { type: `error`, value: err_msg });
|
|
2737
2657
|
throw error;
|
|
2738
2658
|
} // ends if error is timeout error
|
|
2739
2659
|
|
|
@@ -2747,11 +2667,11 @@ module.exports = {
|
|
|
2747
2667
|
// this is complex
|
|
2748
2668
|
let email_msg = `The email address GitHub SECRET "${ email_secret_name }" doesn't exist. Check for a typo and check your workflow file.`
|
|
2749
2669
|
if ( email === undefined ) {
|
|
2750
|
-
|
|
2670
|
+
reports.addToReport( scope, { type: `error`, value: email_msg })
|
|
2751
2671
|
}
|
|
2752
2672
|
let password_msg = `The password GitHub SECRET "${ password_secret_name }" doesn't exist. Check for a typo and check your workflow file.`
|
|
2753
2673
|
if ( password === undefined ) {
|
|
2754
|
-
|
|
2674
|
+
reports.addToReport( scope, { type: `error`, value: password_msg })
|
|
2755
2675
|
}
|
|
2756
2676
|
|
|
2757
2677
|
expect( email, email_msg ).to.not.equal( undefined );
|
|
@@ -2768,7 +2688,7 @@ module.exports = {
|
|
|
2768
2688
|
// TODO: use a Promise.race to fail faster.
|
|
2769
2689
|
await scope.page.waitForSelector( `.datopcenter .alert-success` );
|
|
2770
2690
|
|
|
2771
|
-
|
|
2691
|
+
reports.addToReport( scope, {
|
|
2772
2692
|
type: `row`,
|
|
2773
2693
|
value: `Signed into ${ session_vars.get_da_server_url() }/user/sign-in successfully.`
|
|
2774
2694
|
});
|
|
@@ -2910,7 +2830,7 @@ module.exports = {
|
|
|
2910
2830
|
if ( type !== `` && type !== `hidden` ) {
|
|
2911
2831
|
// Field types that we can't yet handle, but plan to in future
|
|
2912
2832
|
if ( type === `file` ) {
|
|
2913
|
-
|
|
2833
|
+
reports.addToReport( scope, {
|
|
2914
2834
|
type: `warning`,
|
|
2915
2835
|
value: `Sorry, ALKiln's random input tests cannot yet handle "${ type }" fields.`
|
|
2916
2836
|
});
|
|
@@ -3016,7 +2936,7 @@ module.exports = {
|
|
|
3016
2936
|
*/
|
|
3017
2937
|
let current_report_obj = scope.report.get( scope.scenario_id );
|
|
3018
2938
|
let scenario = [ scope.scenario_id, current_report_obj ]; // Mimic how loop works with `Map`
|
|
3019
|
-
let report =
|
|
2939
|
+
let report = reports.getPrintableScenario( scenario );
|
|
3020
2940
|
let all_are_included = true;
|
|
3021
2941
|
for ( let one_expectation of expected ) {
|
|
3022
2942
|
if ( !report.includes( one_expectation )) {
|
|
@@ -3036,7 +2956,7 @@ module.exports = {
|
|
|
3036
2956
|
*/
|
|
3037
2957
|
let current_report_obj = scope.report.get( scope.scenario_id );
|
|
3038
2958
|
let scenario = [ scope.scenario_id, current_report_obj ]; // Mimic how loop works with `Map`
|
|
3039
|
-
let report =
|
|
2959
|
+
let report = reports.getPrintableScenario( scenario );
|
|
3040
2960
|
let none_included = true;
|
|
3041
2961
|
for ( let one_expectation of not_expected ) {
|
|
3042
2962
|
if ( report.includes( one_expectation )) {
|
|
@@ -3047,4 +2967,5 @@ module.exports = {
|
|
|
3047
2967
|
|
|
3048
2968
|
return none_included;
|
|
3049
2969
|
},
|
|
2970
|
+
|
|
3050
2971
|
};
|