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 +0 -4
- package/dist/botium-cjs.js +65 -20
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +65 -20
- package/dist/botium-es.js.map +1 -1
- package/package.json +2 -1
- package/src/scripting/Convo.js +39 -3
- package/src/scripting/ScriptingProvider.js +18 -11
- package/src/scripting/logichook/LogicHookUtils.js +8 -10
- package/src/scripting/logichook/userinput/MediaInput.js +2 -2
- package/test/convo/transcript.spec.js +93 -1
- package/test/scripting/logichooks/localvsglobal.spec.js +105 -0
package/dist/botium-es.js
CHANGED
|
@@ -35,7 +35,7 @@ import express from 'express';
|
|
|
35
35
|
import bodyParser from 'body-parser';
|
|
36
36
|
|
|
37
37
|
var name = "botium-core";
|
|
38
|
-
var version$1 = "1.14.
|
|
38
|
+
var version$1 = "1.14.10";
|
|
39
39
|
var description = "The Selenium for Chatbots";
|
|
40
40
|
var main = "index.js";
|
|
41
41
|
var module = "dist/botium-es.js";
|
|
@@ -98,6 +98,7 @@ var dependencies = {
|
|
|
98
98
|
"socketio-auth": "^0.1.1",
|
|
99
99
|
"swagger-jsdoc": "^6.2.8",
|
|
100
100
|
"swagger-ui-express": "^5.0.0",
|
|
101
|
+
tinyglobby: "^0.2.10",
|
|
101
102
|
uuid: "^9.0.1",
|
|
102
103
|
"word-error-rate": "0.0.7",
|
|
103
104
|
"write-yaml": "^1.0.0",
|
|
@@ -1082,9 +1083,9 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1082
1083
|
caps
|
|
1083
1084
|
}) {
|
|
1084
1085
|
this.asserters = {};
|
|
1085
|
-
this.
|
|
1086
|
+
this.globalAsserterNames = [];
|
|
1086
1087
|
this.logicHooks = {};
|
|
1087
|
-
this.
|
|
1088
|
+
this.globalLogicHookNames = [];
|
|
1088
1089
|
this.userInputs = {};
|
|
1089
1090
|
this.buildScriptContext = buildScriptContext;
|
|
1090
1091
|
this.caps = caps;
|
|
@@ -1117,7 +1118,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1117
1118
|
}
|
|
1118
1119
|
this.asserters[asserter.ref] = this._loadClass(asserter, 'asserter');
|
|
1119
1120
|
if (asserter.global) {
|
|
1120
|
-
this.
|
|
1121
|
+
this.globalAsserterNames.push(asserter.ref);
|
|
1121
1122
|
}
|
|
1122
1123
|
});
|
|
1123
1124
|
}
|
|
@@ -1128,7 +1129,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1128
1129
|
}
|
|
1129
1130
|
this.logicHooks[logicHook.ref] = this._loadClass(logicHook, 'logichook');
|
|
1130
1131
|
if (logicHook.global) {
|
|
1131
|
-
this.
|
|
1132
|
+
this.globalLogicHookNames.push(logicHook.ref);
|
|
1132
1133
|
}
|
|
1133
1134
|
});
|
|
1134
1135
|
}
|
|
@@ -1140,11 +1141,17 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1140
1141
|
this.userInputs[userInput.ref] = this._loadClass(userInput, 'userinput');
|
|
1141
1142
|
});
|
|
1142
1143
|
}
|
|
1143
|
-
|
|
1144
|
-
return this.
|
|
1144
|
+
getGlobalAsserters() {
|
|
1145
|
+
return this.globalAsserterNames.reduce((agg, name) => ({
|
|
1146
|
+
...agg,
|
|
1147
|
+
[name]: this.asserters[name]
|
|
1148
|
+
}), {});
|
|
1145
1149
|
}
|
|
1146
|
-
|
|
1147
|
-
return this.
|
|
1150
|
+
getGlobalLogicHooks() {
|
|
1151
|
+
return this.globalLogicHookNames.reduce((agg, name) => ({
|
|
1152
|
+
...agg,
|
|
1153
|
+
[name]: this.logicHooks[name]
|
|
1154
|
+
}), {});
|
|
1148
1155
|
}
|
|
1149
1156
|
_loadClass({
|
|
1150
1157
|
src,
|
|
@@ -2934,6 +2941,10 @@ class Convo$6 {
|
|
|
2934
2941
|
let skipTranscriptStep = false;
|
|
2935
2942
|
let conditionalGroupId = null;
|
|
2936
2943
|
let conditionMetInGroup = false;
|
|
2944
|
+
let skipOptionalStep = false;
|
|
2945
|
+
// 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.
|
|
2946
|
+
// So in this case an unexpected error should be shown instead of the latest assertion error.
|
|
2947
|
+
let optionalStepAssertionError = false;
|
|
2937
2948
|
let globalConvoStepParameters = container.caps[Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS] || {};
|
|
2938
2949
|
let retryBotMessageTimeoutEnd = null;
|
|
2939
2950
|
let retryBotMessageConvoId = null;
|
|
@@ -2941,6 +2952,13 @@ class Convo$6 {
|
|
|
2941
2952
|
for (let i = 0; i < this.conversation.length; i = retryBotMessageDropBotResponse ? i : i + 1) {
|
|
2942
2953
|
retryBotMessageDropBotResponse = false;
|
|
2943
2954
|
const convoStep = this.conversation[i];
|
|
2955
|
+
if (!convoStep.optional) {
|
|
2956
|
+
skipOptionalStep = false;
|
|
2957
|
+
}
|
|
2958
|
+
if (convoStep.optional && skipOptionalStep) {
|
|
2959
|
+
// 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.
|
|
2960
|
+
continue;
|
|
2961
|
+
}
|
|
2944
2962
|
const rawConvoStepParameters = convoStep.logicHooks.find(lh => lh.name === 'CONVO_STEP_PARAMETERS')?.args;
|
|
2945
2963
|
let convoStepParameters = {};
|
|
2946
2964
|
if (rawConvoStepParameters && rawConvoStepParameters.length) {
|
|
@@ -3125,7 +3143,8 @@ class Convo$6 {
|
|
|
3125
3143
|
debug$k(`${this.header.name}: bot says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
|
|
3126
3144
|
} catch (err) {
|
|
3127
3145
|
transcriptStep.botEnd = new Date();
|
|
3128
|
-
if (convoStep.optional) {
|
|
3146
|
+
if (!(err.message.indexOf('Bot did not respond within') < 0) && convoStep.optional) {
|
|
3147
|
+
skipOptionalStep = true;
|
|
3129
3148
|
continue;
|
|
3130
3149
|
}
|
|
3131
3150
|
const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: error waiting for bot - ${err.message}`, err);
|
|
@@ -3209,6 +3228,7 @@ class Convo$6 {
|
|
|
3209
3228
|
}
|
|
3210
3229
|
waitForBotSays = false;
|
|
3211
3230
|
skipTranscriptStep = true;
|
|
3231
|
+
optionalStepAssertionError = true;
|
|
3212
3232
|
return true;
|
|
3213
3233
|
} else if (retryOn) {
|
|
3214
3234
|
if (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag) {
|
|
@@ -3226,9 +3246,18 @@ class Convo$6 {
|
|
|
3226
3246
|
}
|
|
3227
3247
|
}
|
|
3228
3248
|
if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
|
|
3229
|
-
|
|
3249
|
+
if (optionalStepAssertionError) {
|
|
3250
|
+
optionalStepAssertionError = false;
|
|
3251
|
+
assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
|
|
3252
|
+
} else {
|
|
3253
|
+
assertErrors.push(err);
|
|
3254
|
+
}
|
|
3230
3255
|
return false;
|
|
3231
3256
|
} else {
|
|
3257
|
+
if (optionalStepAssertionError) {
|
|
3258
|
+
optionalStepAssertionError = false;
|
|
3259
|
+
throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
|
|
3260
|
+
}
|
|
3232
3261
|
throw err;
|
|
3233
3262
|
}
|
|
3234
3263
|
};
|
|
@@ -3242,6 +3271,7 @@ class Convo$6 {
|
|
|
3242
3271
|
if (convoStep.not) {
|
|
3243
3272
|
try {
|
|
3244
3273
|
this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
|
|
3274
|
+
optionalStepAssertionError = false;
|
|
3245
3275
|
} catch (err) {
|
|
3246
3276
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3247
3277
|
continue;
|
|
@@ -3250,6 +3280,7 @@ class Convo$6 {
|
|
|
3250
3280
|
} else {
|
|
3251
3281
|
try {
|
|
3252
3282
|
this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
|
|
3283
|
+
optionalStepAssertionError = false;
|
|
3253
3284
|
} catch (err) {
|
|
3254
3285
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3255
3286
|
continue;
|
|
@@ -3259,6 +3290,7 @@ class Convo$6 {
|
|
|
3259
3290
|
} else if (convoStep.sourceData) {
|
|
3260
3291
|
try {
|
|
3261
3292
|
this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg, convoStepParameters);
|
|
3293
|
+
optionalStepAssertionError = false;
|
|
3262
3294
|
} catch (err) {
|
|
3263
3295
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3264
3296
|
continue;
|
|
@@ -3285,11 +3317,13 @@ class Convo$6 {
|
|
|
3285
3317
|
transcript,
|
|
3286
3318
|
transcriptStep
|
|
3287
3319
|
});
|
|
3320
|
+
optionalStepAssertionError = false;
|
|
3288
3321
|
} catch (err) {
|
|
3289
3322
|
const nextConvoStep = this.conversation[i + 1];
|
|
3290
3323
|
if (convoStep.optional && nextConvoStep && nextConvoStep.sender === 'bot') {
|
|
3291
3324
|
waitForBotSays = false;
|
|
3292
3325
|
skipTranscriptStep = true;
|
|
3326
|
+
optionalStepAssertionError = true;
|
|
3293
3327
|
continue;
|
|
3294
3328
|
}
|
|
3295
3329
|
const errors = err.toArray ? err.toArray() : [];
|
|
@@ -3318,8 +3352,17 @@ class Convo$6 {
|
|
|
3318
3352
|
this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
|
|
3319
3353
|
} catch (failErr) {}
|
|
3320
3354
|
if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
|
|
3321
|
-
|
|
3355
|
+
if (optionalStepAssertionError) {
|
|
3356
|
+
optionalStepAssertionError = false;
|
|
3357
|
+
assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
|
|
3358
|
+
} else {
|
|
3359
|
+
assertErrors.push(err);
|
|
3360
|
+
}
|
|
3322
3361
|
} else {
|
|
3362
|
+
if (optionalStepAssertionError) {
|
|
3363
|
+
optionalStepAssertionError = false;
|
|
3364
|
+
throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
|
|
3365
|
+
}
|
|
3323
3366
|
throw failErr;
|
|
3324
3367
|
}
|
|
3325
3368
|
}
|
|
@@ -5520,9 +5563,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5520
5563
|
this.utterances = {};
|
|
5521
5564
|
this.matchFn = null;
|
|
5522
5565
|
this.asserters = {};
|
|
5523
|
-
this.
|
|
5566
|
+
this.globalAsserters = {};
|
|
5524
5567
|
this.logicHooks = {};
|
|
5525
|
-
this.
|
|
5568
|
+
this.globalLogicHooks = {};
|
|
5526
5569
|
this.userInputs = {};
|
|
5527
5570
|
this.partialConvos = {};
|
|
5528
5571
|
this.scriptingMemories = [];
|
|
@@ -5891,7 +5934,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5891
5934
|
return p(this.retryHelperAsserter, () => asserter[asserterType](params));
|
|
5892
5935
|
}
|
|
5893
5936
|
};
|
|
5894
|
-
const
|
|
5937
|
+
const localAsserters = (asserters || []).filter(a => this.asserters[a.name][asserterType]);
|
|
5938
|
+
const convoStepPromises = localAsserters.map(a => ({
|
|
5895
5939
|
asserter: a,
|
|
5896
5940
|
promise: callAsserter(a, this.asserters[a.name], {
|
|
5897
5941
|
convo,
|
|
@@ -5906,7 +5950,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5906
5950
|
promise,
|
|
5907
5951
|
asserter
|
|
5908
5952
|
}) => updateExceptionContext(promise, asserter));
|
|
5909
|
-
const
|
|
5953
|
+
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]);
|
|
5954
|
+
const globalPromises = globalAsserters.map(a => ({
|
|
5910
5955
|
asserter: a,
|
|
5911
5956
|
promise: p(this.retryHelperAsserter, () => a[asserterType]({
|
|
5912
5957
|
convo,
|
|
@@ -5921,7 +5966,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5921
5966
|
promise,
|
|
5922
5967
|
asserter
|
|
5923
5968
|
}) => updateExceptionContext(promise, asserter));
|
|
5924
|
-
const allPromises = [...
|
|
5969
|
+
const allPromises = [...convoStepPromises, ...globalPromises];
|
|
5925
5970
|
if (this.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
|
|
5926
5971
|
return Promise.allSettled(allPromises).then(results => {
|
|
5927
5972
|
const rejected = results.filter(result => result.status === 'rejected').map(result => result.reason);
|
|
@@ -5956,7 +6001,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5956
6001
|
isGlobal: false,
|
|
5957
6002
|
...rest
|
|
5958
6003
|
})));
|
|
5959
|
-
const globalHooks = Object.
|
|
6004
|
+
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]);
|
|
5960
6005
|
const globalPromises = globalHooks.map(l => p(this.retryHelperLogicHook, () => l[hookType]({
|
|
5961
6006
|
convo,
|
|
5962
6007
|
convoStep,
|
|
@@ -6076,9 +6121,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
6076
6121
|
caps: this.caps
|
|
6077
6122
|
});
|
|
6078
6123
|
this.asserters = logicHookUtils.asserters;
|
|
6079
|
-
this.
|
|
6124
|
+
this.globalAsserters = logicHookUtils.getGlobalAsserters();
|
|
6080
6125
|
this.logicHooks = logicHookUtils.logicHooks;
|
|
6081
|
-
this.
|
|
6126
|
+
this.globalLogicHooks = logicHookUtils.getGlobalLogicHooks();
|
|
6082
6127
|
this.userInputs = logicHookUtils.userInputs;
|
|
6083
6128
|
}
|
|
6084
6129
|
IsAsserterValid(name) {
|