botium-core 1.13.17 → 1.13.19

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.
Files changed (38) hide show
  1. package/README.md +0 -1
  2. package/dist/botium-cjs.js +118 -15
  3. package/dist/botium-cjs.js.map +1 -1
  4. package/dist/botium-es.js +118 -15
  5. package/dist/botium-es.js.map +1 -1
  6. package/package.json +2 -1
  7. package/src/BotDriver.js +2 -2
  8. package/src/Capabilities.js +6 -0
  9. package/src/containers/BaseContainer.js +7 -4
  10. package/src/containers/plugins/SimpleRestContainer.js +49 -0
  11. package/src/scripting/Convo.js +21 -0
  12. package/src/scripting/ScriptingProvider.js +19 -2
  13. package/src/scripting/logichook/LogicHookConsts.js +5 -1
  14. package/src/scripting/logichook/asserter/ButtonsAsserter.js +21 -8
  15. package/src/scripting/logichook/logichooks/ClearQueueLogicHook.js +0 -1
  16. package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +56 -0
  17. package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +37 -0
  18. package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +31 -0
  19. package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +46 -0
  20. package/test/connectors/logicHook.js +0 -1
  21. package/test/connectors/simplerest.spec.js +79 -4
  22. package/test/scripting/asserters/buttonsAsserter.spec.js +84 -50
  23. package/test/scripting/logichooks/CustomConditionalLogicHook.js +21 -0
  24. package/test/scripting/logichooks/conditionalStepBusinessHoursLogicHook.spec.js +130 -0
  25. package/test/scripting/logichooks/conditionalStepCapabilityValueBasedLogicHook.spec.js +35 -0
  26. package/test/scripting/logichooks/conditionalStepJsonPathBasedLogicHook.spec.js +35 -0
  27. package/test/scripting/logichooks/conditionalStepTimeBasedLogicHook.spec.js +91 -0
  28. package/test/scripting/logichooks/convos/conditional_steps.convo.txt +12 -0
  29. package/test/scripting/logichooks/convos/conditional_steps_business_hours.convo.txt +16 -0
  30. package/test/scripting/logichooks/convos/conditional_steps_cap_value_based.convo.txt +12 -0
  31. package/test/scripting/logichooks/convos/conditional_steps_followed_by_bot_msg.convo.txt +15 -0
  32. package/test/scripting/logichooks/convos/conditional_steps_followed_by_me.convo.txt +18 -0
  33. package/test/scripting/logichooks/convos/conditional_steps_json_path_based.convo.txt.convo.txt +12 -0
  34. package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups.convo.txt +20 -0
  35. package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +20 -0
  36. package/test/scripting/logichooks/convos/conditional_steps_time_based.convo.txt +12 -0
  37. package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +105 -0
  38. package/test/scripting/scriptingProvider.spec.js +1 -1
package/dist/botium-es.js CHANGED
@@ -2,7 +2,7 @@ import util from 'util';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import async from 'async';
5
- import rimraf$2 from 'rimraf';
5
+ import rimraf$1 from 'rimraf';
6
6
  import mkdirp from 'mkdirp';
7
7
  import sanitizeFilename from 'sanitize-filename';
8
8
  import moment from 'moment';
@@ -37,7 +37,7 @@ import express from 'express';
37
37
  import bodyParser from 'body-parser';
38
38
 
39
39
  var name = "botium-core";
40
- var version$1 = "1.13.17";
40
+ var version$1 = "1.13.19";
41
41
  var description = "The Selenium for Chatbots";
42
42
  var main = "index.js";
43
43
  var module = "dist/botium-es.js";
@@ -88,6 +88,7 @@ var dependencies = {
88
88
  "mime-types": "^2.1.35",
89
89
  mkdirp: "^3.0.1",
90
90
  moment: "^2.29.4",
91
+ "moment-timezone": "^0.5.43",
91
92
  mustache: "^4.2.0",
92
93
  "promise-retry": "^2.0.1",
93
94
  "promise.allsettled": "^1.0.6",
@@ -242,6 +243,12 @@ var Capabilities = {
242
243
  SIMPLEREST_POLL_INTERVAL: 'SIMPLEREST_POLL_INTERVAL',
243
244
  SIMPLEREST_POLL_TIMEOUT: 'SIMPLEREST_PING_TIMEOUT',
244
245
  SIMPLEREST_POLL_UPDATE_CONTEXT: 'SIMPLEREST_POLL_UPDATE_CONTEXT',
246
+ SIMPLEREST_CONTEXT_IGNORE_JSONPATH: 'SIMPLEREST_CONTEXT_IGNORE_JSONPATH',
247
+ SIMPLEREST_CONTEXT_IGNORE_MATCH: 'SIMPLEREST_CONTEXT_IGNORE_MATCH',
248
+ SIMPLEREST_CONTEXT_SKIP_JSONPATH: 'SIMPLEREST_CONTEXT_SKIP_JSONPATH',
249
+ SIMPLEREST_CONTEXT_SKIP_MATCH: 'SIMPLEREST_CONTEXT_SKIP_MATCH',
250
+ SIMPLEREST_CONTEXT_CONTINUE_JSONPATH: 'SIMPLEREST_CONTEXT_CONTINUE_JSONPATH',
251
+ SIMPLEREST_CONTEXT_CONTINUE_MATCH: 'SIMPLEREST_CONTEXT_CONTINUE_MATCH',
245
252
  SIMPLEREST_BODY_JSONPATH: 'SIMPLEREST_BODY_JSONPATH',
246
253
  SIMPLEREST_RESPONSE_JSONPATH: 'SIMPLEREST_RESPONSE_JSONPATH',
247
254
  SIMPLEREST_RESPONSE_HOOK: 'SIMPLEREST_RESPONSE_HOOK',
@@ -408,6 +415,12 @@ Capabilities.SIMPLEREST_POLL_REQUEST_HOOK;
408
415
  Capabilities.SIMPLEREST_POLL_INTERVAL;
409
416
  Capabilities.SIMPLEREST_POLL_TIMEOUT;
410
417
  Capabilities.SIMPLEREST_POLL_UPDATE_CONTEXT;
418
+ Capabilities.SIMPLEREST_CONTEXT_IGNORE_JSONPATH;
419
+ Capabilities.SIMPLEREST_CONTEXT_IGNORE_MATCH;
420
+ Capabilities.SIMPLEREST_CONTEXT_SKIP_JSONPATH;
421
+ Capabilities.SIMPLEREST_CONTEXT_SKIP_MATCH;
422
+ Capabilities.SIMPLEREST_CONTEXT_CONTINUE_JSONPATH;
423
+ Capabilities.SIMPLEREST_CONTEXT_CONTINUE_MATCH;
411
424
  Capabilities.SIMPLEREST_BODY_JSONPATH;
412
425
  Capabilities.SIMPLEREST_RESPONSE_JSONPATH;
413
426
  Capabilities.SIMPLEREST_RESPONSE_HOOK;
@@ -1148,6 +1161,18 @@ var LogicHookConsts = {
1148
1161
  }, {
1149
1162
  name: LOGIC_HOOK_INCLUDE$1,
1150
1163
  className: 'IncludeLogicHook'
1164
+ }, {
1165
+ name: 'CONDITIONAL_STEP_TIME_BASED',
1166
+ className: 'ConditionalTimeBasedLogicHook'
1167
+ }, {
1168
+ name: 'CONDITIONAL_STEP_BUSINESS_HOURS',
1169
+ className: 'ConditionalBusinessHoursLogicHook'
1170
+ }, {
1171
+ name: 'CONDITIONAL_STEP_CAPABILITY_VALUE_BASED',
1172
+ className: 'ConditionalCapabilityValueBasedLogicHook'
1173
+ }, {
1174
+ name: 'CONDITIONAL_STEP_JSON_PATH_BASED',
1175
+ className: 'ConditionalJsonPathBasedLogicHook.js'
1151
1176
  }],
1152
1177
  DEFAULT_USER_INPUTS: [{
1153
1178
  name: 'BUTTON',
@@ -3022,6 +3047,7 @@ class Convo$6 {
3022
3047
  throw failErr;
3023
3048
  }
3024
3049
  } else if (convoStep.sender === 'bot') {
3050
+ const previousWaitForBotSays = waitForBotSays;
3025
3051
  if (waitForBotSays) {
3026
3052
  botMsg = null;
3027
3053
  } else {
@@ -3077,6 +3103,23 @@ class Convo$6 {
3077
3103
  } catch (failErr) {}
3078
3104
  throw failErr;
3079
3105
  }
3106
+ if (convoStep.conditional) {
3107
+ const nextConvoStep = this.conversation[i + 1];
3108
+ if (!previousWaitForBotSays) {
3109
+ skipTranscriptStep = true;
3110
+ }
3111
+ waitForBotSays = false;
3112
+ if (!nextConvoStep || nextConvoStep.sender !== 'bot' || !nextConvoStep.logicHooks || !nextConvoStep.logicHooks.some(lh => lh.name.toUpperCase().startsWith('CONDITIONAL_STEP'))) {
3113
+ waitForBotSays = true;
3114
+ } else {
3115
+ const conditionalLogicHook = convoStep.logicHooks.find(lh => lh.name.startsWith('CONDITIONAL_STEP'));
3116
+ const nextConditionalLogicHook = nextConvoStep.logicHooks.find(lh => lh.name.startsWith('CONDITIONAL_STEP'));
3117
+ waitForBotSays = conditionalLogicHook.args[1] !== nextConditionalLogicHook.args[1];
3118
+ }
3119
+ if (convoStep.conditional.skip) {
3120
+ continue;
3121
+ }
3122
+ }
3080
3123
  if (!botMsg || !botMsg.messageText && !botMsg.media && !botMsg.buttons && !botMsg.cards && !botMsg.sourceData && !botMsg.nlp) {
3081
3124
  const failErr = new BotiumError$4(`${this.header.name}/${convoStep.stepTag}: bot says nothing`);
3082
3125
  debug$j(failErr);
@@ -6371,10 +6414,16 @@ var ScriptingProvider_1 = class ScriptingProvider {
6371
6414
  convoFilter: null
6372
6415
  }, options);
6373
6416
  const expandedConvos = [];
6417
+ // The globalContext is going to keep the data even if the Object.assign which happening to create the myContext in _expandConvo function
6418
+ const context = {
6419
+ globalContext: {
6420
+ totalConvoCount: 0
6421
+ }
6422
+ };
6374
6423
  debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`);
6375
6424
  this.convos.forEach(convo => {
6376
6425
  convo.expandPartialConvos();
6377
- for (const expanded of this._expandConvo(convo, options, {})) {
6426
+ for (const expanded of this._expandConvo(convo, options, context)) {
6378
6427
  expanded.header.assertionCount = this.GetAssertionCount(expanded);
6379
6428
  if (options.justHeader) {
6380
6429
  const ConvoWithOnlyHeader = {
@@ -6390,6 +6439,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
6390
6439
  }
6391
6440
  });
6392
6441
  this.convos = expandedConvos;
6442
+ this.totalConvoCount = context.globalContext.totalConvoCount;
6393
6443
  if (!options.justHeader) {
6394
6444
  this._sortConvos();
6395
6445
  } else {
@@ -6401,16 +6451,23 @@ var ScriptingProvider_1 = class ScriptingProvider {
6401
6451
  // drop unwanted convos
6402
6452
  convoFilter: null
6403
6453
  }, options);
6454
+ // The globalContext is going to keep the data even if the Object.assign which happening to create the myContext in _expandConvo function
6455
+ const context = {
6456
+ globalContext: {
6457
+ totalConvoCount: 0
6458
+ }
6459
+ };
6404
6460
  debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`);
6405
6461
  // creating a nested generator, calling the other.
6406
6462
  // We hope this.convos does not changes while this iterator is used
6407
6463
  const _convosIterable = function* (options) {
6408
6464
  for (const convo of this.convos) {
6409
6465
  convo.expandPartialConvos();
6410
- yield* this._expandConvo(convo, options, {});
6466
+ yield* this._expandConvo(convo, options, context);
6411
6467
  }
6412
6468
  }.bind(this);
6413
6469
  this.convosIterable = _convosIterable(options);
6470
+ this.totalConvoCount = context.globalContext.totalConvoCount;
6414
6471
  }
6415
6472
 
6416
6473
  /**
@@ -6628,6 +6685,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
6628
6685
  const expanded = Object.assign(lodash.cloneDeep(currentConvo), {
6629
6686
  conversation: lodash.cloneDeep(convoStepsStack)
6630
6687
  });
6688
+ if (!lodash.isNil(lodash.get(context, 'globalContext.totalConvoCount'))) {
6689
+ context.globalContext.totalConvoCount++;
6690
+ }
6631
6691
  if (!options.convoFilter || options.convoFilter(expanded)) {
6632
6692
  yield expanded;
6633
6693
  }
@@ -7146,9 +7206,6 @@ var Queue_1 = class Queue {
7146
7206
  }
7147
7207
  };
7148
7208
 
7149
- const {
7150
- rimraf: rimraf$1
7151
- } = rimraf$2;
7152
7209
  const debug$7 = debug$n('botium-connector-BaseContainer');
7153
7210
  const {
7154
7211
  executeHook: executeHook$1,
@@ -7281,7 +7338,12 @@ var BaseContainer_1 = class BaseContainer {
7281
7338
  }, rimraffed => {
7282
7339
  if (this.caps[Capabilities.CLEANUPTEMPDIR]) {
7283
7340
  debug$7(`Cleanup rimrafing temp dir ${this.tempDirectory}`);
7284
- rimraf$1(this.tempDirectory).catch(err => debug$7(`Cleanup temp dir ${this.tempDirectory} failed: ${util.inspect(err)}`)).finally(() => rimraffed());
7341
+ try {
7342
+ rimraf$1.sync(this.tempDirectory);
7343
+ rimraffed();
7344
+ } catch (err) {
7345
+ rimraffed(new Error(`Cleanup temp directory ${this.tempDirectory} failed: ${util.inspect(err)}`));
7346
+ }
7285
7347
  } else {
7286
7348
  rimraffed();
7287
7349
  }
@@ -7900,6 +7962,43 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
7900
7962
  }
7901
7963
  debug$4(`current session context: ${util.inspect(this.view.context)}`);
7902
7964
  }
7965
+ const _isAnyContextJsonPathMatch = (capName, capNameMatch) => {
7966
+ const jsonPaths = getAllCapValues(capName, this.caps);
7967
+ if (jsonPaths.length > 0) {
7968
+ const jsonPathsMatch = getAllCapValues(capNameMatch, this.caps);
7969
+ for (const [index, jsonPath] of jsonPaths.entries()) {
7970
+ const contextNodes = jsonpath.query(this.view.context, jsonPath);
7971
+ if (lodash.isArray(contextNodes) && contextNodes.length > 0) {
7972
+ if (jsonPathsMatch[index]) {
7973
+ if (contextNodes[0] === jsonPathsMatch[index]) {
7974
+ return {
7975
+ jsonPath,
7976
+ match: contextNodes[0]
7977
+ };
7978
+ }
7979
+ } else {
7980
+ return {
7981
+ jsonPath
7982
+ };
7983
+ }
7984
+ }
7985
+ }
7986
+ }
7987
+ return null;
7988
+ };
7989
+ const ignoreMatch = _isAnyContextJsonPathMatch(Capabilities.SIMPLEREST_CONTEXT_IGNORE_JSONPATH, Capabilities.SIMPLEREST_CONTEXT_IGNORE_MATCH);
7990
+ if (ignoreMatch) {
7991
+ if (ignoreMatch.match) debug$4(`ignoring response for context match: ${ignoreMatch.jsonPath} = ${ignoreMatch.match}`);else debug$4(`ignoring response for context: ${ignoreMatch.jsonPath}`);
7992
+ return;
7993
+ }
7994
+ const skipMatch = _isAnyContextJsonPathMatch(Capabilities.SIMPLEREST_CONTEXT_SKIP_JSONPATH, Capabilities.SIMPLEREST_CONTEXT_SKIP_MATCH);
7995
+ if (skipMatch) {
7996
+ if (skipMatch.match) debug$4(`skipping response for context match: ${skipMatch.jsonPath} = ${skipMatch.match}`);else debug$4(`skipping response for context: ${skipMatch.jsonPath}`);
7997
+ setTimeout(() => this._doRequest({
7998
+ messageText: ''
7999
+ }, true, true), 0);
8000
+ return;
8001
+ }
7903
8002
  const result = [];
7904
8003
  if (isFromUser) {
7905
8004
  const _extractFrom = (root, jsonPaths) => {
@@ -8048,6 +8147,13 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8048
8147
  }
8049
8148
  }
8050
8149
  }
8150
+ const continueMatch = _isAnyContextJsonPathMatch(Capabilities.SIMPLEREST_CONTEXT_CONTINUE_JSONPATH, Capabilities.SIMPLEREST_CONTEXT_CONTINUE_MATCH);
8151
+ if (continueMatch) {
8152
+ if (continueMatch.match) debug$4(`continue with next response for context match: ${continueMatch.jsonPath} = ${continueMatch.match}`);else debug$4(`continue with next response for context: ${continueMatch.jsonPath}`);
8153
+ setTimeout(() => this._doRequest({
8154
+ messageText: ''
8155
+ }, true, true), 0);
8156
+ }
8051
8157
  return result;
8052
8158
  }
8053
8159
  _doRequest(msg, isFromUser, updateContext) {
@@ -8805,21 +8911,18 @@ var PluginConnectorContainer_1 = class PluginConnectorContainer extends BaseCont
8805
8911
  }
8806
8912
  };
8807
8913
 
8808
- var require$$4 = getCjsExportFromNamespace(_package$1);
8914
+ var require$$3 = getCjsExportFromNamespace(_package$1);
8809
8915
 
8810
8916
  const {
8811
8917
  rimraf
8812
- } = rimraf$2;
8813
- const {
8814
- mkdirpSync
8815
- } = mkdirp;
8918
+ } = rimraf$1;
8816
8919
  const {
8817
8920
  boolean
8818
8921
  } = boolean$1;
8819
8922
  const debug$1 = debug$n('botium-core-BotDriver');
8820
8923
  const {
8821
8924
  version
8822
- } = require$$4;
8925
+ } = require$$3;
8823
8926
  var BotDriver_1 = class BotDriver {
8824
8927
  constructor(caps = {}, sources = {}, envs = {}) {
8825
8928
  this.eventEmitter = new events();
@@ -8909,7 +9012,7 @@ var BotDriver_1 = class BotDriver {
8909
9012
  }, tempDirectoryCreated => {
8910
9013
  tempDirectory = path.resolve(process.cwd(), this.caps[Capabilities.TEMPDIR], sanitizeFilename(`${this.caps[Capabilities.PROJECTNAME]} ${moment().format('YYYYMMDD HHmmss')} ${randomatic('Aa0', 5)}`));
8911
9014
  try {
8912
- mkdirpSync(tempDirectory);
9015
+ mkdirp.sync(tempDirectory);
8913
9016
  tempDirectoryCreated();
8914
9017
  } catch (err) {
8915
9018
  tempDirectoryCreated(new Error(`Unable to create temp directory ${tempDirectory}: ${err.message}`));