botium-core 1.14.0 → 1.14.3

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/dist/botium-cjs.js +302 -94
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +302 -94
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +19 -19
  6. package/src/Capabilities.js +2 -0
  7. package/src/scripting/BotiumError.js +40 -3
  8. package/src/scripting/Convo.js +139 -28
  9. package/src/scripting/ScriptingMemory.js +7 -0
  10. package/src/scripting/ScriptingProvider.js +79 -30
  11. package/src/scripting/logichook/LogicHookConsts.js +5 -2
  12. package/src/scripting/logichook/LogicHookUtils.js +8 -6
  13. package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +1 -1
  14. package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +1 -1
  15. package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +1 -1
  16. package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +1 -1
  17. package/src/scripting/logichook/logichooks/ConvoStepParametersLogicHook.js +6 -0
  18. package/src/scripting/logichook/logichooks/OrderedListToButtonLogicHook.js +37 -0
  19. package/test/convo/fillAndApplyScriptingMemory.spec.js +11 -0
  20. package/test/logichooks/orderedListToButton.spec.js +35 -0
  21. package/test/scripting/asserters/convoStepParameters.spec.js +140 -0
  22. package/test/scripting/asserters/convos/TEXT_GOOD.convo.txt +6 -0
  23. package/test/scripting/asserters/convos/convo_step_parameter_matchmode_failed.convo.txt +8 -0
  24. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_all_good.convo.txt +9 -0
  25. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_botium_timeout.convo.txt +9 -0
  26. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good.convo.txt +9 -0
  27. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good_global.convo.txt +9 -0
  28. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_and_asserter.convo.txt +10 -0
  29. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_botium_timeout.convo.txt +9 -0
  30. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_but_no_button.convo.txt +10 -0
  31. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good.convo.txt +9 -0
  32. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good_begin.convo.txt +11 -0
  33. package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +6 -6
  34. package/test/scripting/logichooks/convos/conditional_steps_multiple_mandatory_condition_groups.convo.txt +20 -0
  35. package/test/scripting/logichooks/convos/conditional_steps_multiple_optional_condition_groups.convo.txt +20 -0
  36. package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +16 -0
  37. package/test/scripting/matching/matchingmode.spec.js +4 -1
  38. package/test/scripting/scriptingProvider.spec.js +38 -12
@@ -61,11 +61,14 @@ module.exports = {
61
61
  { name: 'CONDITIONAL_STEP_TIME_BASED', className: 'ConditionalTimeBasedLogicHook' },
62
62
  { name: 'CONDITIONAL_STEP_BUSINESS_HOURS', className: 'ConditionalBusinessHoursLogicHook' },
63
63
  { name: 'CONDITIONAL_STEP_CAPABILITY_VALUE_BASED', className: 'ConditionalCapabilityValueBasedLogicHook' },
64
- { name: 'CONDITIONAL_STEP_JSON_PATH_BASED', className: 'ConditionalJsonPathBasedLogicHook.js' }
64
+ { name: 'CONDITIONAL_STEP_JSON_PATH_BASED', className: 'ConditionalJsonPathBasedLogicHook.js' },
65
+ { name: 'CONVO_STEP_PARAMETERS', className: 'ConvoStepParametersLogicHook.js' },
66
+ { name: 'ORDERED_LIST_TO_BUTTON', className: 'OrderedListToButtonLogicHook' }
65
67
  ],
66
68
  DEFAULT_USER_INPUTS: [
67
69
  { name: 'BUTTON', className: 'ButtonInput' },
68
70
  { name: 'MEDIA', className: 'MediaInput' },
69
71
  { name: 'FORM', className: 'FormInput' }
70
- ]
72
+ ],
73
+ LOGIC_HOOK_EVENTS: ['onConvoBegin', 'onMeStart', 'onMePrepare', 'onMeEnd', 'onBotStart', 'onBotEnd', 'onBotPrepare', 'onConvoEnd']
71
74
  }
@@ -147,19 +147,21 @@ module.exports = class LogicHookUtils {
147
147
  }
148
148
  }
149
149
 
150
+ const typeAsText = hookType === 'asserter' ? 'Asserter' : hookType === 'logichook' ? 'Logic Hook' : hookType === 'userinput' ? 'User Input' : 'Unknown'
151
+
150
152
  if (isClass(src)) {
151
153
  try {
152
154
  const CheckClass = src
153
155
  return new CheckClass({ ref, ...this.buildScriptContext }, this.caps, args)
154
156
  } catch (err) {
155
- throw new Error(`Logic Hook specification ${ref} from class invalid: ${err.message}`)
157
+ throw new Error(`${typeAsText} specification ${ref} from class invalid: ${err.message}`)
156
158
  }
157
159
  }
158
160
  if (_.isFunction(src)) {
159
161
  try {
160
162
  return src({ ref, ...this.buildScriptContext }, this.caps, args)
161
163
  } catch (err) {
162
- throw new Error(`Logic Hook specification ${ref} from function invalid: ${err.message}`)
164
+ throw new Error(`${typeAsText} specification ${ref} from function invalid: ${err.message}`)
163
165
  }
164
166
  }
165
167
  if (_.isObject(src) && !_.isString(src)) {
@@ -177,7 +179,7 @@ module.exports = class LogicHookUtils {
177
179
  }, {})
178
180
  return hookObject
179
181
  } catch (err) {
180
- throw new Error(`Logic Hook specification ${ref} ${hookType} from provided src (${util.inspect(src)}) invalid: ${err.message}`)
182
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from provided src (${util.inspect(src)}) invalid: ${err.message}`)
181
183
  }
182
184
  }
183
185
 
@@ -230,7 +232,7 @@ module.exports = class LogicHookUtils {
230
232
  try {
231
233
  return tryLoadFromSource(tryLoadFile, tryLoad.tryLoadAsserterByName)
232
234
  } catch (err) {
233
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
235
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
234
236
  }
235
237
  }
236
238
  }
@@ -239,13 +241,13 @@ module.exports = class LogicHookUtils {
239
241
  try {
240
242
  return tryLoadFromSource(tryLoad.tryLoadPackageName, tryLoad.tryLoadAsserterByName)
241
243
  } catch (err) {
242
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
244
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
243
245
  }
244
246
  }
245
247
  }
246
248
 
247
249
  loadErr.forEach(debug)
248
250
  }
249
- throw new Error(`Logic Hook specification ${ref} ${hookType} from "${util.inspect(src)}" invalid : no loader available`)
251
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from "${util.inspect(src)}" invalid : no loader available`)
250
252
  }
251
253
  }
@@ -51,6 +51,6 @@ module.exports = class ConditionalBusinessHoursLogicHook {
51
51
  }
52
52
  params.now = moment()
53
53
  convoStep.conditional.skip = !this._isBetween(params)
54
- debug(`ConditionalBusinessHoursLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
54
+ debug(`ConditionalBusinessHoursLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${util.inspect(convoStep.conditional)}`)
55
55
  }
56
56
  }
@@ -32,6 +32,6 @@ module.exports = class ConditionalCapabilityValueBasedLogicHook {
32
32
  conditionGroupId
33
33
  }
34
34
  convoStep.conditional.skip = !this._isCapabilityValueEqual(params)
35
- debug(`ConditionalCapabilityValueBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
35
+ debug(`ConditionalCapabilityValueBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${util.inspect(convoStep.conditional)}`)
36
36
  }
37
37
  }
@@ -26,6 +26,6 @@ module.exports = class ConditionalJsonPathBasedLogicHook {
26
26
  skip = !(values && values.length > 0 && values.includes(params.value))
27
27
  }
28
28
  convoStep.conditional.skip = skip
29
- debug(`ConditionalJsonPathBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
29
+ debug(`ConditionalJsonPathBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${util.inspect(convoStep.conditional)}`)
30
30
  }
31
31
  }
@@ -41,6 +41,6 @@ module.exports = class ConditionalTimeBasedLogicHook {
41
41
  }
42
42
  params.now = moment()
43
43
  convoStep.conditional.skip = !this._isBetween(params)
44
- debug(`ConditionalTimeBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
44
+ debug(`ConditionalTimeBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${util.inspect(convoStep.conditional)}`)
45
45
  }
46
46
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This LogicHook is just a marker. It is used Convo Step parameters
3
+ * @type {module.ConvoStepParametersLogicHook}
4
+ */
5
+ module.exports = class ConvoStepParametersLogicHook {
6
+ }
@@ -0,0 +1,37 @@
1
+ const _ = require('lodash')
2
+ const PATTERN = '^\\s*(\\d+)\\.'
3
+ const debug = require('debug')('botium-core-OrderedListToButtonLogicHook')
4
+
5
+ module.exports = class OrderedListToButtonLogicHook {
6
+ constructor (context, caps = {}, globalArgs = {}) {
7
+ this.context = context
8
+ this.caps = caps
9
+ this.globalArgs = globalArgs
10
+ }
11
+
12
+ onBotPrepare ({ botMsg, args }) {
13
+ const pattern = args?.[0] || this.globalArgs?.pattern || PATTERN
14
+ let regexp
15
+ try {
16
+ regexp = new RegExp(pattern, 'gm')
17
+ } catch (err) {
18
+ throw new Error(`OrderedListToButtonLogicHook: regex is not valid: ${pattern} ${err.messageText}`)
19
+ }
20
+ const buttons = []
21
+ if (botMsg.messageText && _.isString(botMsg.messageText)) {
22
+ const matches = botMsg.messageText.matchAll(regexp)
23
+
24
+ for (const match of matches) {
25
+ if (match && match[1]) {
26
+ buttons.push({ text: match[1], payload: match[1] })
27
+ }
28
+ }
29
+ } else {
30
+ debug(`ConditionalBusinessHoursLogicHook onBotPrepare, msg has no messageText to check ${JSON.stringify(botMsg)}`)
31
+ }
32
+
33
+ if (buttons.length) {
34
+ botMsg.buttons = [...(botMsg.buttons || []), ...buttons]
35
+ }
36
+ }
37
+ }
@@ -817,6 +817,17 @@ describe('convo.fillAndApplyScriptingMemory', function () {
817
817
 
818
818
  assert.equal(result, moment().subtract(1, 'month').format('YYYY.MM.DD'))
819
819
  })
820
+ it('date_add_dynamic', async function () {
821
+ const result = ScriptingMemory.apply(
822
+ { caps: CAPS_ENABLE_SCRIPTING_MEMORY },
823
+ {
824
+ days: 2
825
+ },
826
+ '$date_add($days, "day", YYYY.MM.DD)'
827
+ )
828
+
829
+ assert.equal(result, moment().add(2, 'day').format('YYYY.MM.DD'))
830
+ })
820
831
 
821
832
  it('random', async function () {
822
833
  const result = ScriptingMemory.apply(
@@ -0,0 +1,35 @@
1
+ const assert = require('chai').assert
2
+
3
+ const OrderedListToButtonLogicHook = require('../../src/scripting/logichook/logichooks/OrderedListToButtonLogicHook')
4
+
5
+ describe('logichooks.orderedListToButton', function () {
6
+ it('should convert ordered list to buttons', async function () {
7
+ const orderedListToButtonLogicHook = new OrderedListToButtonLogicHook()
8
+ const botMsg = {
9
+ messageText: `0. sometext.
10
+ 1.
11
+ 2.
12
+ 3.sdfdsf
13
+ 4. 3 days per week
14
+ 5.2.2
15
+ 6. 2.dfsdf
16
+ 7777.
17
+ 88euro
18
+ `,
19
+
20
+ buttons: [{ payload: 'existingButtonPayload', text: 'existingButtonText' }]
21
+ }
22
+
23
+ orderedListToButtonLogicHook.onBotPrepare({ botMsg })
24
+ assert.equal(botMsg.buttons?.length, 9)
25
+ assert.deepEqual(botMsg.buttons[0], { payload: 'existingButtonPayload', text: 'existingButtonText' })
26
+ assert.deepEqual(botMsg.buttons[1], { payload: '0', text: '0' })
27
+ assert.deepEqual(botMsg.buttons[2], { payload: '1', text: '1' })
28
+ assert.deepEqual(botMsg.buttons[3], { payload: '2', text: '2' })
29
+ assert.deepEqual(botMsg.buttons[4], { payload: '3', text: '3' })
30
+ assert.deepEqual(botMsg.buttons[5], { payload: '4', text: '4' })
31
+ assert.deepEqual(botMsg.buttons[6], { payload: '5', text: '5' })
32
+ assert.deepEqual(botMsg.buttons[7], { payload: '6', text: '6' })
33
+ assert.deepEqual(botMsg.buttons[8], { payload: '7777', text: '7777' })
34
+ })
35
+ })
@@ -0,0 +1,140 @@
1
+ const path = require('path')
2
+ const assert = require('chai').assert
3
+ const BotDriver = require('../../../index').BotDriver
4
+ const Capabilities = require('../../../index').Capabilities
5
+ const debug = require('debug')('botium-test-logichooks-waitforbot')
6
+ const util = require('util')
7
+
8
+ const createEchoConnector = () => ({ queueBotSays, caps }) => {
9
+ return {
10
+ UserSays (msg) {
11
+ const _send = (msg, timeout) => {
12
+ const botMsg = { sender: 'bot', sourceData: msg.sourceData, messageText: `You said ${msg}` }
13
+ if (msg.toLowerCase().indexOf('button') >= 0) {
14
+ botMsg.buttons = [{ text: 'button1' }, { text: 'button2' }]
15
+ }
16
+ if (msg.toLowerCase().indexOf('intent') >= 0) {
17
+ botMsg.nlp = { intent: { name: 'someIntent', confidence: 0.5 } }
18
+ }
19
+ setTimeout(() => {
20
+ debug(`${prefix} Connector is sending message ${util.inspect(botMsg)}`)
21
+ return queueBotSays(botMsg)
22
+ }, timeout)
23
+ }
24
+
25
+ const prefix = `Testcase "${caps[Capabilities.PROJECTNAME]}"`
26
+ debug(`${prefix} Connector got message ${util.inspect(msg)}`)
27
+ if (msg.messageText) {
28
+ msg.messageText.split('\n').forEach((msgPart, i) => {
29
+ if (msgPart) {
30
+ _send(msgPart, i * 50)
31
+ }
32
+ })
33
+ }
34
+ }
35
+ }
36
+ }
37
+ describe('scripting.asserters.convoStepParametersForAssert', function () {
38
+ beforeEach(async function () {
39
+ const myCaps = {
40
+ [Capabilities.PROJECTNAME]: 'asserters.text',
41
+ [Capabilities.CONTAINERMODE]: createEchoConnector(),
42
+ [Capabilities.WAITFORBOTTIMEOUT]: 1000,
43
+ [Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]: true,
44
+ [Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS]: '{"ignoreNotMatchedBotResponses": {"timeout": 200, "asserters": ["INTENT"]}}'
45
+ }
46
+ const driver = new BotDriver(myCaps)
47
+ this.compiler = driver.BuildCompiler()
48
+ this.container = await driver.Build()
49
+ })
50
+ afterEach(async function () {
51
+ await this.container.Stop()
52
+ await this.container.Clean()
53
+ })
54
+
55
+ describe('scripting.asserters.convoStepParametersForAssert.matchmode', function () {
56
+ it('should not accept bad chatbot response on exact match defined on step', async function () {
57
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_matchmode_failed.convo.txt')
58
+ assert.equal(this.compiler.convos.length, 1)
59
+
60
+ try {
61
+ await this.compiler.convos[0].Run(this.container)
62
+ assert.fail('should have failed')
63
+ } catch (err) {
64
+ assert.isTrue(err.message.indexOf('"You said Hello" expected to match "Hello"') >= 0)
65
+ }
66
+ })
67
+ })
68
+
69
+ describe('scripting.asserters.convoStepParametersForAssert.retry', function () {
70
+ it('should retry until succesful main', async function () {
71
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_main_good.convo.txt')
72
+ assert.equal(this.compiler.convos.length, 1)
73
+
74
+ await this.compiler.convos[0].Run(this.container)
75
+ })
76
+ it('should retry until succesful asserters', async function () {
77
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_asserters_good.convo.txt')
78
+ assert.equal(this.compiler.convos.length, 1)
79
+
80
+ await this.compiler.convos[0].Run(this.container)
81
+ })
82
+ it('should retry until succesful asserters all', async function () {
83
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_asserters_all_good.convo.txt')
84
+ assert.equal(this.compiler.convos.length, 1)
85
+
86
+ await this.compiler.convos[0].Run(this.container)
87
+ })
88
+ it('should retry until succesful main, configured in begin', async function () {
89
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_main_good_begin.convo.txt')
90
+ assert.equal(this.compiler.convos.length, 1)
91
+
92
+ await this.compiler.convos[0].Run(this.container)
93
+ })
94
+ it('should retry until succesful asserters, configured by cap', async function () {
95
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_asserters_good_global.convo.txt')
96
+ assert.equal(this.compiler.convos.length, 1)
97
+
98
+ await this.compiler.convos[0].Run(this.container)
99
+ })
100
+ it('should retry until timeout main', async function () {
101
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_main_botium_timeout.convo.txt')
102
+ assert.equal(this.compiler.convos.length, 1)
103
+
104
+ try {
105
+ await this.compiler.convos[0].Run(this.container)
106
+ assert.fail('should have failed')
107
+ } catch (err) {
108
+ assert.isTrue(err.message.indexOf('error waiting for bot - Bot did not respond within 1s') >= 0)
109
+ }
110
+ })
111
+ it('should retry until timeout asserter', async function () {
112
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_asserters_botium_timeout.convo.txt')
113
+ assert.equal(this.compiler.convos.length, 1)
114
+
115
+ try {
116
+ await this.compiler.convos[0].Run(this.container)
117
+ assert.fail('should have failed')
118
+ } catch (err) {
119
+ assert.isTrue(err.message.indexOf('error waiting for bot - Bot did not respond within 1s') >= 0)
120
+ }
121
+ })
122
+ it('should not retry on not retriable error', async function () {
123
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_main_but_no_button.convo.txt')
124
+ assert.equal(this.compiler.convos.length, 1)
125
+
126
+ try {
127
+ await this.compiler.convos[0].Run(this.container)
128
+ assert.fail('should have failed')
129
+ } catch (err) {
130
+ assert.isTrue(err.message.indexOf('Expected button(s) with text "some not existing button"') >= 0)
131
+ }
132
+ })
133
+ it('should retry until every retriable is succesful', async function () {
134
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convo_step_parameter_retry_main_and_asserter.convo.txt')
135
+ assert.equal(this.compiler.convos.length, 1)
136
+
137
+ await this.compiler.convos[0].Run(this.container)
138
+ })
139
+ })
140
+ })
@@ -0,0 +1,6 @@
1
+ TEXT_GOOD
2
+ #me
3
+ Hello1
4
+
5
+ #bot
6
+ TEXT You said Hello1
@@ -0,0 +1,8 @@
1
+ convo_step_parameter_matchmode_failed
2
+
3
+ #me
4
+ Hello
5
+
6
+ #bot
7
+ Hello
8
+ CONVO_STEP_PARAMETERS {"matchingMode":"equals"}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_asserters_good
2
+
3
+ #me
4
+ Hello
5
+ Button
6
+
7
+ #bot
8
+ BUTTONS button1|button2
9
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "allAsserters": true}}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_asserters_good
2
+
3
+ #me
4
+ Hello
5
+ Button
6
+
7
+ #bot
8
+ BUTTONS button1|buttonXXXXXX
9
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "asserters": ["BUTTONS"]}}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_asserters_good
2
+
3
+ #me
4
+ Hello
5
+ Button
6
+
7
+ #bot
8
+ BUTTONS button1|button2
9
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "asserters": ["BUTTONS"]}}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_asserters_good_global
2
+
3
+
4
+ #me
5
+ Hello1
6
+ Intent
7
+
8
+ #bot
9
+ INTENT someIntent
@@ -0,0 +1,10 @@
1
+ convo_step_parameter_retry_main_and_asserter
2
+
3
+ #me
4
+ Butt
5
+ Button
6
+
7
+ #bot
8
+ You said Butt
9
+ BUTTONS button1|button2
10
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "mainAsserter": true, "allAsserters": true}}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_main_botium_timeout
2
+
3
+ #me
4
+ Hello1
5
+ Hello2
6
+
7
+ #bot
8
+ You said Hello3
9
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "mainAsserter": true}}
@@ -0,0 +1,10 @@
1
+ convo_step_parameter_retry_main_but_no_button
2
+
3
+ #me
4
+ Hello1
5
+ Hello2
6
+
7
+ #bot
8
+ You said Hello2
9
+ BUTTONS some not existing button
10
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "mainAsserter": true}}
@@ -0,0 +1,9 @@
1
+ convo_step_parameter_retry_main_good
2
+
3
+ #me
4
+ Hello1
5
+ Hello2
6
+
7
+ #bot
8
+ You said Hello2
9
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 201, "mainAsserter": true}}
@@ -0,0 +1,11 @@
1
+ convo_step_parameter_retry_main_good_begin
2
+
3
+ #begin
4
+ CONVO_STEP_PARAMETERS {"ignoreNotMatchedBotResponses": {"timeout": 200, "mainAsserter": true}}
5
+
6
+ #me
7
+ Hello1
8
+ Hello2
9
+
10
+ #bot
11
+ You said Hello2
@@ -4,17 +4,17 @@ custom embedded
4
4
  hello
5
5
 
6
6
  #bot
7
- hello should not assert
8
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
7
+ hello
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
9
9
 
10
10
  #bot
11
11
  hello should not assert
12
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
13
 
14
14
  #bot
15
- hello should not assert
16
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
15
+ hello
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
17
17
 
18
18
  #bot
19
19
  hello should not assert
20
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
@@ -0,0 +1,20 @@
1
+ custom embedded
2
+
3
+ #me
4
+ hello
5
+
6
+ #bot
7
+ hello should not assert
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
9
+
10
+ #bot
11
+ hello
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
+
14
+ #bot
15
+ hello should not assert
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
17
+
18
+ #bot
19
+ hello should not assert
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
@@ -0,0 +1,20 @@
1
+ custom embedded
2
+
3
+ #me
4
+ hello
5
+
6
+ #bot
7
+ ?hello
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
9
+
10
+ #bot
11
+ ?hello should not assert
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
+
14
+ #bot
15
+ ?hello 2
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
17
+
18
+ #bot
19
+ ?hello should not assert
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
@@ -101,5 +101,21 @@ describe('convo with custom conditional logichook', function () {
101
101
  const transript = await this.compiler.convos[0].Run(this.container)
102
102
  assert.equal(transript.steps.length, 3)
103
103
  })
104
+
105
+ it('should fail mandatory condition group if no condition met', async function () {
106
+ try {
107
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'conditional_steps_multiple_mandatory_condition_groups.convo.txt')
108
+ await this.compiler.convos[0].Run(this.container)
109
+ assert.fail('it should have failed')
110
+ } catch (e) {
111
+ assert.equal(e.message, 'custom embedded/Line 18: Non of the conditions are met in \'G2\' condition group')
112
+ }
113
+ })
114
+
115
+ it('should not fail optional condition group if no condition met', async function () {
116
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'conditional_steps_multiple_optional_condition_groups.convo.txt')
117
+ const transript = await this.compiler.convos[0].Run(this.container)
118
+ assert.equal(transript.steps.length, 2)
119
+ })
104
120
  })
105
121
  })
@@ -207,7 +207,10 @@ describe('scripting.matching.matchingmode', function () {
207
207
  'umm',
208
208
  'interesting',
209
209
  'really?'
210
- ], 'test')
210
+ ],
211
+ 'test',
212
+ null,
213
+ {})
211
214
  })
212
215
  })
213
216