@suffolklitlab/alkiln 5.11.0 → 5.11.2

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 CHANGED
@@ -45,7 +45,29 @@ Format:
45
45
 
46
46
  <!-- ## [Unreleased] -->
47
47
 
48
- ## [5.11] - 2024-04-05
48
+ ## [5.11.2] - 2024-05-17
49
+
50
+ ### Added
51
+
52
+ - Added new debug log/code to reflect difference between a expected status mismatch and a cucumber status mismatch.
53
+
54
+ ### Changed
55
+
56
+ - Changed text of error to make it more clear.
57
+ - Changed logic of error finding to use expected status for users as well as internal tests. That needs discussion.
58
+ - Refactored code in that section.
59
+ - Wait till the end to throw some errors so the user can get as much info as possible about the failures.
60
+
61
+ ### Internal
62
+
63
+ - Exclude another file from code checking (cucumber-report.txt)
64
+
65
+ ## [5.11.1] - 2024-04-06
66
+
67
+ ### Fixed
68
+ - Typo in run_cucumber.js
69
+
70
+ ## [5.11.0] - 2024-04-05
49
71
 
50
72
  ### Added
51
73
 
@@ -101,7 +101,7 @@ function build_config( command_args ) {
101
101
  }, sources: {paths: []}}, environment);
102
102
 
103
103
  log.info({ type: `run`, code: `ALK0053`, pre: `working directory`, data: codeDir });
104
- log.info(type: `plain`, pre: `\n\n`);
104
+ log.info({ type: `plain`, pre: `\n\n` });
105
105
 
106
106
  const { success } = await cucumber_api.runCucumber({...runConfiguration, support});
107
107
  if ( success ) {
package/lib/steps.js CHANGED
@@ -1262,7 +1262,7 @@ After(async function(scenario) {
1262
1262
  // Save the report as in the Scenario folder
1263
1263
  fs.writeFileSync( scope.paths.scenario_report, report );
1264
1264
 
1265
- // ---------------- Check internal test results of this framework ----------------
1265
+ // ---------------- Check internal test results ----------------
1266
1266
 
1267
1267
  if ( scope.expected_in_report && scope.expected_in_report.length > 0) {
1268
1268
  let report_includes_all_expected_strings = await scope.reportIncludesAllExpected(
@@ -1284,74 +1284,120 @@ After(async function(scenario) {
1284
1284
  scope.expected_not_in_report = null;
1285
1285
  }
1286
1286
 
1287
- // The default is 'passed', which won't need to get in here
1288
- if ( scope.expected_status ) {
1289
- // When internal tests should fail (to test our failure conditions), passing _is_ failing
1290
- expect( changeable_test_status ).to.equal( scope.expected_status );
1291
- // If the status was as expected, pass this Scenario
1292
- changeable_test_status = `PASSED`;
1293
- scope.expected_status = null; // reset for next Scenario
1287
+ // ---------------- Ends internal results check ----------------
1288
+
1289
+ if ( scope.expected_status === null ) {
1290
+ scope.expected_status = `PASSED`; // default expected status
1294
1291
  }
1295
1292
 
1296
- // ---------------- Ends check internal test results of this framework ----------------
1293
+ let expected_status_was_met = true;
1294
+ let expected_status_err_msg = ``;
1295
+ // Avoid manipulating `UNDEFINED` and such
1296
+ if ( changeable_test_status === `PASSED`
1297
+ || changeable_test_status === `FAILED` ) {
1298
+
1299
+ if ( changeable_test_status === scope.expected_status ) {
1300
+ // If the status was as expected, pass this Scenario. E.g. an internal
1301
+ // test was supposed to fail and it did. Or a test was suppose to pass
1302
+ // and it passed.
1303
+ changeable_test_status = `PASSED`;
1304
+ } else {
1305
+ // If a test that was supposed to fail passed (e.g. internal
1306
+ // test), it failed. If is was supposed to pass and failed, it also
1307
+ // failed. E.g. a11y failures let the Scenario pass initially, but
1308
+ // should cause a failure here.
1309
+ changeable_test_status = `FAILED`;
1310
+ // Flag this failure to trigger an error later, so cucumber shows
1311
+ // it as failed too.
1312
+ expected_status_was_met = false;
1313
+ // Keep it general. Users may see this message, e.g. for a11y tests.
1314
+ let msg = `Test failed. Expected status: ${scope.expected_status}. `
1315
+ + `ALKiln's assessed status: ${ changeable_test_status }. `
1316
+ + `See the report for details.`;
1317
+ let code = `ALK0099`;
1318
+ log.debug({ type: `error`, code: code, pre: msg, })
1319
+ expected_status_err_msg = `🤕 ${ code } ERROR: ${ msg }`
1320
+ }
1321
+ }
1322
+ scope.expected_status = null; // reset for next Scenario
1323
+
1324
+ let need_to_force_failed_status = false;
1325
+ let force_failure_msg = `ALKiln assessed that the test failed. See the report for details.`;
1326
+ let force_failure_code = `ALK0180`;
1327
+ if ( changeable_test_status !== `FAILED` ) {
1328
+ // Other than `FAILED`, it's fine to set the scenario status to make
1329
+ // sure it matches up with ALKiln's assessed status.
1330
+ // WARNING: This may be impossible in future cucumber versions
1331
+ scenario.result.status = changeable_test_status;
1332
+ // TODO: Should we add (an info) debug log here too?
1333
+
1334
+ // If assessed status is FAILED, but result.status is something else
1335
+ } else if ( scenario.result.status !== `FAILED` ) {
1336
+ // Make sure that tests which ALKiln has calculated as failed
1337
+ // cause a cucumber error later. Just changing the status to `FAILED`
1338
+ // causes unhelpful cucumber errors. TODO: Add to internal docs.
1339
+ log.debug({
1340
+ type: `error`,
1341
+ code: force_failure_code,
1342
+ pre: force_failure_msg
1343
+ });
1344
+ // TODO: Look into setDefinitionFunctionWrapper to catch errors
1345
+ // of failing tests that should indeed be failing:
1346
+ // https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/api_reference.md#setdefinitionfunctionwrapperwrapper
1347
+ need_to_force_failed_status = true;
1348
+ }
1297
1349
 
1350
+ let signout_succeeded = true;
1351
+ let signout_error_msg = ``;
1298
1352
  // If there is a page open, then sign out and close it
1299
1353
  if ( scope.page ) {
1300
1354
  // Catch a possible reload error.
1301
-
1302
- // TODO: implement and use scope.handle_possible_timeout()
1303
1355
  try {
1304
1356
  // puppeteer will ensure proper timeout.
1305
1357
  await scope.page.goto(`${ session_vars.get_da_server_url() }/user/sign-out`, {waitUntil: `domcontentloaded`});
1306
1358
 
1307
1359
  } catch ( error ) {
1360
+ signout_succeeded = false;
1308
1361
 
1309
1362
  if ( error.name === `TimeoutError` ) {
1310
1363
  // TODO: Should a more specific message about signing out get into the report no matter what?
1311
1364
  // If so, what should the message be in order to not get confused with these other messages?
1312
1365
  let non_reload_report_msg = `It took too long to sign out in preparation for the next test.`;
1313
- await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
1314
- code: `ALK0097`,
1315
- message: non_reload_report_msg,
1316
- }, error });
1366
+ let code = `ALK0097`;
1367
+ try {
1368
+ await scope.handle_page_timeout_error( scope, { non_reload_report_data: {
1369
+ code: code,
1370
+ message: non_reload_report_msg,
1371
+ }, error });
1372
+ } catch {
1373
+ signout_error_msg = `🤕 ${ code } ERROR: ${ non_reload_report_msg }`;
1374
+ }
1317
1375
  } else {
1318
1376
  // Throw any non-timeout error
1319
- let err_msg = `Error occurred when ALKiln tried to sign out in preparation for the next test.`
1320
- reports.addToReport( scope, { type: `error`, code: `ALK0098`, value: err_msg });
1321
- throw error;
1377
+ let other_err_msg = `Error occurred when ALKiln tried to sign out in preparation for the next test.`
1378
+ let code = `ALK0098`;
1379
+ reports.addToReport( scope, { type: `error`, code: code, value: other_err_msg });
1380
+ signout_error_msg = `🤕 ${ code } ERROR: ${ other_err_msg }`;
1322
1381
  } // ends if error is timeout error
1323
1382
 
1324
1383
  } // ends try/catch
1325
1384
 
1326
1385
  } // ends if scope.page
1327
1386
 
1328
- // INTERNAL WARNING: TODO: A console.log here prevents the try/catch from
1329
- // throwing an error. Why is that? Does it somehow make sure that scope.page
1330
- // gets destroyed?
1331
-
1332
- // console.log('This stops try/catch from throwing an error in some cases.');
1333
-
1334
- // More internal testing stuff
1335
- if ( changeable_test_status === `FAILED` ) {
1336
- // If the result object status wasn't failure and we still want
1337
- // the tests to fail, as with a11y tests, we can't mess with the
1338
- // cucumber result.status object because it will cause unwanted
1339
- // errors. We have to throw an error here instead.
1340
- if ( scenario.result.status !== `FAILED` ) {
1341
- let msg = `The test unexpectedly didn't fail. Scenario status: ${scenario.result.status}.`
1342
- reports.addToReport( scope, { type: `error`, code: `ALK0099`, value: msg });
1343
- throw new Error(msg);
1344
- }
1345
- } else {
1346
- // Some internal test failures should be ok
1347
- // TODO: Look into setDefinitionFunctionWrapper to catch errors
1348
- // of failing tests that should indeed be failing:
1349
- // https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/api_reference.md#setdefinitionfunctionwrapperwrapper
1350
- scenario.result.status = changeable_test_status;
1387
+ let errors = []
1388
+ if ( !expected_status_was_met ) { errors.push( expected_status_err_msg ); }
1389
+ if ( !signout_succeeded ) { errors.push( signout_error_msg ); }
1390
+ if ( !expected_status_was_met || !signout_succeeded ) {
1391
+ throw new Error( `${errors.join( errors, '\n')}` );
1392
+ }
1393
+
1394
+ // Theoretically, we should never get here:
1395
+ // If everything else worked, if we need to force an internal test failure
1396
+ if ( need_to_force_failed_status ) {
1397
+ throw new Error( `🤕 ${force_failure_code} unreachable ERROR: ${force_failure_msg}` );
1351
1398
  }
1352
- // Ends more internal testing stuff
1353
1399
 
1354
- // WARNING: TODO: console.log can prevent a sign-out error. What race condition is going on?
1400
+ // Find the race condition.
1355
1401
  log.debug({ type: `cucumber`, code: `ALK0100`, verbose: true, pre: `Scenario AfterStep() message`, data: scenario.result.message });
1356
1402
 
1357
1403
  });
package/lib/utils/log.js CHANGED
@@ -2,6 +2,8 @@ const fs = require('fs');
2
2
  const session_vars = require( './session_vars' );
3
3
 
4
4
  // ? 🌈 💡 🔎 🤕 🐞
5
+ // TODO: return full message so it can be passed to manually
6
+ // thrown errors if needed.
5
7
 
6
8
  let log = {};
7
9
  module.exports = log;
@@ -46,6 +46,9 @@ reports.addToReport = function( scope, { type, code, value }) {
46
46
  * @params code {string} (Optional) Error or warning code. Default
47
47
  * is unspecified error or warning.
48
48
  * */
49
+ // TODO: return full message so it can be passed to manually
50
+ // thrown errors if needed.
51
+
49
52
  // Debugging logs
50
53
  let debug_line = getDebugLine({ type, code, value });
51
54
  if ( session_vars.get_debug() ) {
@@ -120,7 +120,7 @@ session_vars.save_project_name = function ( project_name ) {
120
120
  // Warn local developers if file already exists
121
121
  if ( fs.existsSync( runtime_config_path ) ) {
122
122
  let old_project_name = session_vars.get_project_name();
123
- let session_project_already_exists_msg = `🔎 ALK0035 WARNING: `
123
+ let session_project_already_exists_msg = `🔎 ALK0035 setup WARNING: `
124
124
  + `This session had a project name already: ${ old_project_name }. `
125
125
  + `A new project has now been created called ${ project_name }. `
126
126
  + `Remember to delete ${ old_project_name }`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suffolklitlab/alkiln",
3
- "version": "5.11.0",
3
+ "version": "5.11.2",
4
4
  "description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -16,7 +16,7 @@ fi
16
16
  # The grepped files will include the list of all the codes that have been
17
17
  # removed and are no longer used. Syntax used works with GitHub cli ([[:digit:]])
18
18
  # https://stackoverflow.com/a/6901221
19
- lines=$(grep -roh --exclude="tests/log_codes/check_codes.sh" --exclude="debug_log.txt" --exclude-dir="node_modules" --exclude-dir='alkiln-*' --exclude-dir='_alkiln*' 'ALK[[:digit:]][[:digit:]][[:digit:]][[:digit:]]' "$directory")
19
+ lines=$(grep -roh --exclude="tests/log_codes/check_codes.sh" --exclude="debug_log.txt" --exclude="cucumber-report.txt" --exclude-dir="node_modules" --exclude-dir='alkiln-*' --exclude-dir='_alkiln*' 'ALK[[:digit:]][[:digit:]][[:digit:]][[:digit:]]' "$directory")
20
20
  sorted=$(echo "$lines" | sort -n)
21
21
 
22
22