botium-core 1.14.9 → 1.14.10

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/README.md CHANGED
@@ -13,10 +13,6 @@
13
13
 
14
14
  **_IF YOU LIKE WHAT YOU SEE, PLEASE CONSIDER GIVING US A STAR ON GITHUB!_**
15
15
 
16
- **UPDATE 2020/11/05:** Botium has a FREE, hosted plan available! The new Botium Box Mini is our ❤️ to the community. [Take it for a test drive 🚗 ...](https://www.botium.ai/pricing/)
17
-
18
- [![](http://img.youtube.com/vi/ciVxojvRfng/0.jpg)](https://www.youtube.com/watch?v=ciVxojvRfng "Botium Box Mini")
19
-
20
16
  ## Getting Help
21
17
 
22
18
  See our [Botium Forum](https://forum.botium.ai/)
@@ -77,7 +77,7 @@ var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
77
77
  var bodyParser__default = /*#__PURE__*/_interopDefaultLegacy(bodyParser);
78
78
 
79
79
  var name = "botium-core";
80
- var version$1 = "1.14.9";
80
+ var version$1 = "1.14.10";
81
81
  var description = "The Selenium for Chatbots";
82
82
  var main = "index.js";
83
83
  var module$1 = "dist/botium-es.js";
@@ -140,6 +140,7 @@ var dependencies = {
140
140
  "socketio-auth": "^0.1.1",
141
141
  "swagger-jsdoc": "^6.2.8",
142
142
  "swagger-ui-express": "^5.0.0",
143
+ tinyglobby: "^0.2.10",
143
144
  uuid: "^9.0.1",
144
145
  "word-error-rate": "0.0.7",
145
146
  "write-yaml": "^1.0.0",
@@ -1124,9 +1125,9 @@ var LogicHookUtils_1 = class LogicHookUtils {
1124
1125
  caps
1125
1126
  }) {
1126
1127
  this.asserters = {};
1127
- this.globalAsserters = [];
1128
+ this.globalAsserterNames = [];
1128
1129
  this.logicHooks = {};
1129
- this.globalLogicHooks = [];
1130
+ this.globalLogicHookNames = [];
1130
1131
  this.userInputs = {};
1131
1132
  this.buildScriptContext = buildScriptContext;
1132
1133
  this.caps = caps;
@@ -1159,7 +1160,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1159
1160
  }
1160
1161
  this.asserters[asserter.ref] = this._loadClass(asserter, 'asserter');
1161
1162
  if (asserter.global) {
1162
- this.globalAsserters.push(asserter.ref);
1163
+ this.globalAsserterNames.push(asserter.ref);
1163
1164
  }
1164
1165
  });
1165
1166
  }
@@ -1170,7 +1171,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1170
1171
  }
1171
1172
  this.logicHooks[logicHook.ref] = this._loadClass(logicHook, 'logichook');
1172
1173
  if (logicHook.global) {
1173
- this.globalLogicHooks.push(logicHook.ref);
1174
+ this.globalLogicHookNames.push(logicHook.ref);
1174
1175
  }
1175
1176
  });
1176
1177
  }
@@ -1182,11 +1183,17 @@ var LogicHookUtils_1 = class LogicHookUtils {
1182
1183
  this.userInputs[userInput.ref] = this._loadClass(userInput, 'userinput');
1183
1184
  });
1184
1185
  }
1185
- getGlobalAsserter() {
1186
- return this.globalAsserters.map(name => this.asserters[name]);
1186
+ getGlobalAsserters() {
1187
+ return this.globalAsserterNames.reduce((agg, name) => ({
1188
+ ...agg,
1189
+ [name]: this.asserters[name]
1190
+ }), {});
1187
1191
  }
1188
- getGlobalLogicHook() {
1189
- return this.globalLogicHooks.map(name => this.logicHooks[name]);
1192
+ getGlobalLogicHooks() {
1193
+ return this.globalLogicHookNames.reduce((agg, name) => ({
1194
+ ...agg,
1195
+ [name]: this.logicHooks[name]
1196
+ }), {});
1190
1197
  }
1191
1198
  _loadClass({
1192
1199
  src,
@@ -2976,6 +2983,10 @@ class Convo$6 {
2976
2983
  let skipTranscriptStep = false;
2977
2984
  let conditionalGroupId = null;
2978
2985
  let conditionMetInGroup = false;
2986
+ let skipOptionalStep = false;
2987
+ // If there are optional step(s) in the conversation, and the message from the bot fails on each optional bot step(s) and/or mandatory bot step, then we have an unexpected message.
2988
+ // So in this case an unexpected error should be shown instead of the latest assertion error.
2989
+ let optionalStepAssertionError = false;
2979
2990
  let globalConvoStepParameters = container.caps[Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS] || {};
2980
2991
  let retryBotMessageTimeoutEnd = null;
2981
2992
  let retryBotMessageConvoId = null;
@@ -2983,6 +2994,13 @@ class Convo$6 {
2983
2994
  for (let i = 0; i < this.conversation.length; i = retryBotMessageDropBotResponse ? i : i + 1) {
2984
2995
  retryBotMessageDropBotResponse = false;
2985
2996
  const convoStep = this.conversation[i];
2997
+ if (!convoStep.optional) {
2998
+ skipOptionalStep = false;
2999
+ }
3000
+ if (convoStep.optional && skipOptionalStep) {
3001
+ // If there are multiple optional steps, and the previous optional step was timeout, then the next optional step should be skipped to prevent too long convo run with multiple timeout.
3002
+ continue;
3003
+ }
2986
3004
  const rawConvoStepParameters = convoStep.logicHooks.find(lh => lh.name === 'CONVO_STEP_PARAMETERS')?.args;
2987
3005
  let convoStepParameters = {};
2988
3006
  if (rawConvoStepParameters && rawConvoStepParameters.length) {
@@ -3167,7 +3185,8 @@ class Convo$6 {
3167
3185
  debug$k(`${this.header.name}: bot says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3168
3186
  } catch (err) {
3169
3187
  transcriptStep.botEnd = new Date();
3170
- if (convoStep.optional) {
3188
+ if (!(err.message.indexOf('Bot did not respond within') < 0) && convoStep.optional) {
3189
+ skipOptionalStep = true;
3171
3190
  continue;
3172
3191
  }
3173
3192
  const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: error waiting for bot - ${err.message}`, err);
@@ -3251,6 +3270,7 @@ class Convo$6 {
3251
3270
  }
3252
3271
  waitForBotSays = false;
3253
3272
  skipTranscriptStep = true;
3273
+ optionalStepAssertionError = true;
3254
3274
  return true;
3255
3275
  } else if (retryOn) {
3256
3276
  if (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag) {
@@ -3268,9 +3288,18 @@ class Convo$6 {
3268
3288
  }
3269
3289
  }
3270
3290
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
3271
- assertErrors.push(err);
3291
+ if (optionalStepAssertionError) {
3292
+ optionalStepAssertionError = false;
3293
+ assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
3294
+ } else {
3295
+ assertErrors.push(err);
3296
+ }
3272
3297
  return false;
3273
3298
  } else {
3299
+ if (optionalStepAssertionError) {
3300
+ optionalStepAssertionError = false;
3301
+ throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
3302
+ }
3274
3303
  throw err;
3275
3304
  }
3276
3305
  };
@@ -3284,6 +3313,7 @@ class Convo$6 {
3284
3313
  if (convoStep.not) {
3285
3314
  try {
3286
3315
  this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3316
+ optionalStepAssertionError = false;
3287
3317
  } catch (err) {
3288
3318
  if (isErrorHandledWithOptionConvoStep(err)) {
3289
3319
  continue;
@@ -3292,6 +3322,7 @@ class Convo$6 {
3292
3322
  } else {
3293
3323
  try {
3294
3324
  this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3325
+ optionalStepAssertionError = false;
3295
3326
  } catch (err) {
3296
3327
  if (isErrorHandledWithOptionConvoStep(err)) {
3297
3328
  continue;
@@ -3301,6 +3332,7 @@ class Convo$6 {
3301
3332
  } else if (convoStep.sourceData) {
3302
3333
  try {
3303
3334
  this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg, convoStepParameters);
3335
+ optionalStepAssertionError = false;
3304
3336
  } catch (err) {
3305
3337
  if (isErrorHandledWithOptionConvoStep(err)) {
3306
3338
  continue;
@@ -3327,11 +3359,13 @@ class Convo$6 {
3327
3359
  transcript,
3328
3360
  transcriptStep
3329
3361
  });
3362
+ optionalStepAssertionError = false;
3330
3363
  } catch (err) {
3331
3364
  const nextConvoStep = this.conversation[i + 1];
3332
3365
  if (convoStep.optional && nextConvoStep && nextConvoStep.sender === 'bot') {
3333
3366
  waitForBotSays = false;
3334
3367
  skipTranscriptStep = true;
3368
+ optionalStepAssertionError = true;
3335
3369
  continue;
3336
3370
  }
3337
3371
  const errors = err.toArray ? err.toArray() : [];
@@ -3360,8 +3394,17 @@ class Convo$6 {
3360
3394
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3361
3395
  } catch (failErr) {}
3362
3396
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
3363
- assertErrors.push(err);
3397
+ if (optionalStepAssertionError) {
3398
+ optionalStepAssertionError = false;
3399
+ assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
3400
+ } else {
3401
+ assertErrors.push(err);
3402
+ }
3364
3403
  } else {
3404
+ if (optionalStepAssertionError) {
3405
+ optionalStepAssertionError = false;
3406
+ throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
3407
+ }
3365
3408
  throw failErr;
3366
3409
  }
3367
3410
  }
@@ -5562,9 +5605,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
5562
5605
  this.utterances = {};
5563
5606
  this.matchFn = null;
5564
5607
  this.asserters = {};
5565
- this.globalAsserter = {};
5608
+ this.globalAsserters = {};
5566
5609
  this.logicHooks = {};
5567
- this.globalLogicHook = {};
5610
+ this.globalLogicHooks = {};
5568
5611
  this.userInputs = {};
5569
5612
  this.partialConvos = {};
5570
5613
  this.scriptingMemories = [];
@@ -5933,7 +5976,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5933
5976
  return p(this.retryHelperAsserter, () => asserter[asserterType](params));
5934
5977
  }
5935
5978
  };
5936
- const convoAsserter = asserters.filter(a => this.asserters[a.name][asserterType]).map(a => ({
5979
+ const localAsserters = (asserters || []).filter(a => this.asserters[a.name][asserterType]);
5980
+ const convoStepPromises = localAsserters.map(a => ({
5937
5981
  asserter: a,
5938
5982
  promise: callAsserter(a, this.asserters[a.name], {
5939
5983
  convo,
@@ -5948,7 +5992,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5948
5992
  promise,
5949
5993
  asserter
5950
5994
  }) => updateExceptionContext(promise, asserter));
5951
- const globalAsserter = Object.values(this.globalAsserter).filter(a => a[asserterType]).map(a => ({
5995
+ const globalAsserters = Object.keys(this.globalAsserters).filter(name => localAsserters.map(a => a.name).indexOf(name) < 0).reduce((agg, name) => [...agg, this.globalAsserters[name]], []).filter(a => a[asserterType]);
5996
+ const globalPromises = globalAsserters.map(a => ({
5952
5997
  asserter: a,
5953
5998
  promise: p(this.retryHelperAsserter, () => a[asserterType]({
5954
5999
  convo,
@@ -5963,7 +6008,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5963
6008
  promise,
5964
6009
  asserter
5965
6010
  }) => updateExceptionContext(promise, asserter));
5966
- const allPromises = [...convoAsserter, ...globalAsserter];
6011
+ const allPromises = [...convoStepPromises, ...globalPromises];
5967
6012
  if (this.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
5968
6013
  return Promise.allSettled(allPromises).then(results => {
5969
6014
  const rejected = results.filter(result => result.status === 'rejected').map(result => result.reason);
@@ -5998,7 +6043,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5998
6043
  isGlobal: false,
5999
6044
  ...rest
6000
6045
  })));
6001
- const globalHooks = Object.values(this.globalLogicHook).filter(l => l[hookType]);
6046
+ const globalHooks = Object.keys(this.globalLogicHooks).filter(name => localHooks.map(l => l.name).indexOf(name) < 0).reduce((agg, name) => [...agg, this.globalLogicHooks[name]], []).filter(l => l[hookType]);
6002
6047
  const globalPromises = globalHooks.map(l => p(this.retryHelperLogicHook, () => l[hookType]({
6003
6048
  convo,
6004
6049
  convoStep,
@@ -6118,9 +6163,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
6118
6163
  caps: this.caps
6119
6164
  });
6120
6165
  this.asserters = logicHookUtils.asserters;
6121
- this.globalAsserter = logicHookUtils.getGlobalAsserter();
6166
+ this.globalAsserters = logicHookUtils.getGlobalAsserters();
6122
6167
  this.logicHooks = logicHookUtils.logicHooks;
6123
- this.globalLogicHook = logicHookUtils.getGlobalLogicHook();
6168
+ this.globalLogicHooks = logicHookUtils.getGlobalLogicHooks();
6124
6169
  this.userInputs = logicHookUtils.userInputs;
6125
6170
  }
6126
6171
  IsAsserterValid(name) {