botium-core 1.11.14 → 1.12.1
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 +853 -579
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +471 -198
- package/dist/botium-es.js.map +1 -1
- package/index.js +1 -0
- package/package.json +29 -29
- package/samples/connectors/custom/botium-connector-myapi.js +3 -3
- package/samples/extensions/asserterHooks/DummyAsserter.js +3 -3
- package/src/Capabilities.js +4 -1
- package/src/Defaults.js +1 -0
- package/src/Enums.js +6 -0
- package/src/containers/plugins/SimpleRestContainer.js +32 -1
- package/src/scripting/BotiumError.js +21 -0
- package/src/scripting/CompilerCsv.js +1 -1
- package/src/scripting/CompilerObjectBase.js +4 -14
- package/src/scripting/CompilerTxt.js +4 -15
- package/src/scripting/CompilerXlsx.js +81 -25
- package/src/scripting/Convo.js +16 -4
- package/src/scripting/MatchFunctions.js +21 -0
- package/src/scripting/ScriptingProvider.js +55 -40
- package/src/scripting/helper.js +57 -4
- package/src/scripting/logichook/LogicHookConsts.js +4 -0
- package/src/scripting/logichook/LogicHookUtils.js +2 -0
- package/src/scripting/logichook/asserter/JsonPathAsserter.js +1 -1
- package/src/scripting/logichook/asserter/TextWildcardExactAllAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAllICAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAnyAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAnyICAsserter.js +8 -0
- package/src/scripting/logichook/logichooks/ClearQueueLogicHook.js +1 -1
- package/src/scripting/logichook/userinput/MediaInput.js +14 -2
- package/test/connectors/convos/hello.convo.txt +6 -0
- package/test/connectors/simplerest.spec.js +42 -2
- package/test/convo/convos/continuefailing.convo.txt +19 -0
- package/test/convo/transcript.spec.js +34 -0
- package/test/scripting/asserters/convos/text_wildcardexact_all_nok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_all_ok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_any_nok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_any_ok.yml +7 -0
- package/test/scripting/asserters/textWildcardExactAllAsserter.spec.js +51 -0
- package/test/scripting/asserters/textWildcardExactAnyAsserter.spec.js +51 -0
- package/test/scripting/matching/matchingmode.spec.js +43 -0
- package/test/scripting/scriptingProvider.spec.js +4 -4
- package/test/scripting/scriptingmemory/convosMultiMemorySameCols/buy.convo.txt +6 -0
- package/test/scripting/scriptingmemory/convosMultiMemorySameCols/products1.scriptingmemory.txt +2 -0
- package/test/scripting/scriptingmemory/convosMultiMemorySameCols/products2.scriptingmemory.txt +2 -0
- package/test/scripting/scriptingmemory/convosSimpleCols/buy.convo.txt +8 -0
- package/test/scripting/scriptingmemory/convosSimpleCols/product.scriptingmemory.txt +3 -0
- package/test/scripting/scriptingmemory/convosTwoTablesCols/buy.convo.txt +6 -0
- package/test/scripting/scriptingmemory/convosTwoTablesCols/customer.xlsx +0 -0
- package/test/scripting/scriptingmemory/convosTwoTablesCols/product.xlsx +0 -0
- package/test/scripting/scriptingmemory/fillScriptingMemoryFromFile.spec.js +45 -0
- package/test/scripting/userinputs/mediaInputConvos.spec.js +53 -2
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ module.exports = {
|
|
|
4
4
|
ScriptingConstants: require('./src/scripting/Constants'),
|
|
5
5
|
Capabilities: require('./src/Capabilities'),
|
|
6
6
|
Defaults: require('./src/Defaults'),
|
|
7
|
+
Enums: require('./src/Enums'),
|
|
7
8
|
Source: require('./src/Source'),
|
|
8
9
|
Events: require('./src/Events'),
|
|
9
10
|
Plugins: require('./src/Plugins'),
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botium-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "The Selenium for Chatbots",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/botium-es.js",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=14.0.0"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"postinstall": "node ./report.js",
|
|
@@ -32,66 +32,66 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://www.botium.ai",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@babel/runtime": "^7.
|
|
36
|
-
"async": "^3.2.
|
|
37
|
-
"body-parser": "^1.19.
|
|
35
|
+
"@babel/runtime": "^7.16.7",
|
|
36
|
+
"async": "^3.2.3",
|
|
37
|
+
"body-parser": "^1.19.1",
|
|
38
38
|
"boolean": "^3.1.4",
|
|
39
39
|
"bottleneck": "^2.19.5",
|
|
40
|
-
"csv-parse": "^
|
|
41
|
-
"debug": "^4.3.
|
|
40
|
+
"csv-parse": "^5.0.4",
|
|
41
|
+
"debug": "^4.3.3",
|
|
42
42
|
"esprima": "^4.0.1",
|
|
43
|
-
"express": "^4.17.
|
|
43
|
+
"express": "^4.17.2",
|
|
44
44
|
"globby": "11.0.4",
|
|
45
|
-
"ioredis": "^4.
|
|
45
|
+
"ioredis": "^4.28.3",
|
|
46
46
|
"is-class": "^0.0.9",
|
|
47
47
|
"is-json": "^2.0.1",
|
|
48
48
|
"jsonpath": "^1.1.1",
|
|
49
49
|
"lodash": "^4.17.21",
|
|
50
|
-
"markdown-it": "^12.2
|
|
51
|
-
"mime-types": "^2.1.
|
|
50
|
+
"markdown-it": "^12.3.2",
|
|
51
|
+
"mime-types": "^2.1.34",
|
|
52
52
|
"mkdirp": "^1.0.4",
|
|
53
53
|
"moment": "^2.29.1",
|
|
54
54
|
"mustache": "^4.2.0",
|
|
55
55
|
"promise-retry": "^2.0.1",
|
|
56
|
-
"promise.allsettled": "^1.0.
|
|
56
|
+
"promise.allsettled": "^1.0.5",
|
|
57
57
|
"randomatic": "^3.1.1",
|
|
58
58
|
"request": "^2.88.2",
|
|
59
59
|
"rimraf": "^3.0.2",
|
|
60
60
|
"sanitize-filename": "^1.6.3",
|
|
61
|
-
"slugify": "^1.6.
|
|
62
|
-
"socket.io": "^4.
|
|
63
|
-
"socket.io-client": "^4.
|
|
61
|
+
"slugify": "^1.6.5",
|
|
62
|
+
"socket.io": "^4.4.1",
|
|
63
|
+
"socket.io-client": "^4.4.1",
|
|
64
64
|
"socketio-auth": "^0.1.1",
|
|
65
65
|
"swagger-jsdoc": "^6.1.0",
|
|
66
|
-
"swagger-ui-express": "^4.
|
|
66
|
+
"swagger-ui-express": "^4.3.0",
|
|
67
67
|
"uuid": "^8.3.2",
|
|
68
|
-
"vm2": "^3.9.
|
|
68
|
+
"vm2": "^3.9.5",
|
|
69
69
|
"write-yaml": "^1.0.0",
|
|
70
|
-
"xlsx": "^0.17.
|
|
70
|
+
"xlsx": "^0.17.5",
|
|
71
71
|
"xregexp": "^5.1.0",
|
|
72
72
|
"yaml": "^1.10.2"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@babel/core": "^7.
|
|
76
|
-
"@babel/node": "^7.
|
|
77
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
78
|
-
"@babel/preset-env": "^7.
|
|
75
|
+
"@babel/core": "^7.16.12",
|
|
76
|
+
"@babel/node": "^7.16.8",
|
|
77
|
+
"@babel/plugin-transform-runtime": "^7.16.10",
|
|
78
|
+
"@babel/preset-env": "^7.16.11",
|
|
79
79
|
"chai": "^4.3.4",
|
|
80
80
|
"chai-as-promised": "^7.1.1",
|
|
81
81
|
"cross-env": "^7.0.3",
|
|
82
|
-
"eslint": "^7.
|
|
82
|
+
"eslint": "^8.7.0",
|
|
83
83
|
"eslint-config-standard": "^16.0.3",
|
|
84
|
-
"eslint-plugin-import": "^2.
|
|
84
|
+
"eslint-plugin-import": "^2.25.4",
|
|
85
85
|
"eslint-plugin-node": "^11.1.0",
|
|
86
|
-
"eslint-plugin-promise": "^
|
|
86
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
87
87
|
"eslint-plugin-standard": "^4.1.0",
|
|
88
88
|
"license-checker": "^25.0.1",
|
|
89
89
|
"license-compatibility-checker": "^0.3.5",
|
|
90
|
-
"mocha": "^9.
|
|
91
|
-
"nock": "^13.
|
|
92
|
-
"npm-check-updates": "^
|
|
90
|
+
"mocha": "^9.2.0",
|
|
91
|
+
"nock": "^13.2.2",
|
|
92
|
+
"npm-check-updates": "^12.2.1",
|
|
93
93
|
"nyc": "^15.1.0",
|
|
94
|
-
"rollup": "^2.
|
|
94
|
+
"rollup": "^2.66.0",
|
|
95
95
|
"rollup-plugin-babel": "^4.4.0",
|
|
96
96
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
97
97
|
"rollup-plugin-json": "^4.0.0",
|
|
@@ -23,13 +23,13 @@ class BotiumConnectorMyApi {
|
|
|
23
23
|
[CoreCapabilities.SIMPLEREST_URL]: this.caps[Capabilities.MYAPI_URL],
|
|
24
24
|
[CoreCapabilities.SIMPLEREST_METHOD]: 'POST',
|
|
25
25
|
[CoreCapabilities.SIMPLEREST_RESPONSE_JSONPATH]: '$.reply',
|
|
26
|
-
[CoreCapabilities.SIMPLEREST_BODY_TEMPLATE]: JSON.stringify({
|
|
26
|
+
[CoreCapabilities.SIMPLEREST_BODY_TEMPLATE]: JSON.stringify({
|
|
27
27
|
username: 'botium',
|
|
28
28
|
message: '{{msg.messageText}}',
|
|
29
29
|
session: '{{botium.conversationId}}',
|
|
30
30
|
startsession: false,
|
|
31
31
|
quickreply: null
|
|
32
|
-
|
|
32
|
+
})
|
|
33
33
|
}
|
|
34
34
|
if (this.caps[Capabilities.MYAPI_TOKEN]) {
|
|
35
35
|
this.delegateCaps[CoreCapabilities.SIMPLEREST_HEADERS_TEMPLATE] = `{ "Authorization": "Token ${this.caps[Capabilities.MYAPI_TOKEN]}"}`
|
|
@@ -104,4 +104,4 @@ module.exports = {
|
|
|
104
104
|
}
|
|
105
105
|
]
|
|
106
106
|
}
|
|
107
|
-
}
|
|
107
|
+
}
|
|
@@ -6,17 +6,17 @@ module.exports = class DummyAsserter {
|
|
|
6
6
|
this.caps = caps
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
assertConvoBegin ({convo, container, args}) {
|
|
9
|
+
assertConvoBegin ({ convo, container, args }) {
|
|
10
10
|
console.log(`Dummy asserter Begin started with those args: ${utils.inspect(args)}`)
|
|
11
11
|
return Promise.resolve()
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
assertConvoStep ({convo, convoStep, args, botMsg}) {
|
|
14
|
+
assertConvoStep ({ convo, convoStep, args, botMsg }) {
|
|
15
15
|
console.log(`ConvoStep dummy assertion with those args: ${utils.inspect(args)}, botMessage: ${utils.inspect(botMsg)} ...`)
|
|
16
16
|
return Promise.resolve()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
assertConvoEnd ({convo, container, transcript, args}) {
|
|
19
|
+
assertConvoEnd ({ convo, container, transcript, args }) {
|
|
20
20
|
console.log(`ConvoEnd dummy assertion with those args: ${utils.inspect(args)}, transcript: ${utils.inspect(transcript)} ...`)
|
|
21
21
|
return Promise.resolve()
|
|
22
22
|
}
|
package/src/Capabilities.js
CHANGED
|
@@ -111,8 +111,9 @@ module.exports = {
|
|
|
111
111
|
SCRIPTING_NORMALIZE_TEXT: 'SCRIPTING_NORMALIZE_TEXT',
|
|
112
112
|
SCRIPTING_ENABLE_MEMORY: 'SCRIPTING_ENABLE_MEMORY',
|
|
113
113
|
SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS: 'SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS',
|
|
114
|
+
SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS: 'SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS',
|
|
114
115
|
SCRIPTING_FORCE_BOT_CONSUMED: 'SCRIPTING_FORCE_BOT_CONSUMED',
|
|
115
|
-
// regexp, regexpIgnoreCase, wildcard, wildcardIgnoreCase, include, includeIgnoreCase, equals, equalsIgnoreCase
|
|
116
|
+
// regexp, regexpIgnoreCase, wildcard, wildcardIgnoreCase, wildcardExact, wildcardExactIgnoreCase, include, includeIgnoreCase, equals, equalsIgnoreCase
|
|
116
117
|
SCRIPTING_MATCHING_MODE: 'SCRIPTING_MATCHING_MODE',
|
|
117
118
|
// all, first, random
|
|
118
119
|
SCRIPTING_UTTEXPANSION_MODE: 'SCRIPTING_UTTEXPANSION_MODE',
|
|
@@ -126,6 +127,8 @@ module.exports = {
|
|
|
126
127
|
SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: 'SCRIPTING_MEMORYEXPANSION_KEEP_ORIG',
|
|
127
128
|
// word, non_whitespace, joker
|
|
128
129
|
SCRIPTING_MEMORY_MATCHING_MODE: 'SCRIPTING_MEMORY_MATCHING_MODE',
|
|
130
|
+
// varnames, testcasenames
|
|
131
|
+
SCRIPTING_MEMORY_COLUMN_MODE: 'SCRIPTING_MEMORY_COLUMN_MODE',
|
|
129
132
|
// Botium Lifecycle Hooks
|
|
130
133
|
CUSTOMHOOK_ONBUILD: 'CUSTOMHOOK_ONBUILD',
|
|
131
134
|
CUSTOMHOOK_ONSTART: 'CUSTOMHOOK_ONSTART',
|
package/src/Defaults.js
CHANGED
|
@@ -50,6 +50,7 @@ module.exports = {
|
|
|
50
50
|
[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_MODE]: 'justLineTag',
|
|
51
51
|
[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_UTTERANCE_MAX]: '16',
|
|
52
52
|
[Capabilities.SCRIPTING_MEMORYEXPANSION_KEEP_ORIG]: false,
|
|
53
|
+
[Capabilities.SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS]: false,
|
|
53
54
|
[Capabilities.SCRIPTING_FORCE_BOT_CONSUMED]: false,
|
|
54
55
|
[Capabilities.ASSERTERS]: [],
|
|
55
56
|
[Capabilities.LOGIC_HOOKS]: [],
|
package/src/Enums.js
ADDED
|
@@ -17,6 +17,7 @@ const Defaults = require('../../Defaults').Capabilities
|
|
|
17
17
|
const { SCRIPTING_FUNCTIONS } = require('../../scripting/ScriptingMemory')
|
|
18
18
|
const { getHook, executeHook } = require('../../helpers/HookUtils')
|
|
19
19
|
const { escapeJSONString } = require('../../helpers/Utils')
|
|
20
|
+
const { BotiumError } = require('../../scripting/BotiumError')
|
|
20
21
|
|
|
21
22
|
Mustache.escape = s => s
|
|
22
23
|
|
|
@@ -384,6 +385,18 @@ module.exports = class SimpleRestContainer {
|
|
|
384
385
|
} else {
|
|
385
386
|
if (response.statusCode >= 400) {
|
|
386
387
|
debug(`got error response: ${response.statusCode}/${response.statusMessage}`)
|
|
388
|
+
if (debug.enabled && body) {
|
|
389
|
+
debug(botiumUtils.shortenJsonString(body))
|
|
390
|
+
}
|
|
391
|
+
if (body) {
|
|
392
|
+
const jsonBody = botiumUtils.toJsonWeak(body)
|
|
393
|
+
const errKey = Object.keys(jsonBody).find(k => k.startsWith('err') || k.startsWith('fail'))
|
|
394
|
+
if (errKey) {
|
|
395
|
+
return reject(new BotiumError(`got error response: ${response.statusCode}/${response.statusMessage} - ${jsonBody[errKey]}`, {
|
|
396
|
+
message: botiumUtils.shortenJsonString(body)
|
|
397
|
+
}))
|
|
398
|
+
}
|
|
399
|
+
}
|
|
387
400
|
return reject(new Error(`got error response: ${response.statusCode}/${response.statusMessage}`))
|
|
388
401
|
}
|
|
389
402
|
|
|
@@ -475,6 +488,15 @@ module.exports = class SimpleRestContainer {
|
|
|
475
488
|
requestOptions.uri = `${requestOptions.uri}?${appendToUri}`
|
|
476
489
|
}
|
|
477
490
|
}
|
|
491
|
+
if (msg.ADD_FORM_PARAM && Object.keys(msg.ADD_FORM_PARAM).length > 0) {
|
|
492
|
+
requestOptions.form = {}
|
|
493
|
+
for (const formKey of Object.keys(msg.ADD_FORM_PARAM)) {
|
|
494
|
+
const formValue = this._getMustachedVal(
|
|
495
|
+
_.isString(msg.ADD_FORM_PARAM[formKey]) ? msg.ADD_FORM_PARAM[formKey] : JSON.stringify(msg.ADD_FORM_PARAM[formKey]),
|
|
496
|
+
false)
|
|
497
|
+
requestOptions.form[formKey] = formValue
|
|
498
|
+
}
|
|
499
|
+
}
|
|
478
500
|
if (msg.ADD_HEADER && Object.keys(msg.ADD_HEADER).length > 0) {
|
|
479
501
|
requestOptions.headers = requestOptions.headers || {}
|
|
480
502
|
|
|
@@ -516,9 +538,15 @@ module.exports = class SimpleRestContainer {
|
|
|
516
538
|
await timeout(pingConfig.timeout)
|
|
517
539
|
} else if (response.statusCode >= 400) {
|
|
518
540
|
debug(`_waitForUrlResponse on url check ${pingConfig.uri} got error response: ${response.statusCode}/${response.statusMessage}`)
|
|
541
|
+
if (debug.enabled && body) {
|
|
542
|
+
debug(botiumUtils.shortenJsonString(body))
|
|
543
|
+
}
|
|
519
544
|
await timeout(pingConfig.timeout)
|
|
520
545
|
} else {
|
|
521
|
-
debug(`_waitForUrlResponse success on url check ${pingConfig.uri}`)
|
|
546
|
+
debug(`_waitForUrlResponse success on url check ${pingConfig.uri}: ${response.statusCode}/${response.statusMessage}`)
|
|
547
|
+
if (debug.enabled && body) {
|
|
548
|
+
debug(botiumUtils.shortenJsonString(body))
|
|
549
|
+
}
|
|
522
550
|
return body
|
|
523
551
|
}
|
|
524
552
|
}
|
|
@@ -712,6 +740,9 @@ module.exports = class SimpleRestContainer {
|
|
|
712
740
|
} else {
|
|
713
741
|
if (response.statusCode >= 400) {
|
|
714
742
|
debug(`_runPolling: got error response: ${response.statusCode}/${response.statusMessage}, request: ${JSON.stringify(pollConfig)}`)
|
|
743
|
+
if (debug.enabled && body) {
|
|
744
|
+
debug(botiumUtils.shortenJsonString(body))
|
|
745
|
+
}
|
|
715
746
|
} else if (body) {
|
|
716
747
|
debug(`_runPolling: got response code: ${response.statusCode}, body: ${botiumUtils.shortenJsonString(body)}`)
|
|
717
748
|
|
|
@@ -26,6 +26,27 @@ const BotiumError = class BotiumError extends Error {
|
|
|
26
26
|
this.context.message = message.message || message
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
isAsserterError () {
|
|
30
|
+
if (this.context) {
|
|
31
|
+
const errArr = _.isArray(this.context) ? this.context : [this.context]
|
|
32
|
+
const hasNotAsserterError = errArr.findIndex(errDetail => {
|
|
33
|
+
if (errDetail.type === 'list') {
|
|
34
|
+
if (errDetail.errors) {
|
|
35
|
+
return errDetail.errors.findIndex(e => e.type !== 'asserter') >= 0
|
|
36
|
+
} else {
|
|
37
|
+
return true
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
return errDetail.type !== 'asserter'
|
|
41
|
+
}
|
|
42
|
+
}) >= 0
|
|
43
|
+
if (hasNotAsserterError) return false
|
|
44
|
+
return true
|
|
45
|
+
} else {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
29
50
|
prettify (includeJson) {
|
|
30
51
|
const lines = []
|
|
31
52
|
if (this.context) {
|
|
@@ -6,7 +6,7 @@ const CompilerBase = require('./CompilerBase')
|
|
|
6
6
|
const Constants = require('./Constants')
|
|
7
7
|
const Utterance = require('./Utterance')
|
|
8
8
|
const { Convo } = require('./Convo')
|
|
9
|
-
const { linesToConvoStep, validSenders } = require('./helper')
|
|
9
|
+
const { linesToConvoStep, validSenders, linesToScriptingMemories } = require('./helper')
|
|
10
10
|
|
|
11
11
|
module.exports = class CompilerObjectBase extends CompilerBase {
|
|
12
12
|
constructor (context, caps = {}) {
|
|
@@ -109,20 +109,10 @@ module.exports = class CompilerObjectBase extends CompilerBase {
|
|
|
109
109
|
if (lines && lines.length > 0) {
|
|
110
110
|
if (_.isString(lines[0])) {
|
|
111
111
|
if (lines.length > 1) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const rawRow = lines[row].split('|').map((name) => name.trim())
|
|
116
|
-
const caseName = rawRow[0]
|
|
117
|
-
const values = rawRow.slice(1)
|
|
118
|
-
const json = {}
|
|
119
|
-
for (let col = 0; col < names.length; col++) {
|
|
120
|
-
json[names[col]] = values[col]
|
|
121
|
-
}
|
|
122
|
-
const scriptingMemory = { header: { name: caseName }, values: json }
|
|
123
|
-
scriptingMemories.push(scriptingMemory)
|
|
112
|
+
const scriptingMemories = linesToScriptingMemories(lines, this.caps[Capabilities.SCRIPTING_MEMORY_COLUMN_MODE])
|
|
113
|
+
if (scriptingMemories && scriptingMemories.length > 0) {
|
|
114
|
+
this.context.AddScriptingMemories(scriptingMemories)
|
|
124
115
|
}
|
|
125
|
-
this.context.AddScriptingMemories(scriptingMemories)
|
|
126
116
|
return scriptingMemories
|
|
127
117
|
}
|
|
128
118
|
} else {
|
|
@@ -5,7 +5,7 @@ const Constants = require('./Constants')
|
|
|
5
5
|
const CompilerBase = require('./CompilerBase')
|
|
6
6
|
const Utterance = require('./Utterance')
|
|
7
7
|
const { ConvoHeader, Convo } = require('./Convo')
|
|
8
|
-
const { linesToConvoStep, convoStepToLines, validateConvo, validSenders } = require('./helper')
|
|
8
|
+
const { linesToConvoStep, convoStepToLines, validateConvo, validSenders, linesToScriptingMemories } = require('./helper')
|
|
9
9
|
|
|
10
10
|
module.exports = class CompilerTxt extends CompilerBase {
|
|
11
11
|
constructor (context, caps = {}) {
|
|
@@ -131,21 +131,10 @@ module.exports = class CompilerTxt extends CompilerBase {
|
|
|
131
131
|
|
|
132
132
|
_compileScriptingMemory (lines) {
|
|
133
133
|
if (lines && lines.length > 1) {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (!lines[row] || lines[row].length === 0) continue
|
|
138
|
-
const rawRow = lines[row].split('|').map((name) => name.trim())
|
|
139
|
-
const caseName = rawRow[0]
|
|
140
|
-
const values = rawRow.slice(1)
|
|
141
|
-
const json = {}
|
|
142
|
-
for (let col = 0; col < names.length; col++) {
|
|
143
|
-
json[names[col]] = values[col]
|
|
144
|
-
}
|
|
145
|
-
const scriptingMemory = { header: { name: caseName }, values: json }
|
|
146
|
-
scriptingMemories.push(scriptingMemory)
|
|
134
|
+
const scriptingMemories = linesToScriptingMemories(lines, this.caps[Capabilities.SCRIPTING_MEMORY_COLUMN_MODE])
|
|
135
|
+
if (scriptingMemories && scriptingMemories.length > 0) {
|
|
136
|
+
this.context.AddScriptingMemories(scriptingMemories)
|
|
147
137
|
}
|
|
148
|
-
this.context.AddScriptingMemories(scriptingMemories)
|
|
149
138
|
return scriptingMemories
|
|
150
139
|
}
|
|
151
140
|
}
|
|
@@ -4,6 +4,7 @@ const _ = require('lodash')
|
|
|
4
4
|
const debug = require('debug')('botium-core-CompilerXlsx')
|
|
5
5
|
|
|
6
6
|
const Capabilities = require('../Capabilities')
|
|
7
|
+
const { E_SCRIPTING_MEMORY_COLUMN_MODE } = require('../Enums')
|
|
7
8
|
const CompilerBase = require('./CompilerBase')
|
|
8
9
|
const Constants = require('./Constants')
|
|
9
10
|
const Utterance = require('./Utterance')
|
|
@@ -286,38 +287,93 @@ module.exports = class CompilerXlsx extends CompilerBase {
|
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
if (scriptType === Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY) {
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (sheet[variableNameCell] && sheet[variableNameCell].v) {
|
|
294
|
-
variableNames.push(sheet[variableNameCell].v)
|
|
295
|
-
} else {
|
|
296
|
-
break
|
|
290
|
+
const guessScriptingMemoryColumnMode = () => {
|
|
291
|
+
const line1Cell = this.colnames[colindex] + (rowindex + 1)
|
|
292
|
+
if (sheet[line1Cell] && sheet[line1Cell].v) {
|
|
293
|
+
if (sheet[line1Cell].v.startsWith('$')) return E_SCRIPTING_MEMORY_COLUMN_MODE.TESTCASENAMES
|
|
297
294
|
}
|
|
298
|
-
|
|
299
|
-
colindexTemp++
|
|
295
|
+
return E_SCRIPTING_MEMORY_COLUMN_MODE.VARNAMES
|
|
300
296
|
}
|
|
297
|
+
const columnMode = this.caps[Capabilities.SCRIPTING_MEMORY_COLUMN_MODE] || guessScriptingMemoryColumnMode()
|
|
298
|
+
|
|
299
|
+
if (columnMode === E_SCRIPTING_MEMORY_COLUMN_MODE.TESTCASENAMES) {
|
|
300
|
+
const caseNames = []
|
|
301
|
+
let colindexTemp = colindex + 1
|
|
302
|
+
while (true) {
|
|
303
|
+
const caseNameCell = this.colnames[colindexTemp] + rowindex
|
|
304
|
+
if (sheet[caseNameCell] && sheet[caseNameCell].v) {
|
|
305
|
+
caseNames.push(sheet[caseNameCell].v)
|
|
306
|
+
} else {
|
|
307
|
+
break
|
|
308
|
+
}
|
|
309
|
+
colindexTemp++
|
|
310
|
+
}
|
|
301
311
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
312
|
+
const varNames = []
|
|
313
|
+
const varValues = []
|
|
314
|
+
|
|
315
|
+
rowindex += 1
|
|
316
|
+
while (true) {
|
|
317
|
+
const varNameCell = this.colnames[colindex] + rowindex
|
|
318
|
+
if (sheet[varNameCell] && sheet[varNameCell].v) {
|
|
319
|
+
varNames.push(sheet[varNameCell].v)
|
|
320
|
+
const values = []
|
|
321
|
+
for (let i = 0; i < caseNames.length; i++) {
|
|
322
|
+
const variableValueCell = this.colnames[colindex + 1 + i] + rowindex
|
|
323
|
+
if (sheet[variableValueCell] && sheet[variableValueCell].v) {
|
|
324
|
+
values.push(sheet[variableValueCell].v.toString())
|
|
325
|
+
} else {
|
|
326
|
+
values.push(null)
|
|
327
|
+
}
|
|
314
328
|
}
|
|
329
|
+
varValues.push(values)
|
|
330
|
+
rowindex += 1
|
|
331
|
+
} else {
|
|
332
|
+
break
|
|
315
333
|
}
|
|
316
|
-
|
|
334
|
+
}
|
|
335
|
+
for (let caseIndex = 0; caseIndex < caseNames.length; caseIndex++) {
|
|
336
|
+
const caseName = caseNames[caseIndex]
|
|
317
337
|
|
|
338
|
+
const values = varNames.reduce((agg, varName, varIndex) => {
|
|
339
|
+
agg[varName] = varValues[varIndex][caseIndex] || null
|
|
340
|
+
return agg
|
|
341
|
+
}, {})
|
|
318
342
|
scriptResults.push({ header: { name: caseName }, values: values })
|
|
319
|
-
}
|
|
320
|
-
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
const variableNames = []
|
|
346
|
+
let colindexTemp = colindex + 1
|
|
347
|
+
while (true) {
|
|
348
|
+
const variableNameCell = this.colnames[colindexTemp] + rowindex
|
|
349
|
+
if (sheet[variableNameCell] && sheet[variableNameCell].v) {
|
|
350
|
+
variableNames.push(sheet[variableNameCell].v)
|
|
351
|
+
} else {
|
|
352
|
+
break
|
|
353
|
+
}
|
|
354
|
+
colindexTemp++
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
rowindex += 1
|
|
358
|
+
while (true) {
|
|
359
|
+
const caseNameCell = this.colnames[colindex] + rowindex
|
|
360
|
+
if (sheet[caseNameCell] && sheet[caseNameCell].v) {
|
|
361
|
+
const caseName = sheet[caseNameCell].v
|
|
362
|
+
const values = {}
|
|
363
|
+
for (let i = 0; i < variableNames.length; i++) {
|
|
364
|
+
const variableValueCell = this.colnames[colindex + 1 + i] + rowindex
|
|
365
|
+
if (sheet[variableValueCell] && sheet[variableValueCell].v) {
|
|
366
|
+
values[variableNames[i]] = sheet[variableValueCell].v.toString()
|
|
367
|
+
} else {
|
|
368
|
+
values[variableNames[i]] = null
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
rowindex += 1
|
|
372
|
+
|
|
373
|
+
scriptResults.push({ header: { name: caseName }, values: values })
|
|
374
|
+
} else {
|
|
375
|
+
break
|
|
376
|
+
}
|
|
321
377
|
}
|
|
322
378
|
}
|
|
323
379
|
}
|
package/src/scripting/Convo.js
CHANGED
|
@@ -36,7 +36,7 @@ class ConvoStepAssert {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
toString () {
|
|
39
|
-
return (this.optional ? '?' : '') + (this.not ? '!' : '') + this.name + '(' + (this.args ? this.args.join(',') : 'no args') + ')'
|
|
39
|
+
return (this.optional ? '?' : '') + (this.not ? '!' : '') + this.name + '(' + (this.args ? this.args.map(a => _.truncate(a, { length: 200 })).join(',') : 'no args') + ')'
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -47,7 +47,7 @@ class ConvoStepLogicHook {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
toString () {
|
|
50
|
-
return this.name + '(' + (this.args ? this.args.join(',') : 'no args') + ')'
|
|
50
|
+
return this.name + '(' + (this.args ? this.args.map(a => _.truncate(a, { length: 200 })).join(',') : 'no args') + ')'
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -58,7 +58,7 @@ class ConvoStepUserInput {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
toString () {
|
|
61
|
-
return this.name + '(' + (this.args ? this.args.join(',') : 'no args') + ')'
|
|
61
|
+
return this.name + '(' + (this.args ? this.args.map(a => _.truncate(a, { length: 200 })).join(',') : 'no args') + ')'
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -511,7 +511,13 @@ class Convo {
|
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
513
|
transcriptStep.err = err
|
|
514
|
-
|
|
514
|
+
if (err instanceof BotiumError && container.caps[Capabilities.SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS]) {
|
|
515
|
+
if (!err.isAsserterError()) {
|
|
516
|
+
throw err
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
throw err
|
|
520
|
+
}
|
|
515
521
|
} finally {
|
|
516
522
|
if (convoStep.sender !== 'begin' && convoStep.sender !== 'end' && !skipTranscriptStep) {
|
|
517
523
|
transcriptStep.scriptingMemory = Object.assign({}, scriptingMemory)
|
|
@@ -526,6 +532,12 @@ class Convo {
|
|
|
526
532
|
transcript.steps = transcriptSteps.filter(s => s)
|
|
527
533
|
transcript.scriptingMemory = scriptingMemory
|
|
528
534
|
transcript.convoEnd = new Date()
|
|
535
|
+
if (container.caps[Capabilities.SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS]) {
|
|
536
|
+
const transcriptStepErrs = transcript.steps.filter(s => s.err).map(s => s.err)
|
|
537
|
+
if (transcriptStepErrs && transcriptStepErrs.length > 0) {
|
|
538
|
+
transcript.err = botiumErrorFromList([transcriptStepErrs, transcript.err].filter(e => e), {})
|
|
539
|
+
}
|
|
540
|
+
}
|
|
529
541
|
}
|
|
530
542
|
}
|
|
531
543
|
|
|
@@ -37,6 +37,24 @@ const wildcard = (ignoreCase) => (botresponse, utterance) => {
|
|
|
37
37
|
return regexp.test(botresponse)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
const wildcardExact = (ignoreCase) => (botresponse, utterance) => {
|
|
41
|
+
if (_.isUndefined(botresponse)) {
|
|
42
|
+
if (utterance.trim() === '*') return true
|
|
43
|
+
else return false
|
|
44
|
+
}
|
|
45
|
+
utterance = toString(utterance)
|
|
46
|
+
botresponse = _normalize(botresponse)
|
|
47
|
+
|
|
48
|
+
const numWildcards = utterance.split('*').length - 1
|
|
49
|
+
if (numWildcards > 10) {
|
|
50
|
+
throw new Error('Maximum number of 10 wildcards supported.')
|
|
51
|
+
}
|
|
52
|
+
const utteranceRe = '^' + quoteRegexpString(utterance).replace(/\\\*/g, '(.*)') + '$'
|
|
53
|
+
|
|
54
|
+
const regexp = ignoreCase ? (new RegExp(utteranceRe, 'i')) : (new RegExp(utteranceRe, ''))
|
|
55
|
+
return regexp.test(botresponse)
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
const include = (ignoreCase) => (botresponse, utterance) => {
|
|
41
59
|
if (_.isUndefined(botresponse)) return false
|
|
42
60
|
utterance = toString(utterance)
|
|
@@ -66,6 +84,8 @@ const getMatchFunction = (matchingMode) => {
|
|
|
66
84
|
return regexp(matchingMode === 'regexpIgnoreCase')
|
|
67
85
|
} else if (matchingMode === 'wildcard' || matchingMode === 'wildcardIgnoreCase' || matchingMode === 'wildcardLowerCase') {
|
|
68
86
|
return wildcard(matchingMode === 'wildcardIgnoreCase' || matchingMode === 'wildcardLowerCase')
|
|
87
|
+
} else if (matchingMode === 'wildcardExact' || matchingMode === 'wildcardExactIgnoreCase') {
|
|
88
|
+
return wildcardExact(matchingMode === 'wildcardExactIgnoreCase')
|
|
69
89
|
} else if (matchingMode === 'include' || matchingMode === 'includeIgnoreCase' || matchingMode === 'includeLowerCase') {
|
|
70
90
|
return include(matchingMode === 'includeIgnoreCase' || matchingMode === 'includeLowerCase')
|
|
71
91
|
} else if (matchingMode === 'equals' || matchingMode === 'equalsIgnoreCase') {
|
|
@@ -78,6 +98,7 @@ const getMatchFunction = (matchingMode) => {
|
|
|
78
98
|
module.exports = {
|
|
79
99
|
regexp,
|
|
80
100
|
wildcard,
|
|
101
|
+
wildcardExact,
|
|
81
102
|
include,
|
|
82
103
|
equals,
|
|
83
104
|
getMatchFunction
|