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.
- package/dist/botium-cjs.js +302 -94
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +302 -94
- package/dist/botium-es.js.map +1 -1
- package/package.json +19 -19
- package/src/Capabilities.js +2 -0
- package/src/scripting/BotiumError.js +40 -3
- package/src/scripting/Convo.js +139 -28
- package/src/scripting/ScriptingMemory.js +7 -0
- package/src/scripting/ScriptingProvider.js +79 -30
- package/src/scripting/logichook/LogicHookConsts.js +5 -2
- package/src/scripting/logichook/LogicHookUtils.js +8 -6
- package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +1 -1
- package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +1 -1
- package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +1 -1
- package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +1 -1
- package/src/scripting/logichook/logichooks/ConvoStepParametersLogicHook.js +6 -0
- package/src/scripting/logichook/logichooks/OrderedListToButtonLogicHook.js +37 -0
- package/test/convo/fillAndApplyScriptingMemory.spec.js +11 -0
- package/test/logichooks/orderedListToButton.spec.js +35 -0
- package/test/scripting/asserters/convoStepParameters.spec.js +140 -0
- package/test/scripting/asserters/convos/TEXT_GOOD.convo.txt +6 -0
- package/test/scripting/asserters/convos/convo_step_parameter_matchmode_failed.convo.txt +8 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_all_good.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_botium_timeout.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good_global.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_main_and_asserter.convo.txt +10 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_main_botium_timeout.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_main_but_no_button.convo.txt +10 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good.convo.txt +9 -0
- package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good_begin.convo.txt +11 -0
- package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +6 -6
- package/test/scripting/logichooks/convos/conditional_steps_multiple_mandatory_condition_groups.convo.txt +20 -0
- package/test/scripting/logichooks/convos/conditional_steps_multiple_optional_condition_groups.convo.txt +20 -0
- package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +16 -0
- package/test/scripting/matching/matchingmode.spec.js +4 -1
- 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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,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
|
+
})
|
|
@@ -4,17 +4,17 @@ custom embedded
|
|
|
4
4
|
hello
|
|
5
5
|
|
|
6
6
|
#bot
|
|
7
|
-
hello
|
|
8
|
-
CONDITIONAL_STEP_LOGIC_HOOK { "skip":
|
|
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":
|
|
12
|
+
CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
|
|
13
13
|
|
|
14
14
|
#bot
|
|
15
|
-
hello
|
|
16
|
-
CONDITIONAL_STEP_LOGIC_HOOK { "skip":
|
|
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":
|
|
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
|
})
|