botium-core 1.11.16 → 1.12.0
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 +95 -63
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +95 -63
- package/dist/botium-es.js.map +1 -1
- package/package.json +25 -25
- package/samples/connectors/custom/botium-connector-myapi.js +3 -3
- package/samples/extensions/asserterHooks/DummyAsserter.js +3 -3
- package/src/containers/plugins/SimpleRestContainer.js +19 -0
- package/src/scripting/CompilerCsv.js +1 -1
- package/src/scripting/logichook/LogicHookUtils.js +2 -0
- package/src/scripting/logichook/asserter/JsonPathAsserter.js +1 -1
- package/test/connectors/convos/hello.convo.txt +6 -0
- package/test/connectors/simplerest.spec.js +42 -2
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botium-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
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,23 +32,23 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://www.botium.ai",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@babel/runtime": "^7.16.
|
|
35
|
+
"@babel/runtime": "^7.16.5",
|
|
36
36
|
"async": "^3.2.2",
|
|
37
|
-
"body-parser": "^1.19.
|
|
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.3",
|
|
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.28.
|
|
45
|
+
"ioredis": "^4.28.2",
|
|
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.
|
|
51
|
-
"mime-types": "^2.1.
|
|
50
|
+
"markdown-it": "^12.3.0",
|
|
51
|
+
"mime-types": "^2.1.34",
|
|
52
52
|
"mkdirp": "^1.0.4",
|
|
53
53
|
"moment": "^2.29.1",
|
|
54
54
|
"mustache": "^4.2.0",
|
|
@@ -58,40 +58,40 @@
|
|
|
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.4",
|
|
62
|
+
"socket.io": "^4.4.0",
|
|
63
|
+
"socket.io-client": "^4.4.0",
|
|
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
68
|
"vm2": "^3.9.5",
|
|
69
69
|
"write-yaml": "^1.0.0",
|
|
70
|
-
"xlsx": "^0.17.
|
|
70
|
+
"xlsx": "^0.17.4",
|
|
71
71
|
"xregexp": "^5.1.0",
|
|
72
72
|
"yaml": "^1.10.2"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@babel/core": "^7.16.
|
|
76
|
-
"@babel/node": "^7.16.
|
|
77
|
-
"@babel/plugin-transform-runtime": "^7.16.
|
|
78
|
-
"@babel/preset-env": "^7.16.
|
|
75
|
+
"@babel/core": "^7.16.5",
|
|
76
|
+
"@babel/node": "^7.16.5",
|
|
77
|
+
"@babel/plugin-transform-runtime": "^7.16.5",
|
|
78
|
+
"@babel/preset-env": "^7.16.5",
|
|
79
79
|
"chai": "^4.3.4",
|
|
80
80
|
"chai-as-promised": "^7.1.1",
|
|
81
81
|
"cross-env": "^7.0.3",
|
|
82
|
-
"eslint": "^8.1
|
|
82
|
+
"eslint": "^8.4.1",
|
|
83
83
|
"eslint-config-standard": "^16.0.3",
|
|
84
|
-
"eslint-plugin-import": "^2.25.
|
|
84
|
+
"eslint-plugin-import": "^2.25.3",
|
|
85
85
|
"eslint-plugin-node": "^11.1.0",
|
|
86
|
-
"eslint-plugin-promise": "^5.
|
|
86
|
+
"eslint-plugin-promise": "^5.2.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
90
|
"mocha": "^9.1.3",
|
|
91
|
-
"nock": "^13.1
|
|
92
|
-
"npm-check-updates": "^12.0.
|
|
91
|
+
"nock": "^13.2.1",
|
|
92
|
+
"npm-check-updates": "^12.0.5",
|
|
93
93
|
"nyc": "^15.1.0",
|
|
94
|
-
"rollup": "^2.
|
|
94
|
+
"rollup": "^2.61.1",
|
|
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
|
}
|
|
@@ -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
|
|
|
@@ -387,6 +388,15 @@ module.exports = class SimpleRestContainer {
|
|
|
387
388
|
if (debug.enabled && body) {
|
|
388
389
|
debug(botiumUtils.shortenJsonString(body))
|
|
389
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
|
+
}
|
|
390
400
|
return reject(new Error(`got error response: ${response.statusCode}/${response.statusMessage}`))
|
|
391
401
|
}
|
|
392
402
|
|
|
@@ -478,6 +488,15 @@ module.exports = class SimpleRestContainer {
|
|
|
478
488
|
requestOptions.uri = `${requestOptions.uri}?${appendToUri}`
|
|
479
489
|
}
|
|
480
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
|
+
}
|
|
481
500
|
if (msg.ADD_HEADER && Object.keys(msg.ADD_HEADER).length > 0) {
|
|
482
501
|
requestOptions.headers = requestOptions.headers || {}
|
|
483
502
|
|
|
@@ -240,6 +240,8 @@ module.exports = class LogicHookUtils {
|
|
|
240
240
|
return CheckClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
241
241
|
} else if (isClass(CheckClass.PluginClass)) {
|
|
242
242
|
return new CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
243
|
+
} else if (_.isFunction(CheckClass.PluginClass)) {
|
|
244
|
+
return CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
243
245
|
} else {
|
|
244
246
|
throw new Error(`${src} class or function expected`)
|
|
245
247
|
}
|
|
@@ -118,7 +118,7 @@ module.exports = class JsonPathAsserter {
|
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
cause: {
|
|
121
|
-
expected: assert || (args && `any element for ${args.join('|')}`) || (!args && `any element in ${path}`),
|
|
121
|
+
expected: assert || ((args && args.length > 0) && `any element for ${args.join('|')}`) || ((!args || args.length === 0) && `any element in ${path}`),
|
|
122
122
|
actual: null,
|
|
123
123
|
path
|
|
124
124
|
}
|
|
@@ -22,6 +22,12 @@ const myCapsPost = {
|
|
|
22
22
|
[Capabilities.SIMPLEREST_BODY_TEMPLATE]: { BODY1: 'BODY1VALUE', BODY2: '{{msg.messageText}}' },
|
|
23
23
|
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: ['$']
|
|
24
24
|
}
|
|
25
|
+
const myCapsFormPost = {
|
|
26
|
+
[Capabilities.CONTAINERMODE]: 'simplerest',
|
|
27
|
+
[Capabilities.SIMPLEREST_URL]: 'http://my-host.com/api/endpoint/{{msg.messageText}}',
|
|
28
|
+
[Capabilities.SIMPLEREST_METHOD]: 'POST',
|
|
29
|
+
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: ['$']
|
|
30
|
+
}
|
|
25
31
|
|
|
26
32
|
const myCapsScriptingMemory = {
|
|
27
33
|
[Capabilities.CONTAINERMODE]: 'simplerest',
|
|
@@ -448,7 +454,7 @@ describe('connectors.simplerest.build', function () {
|
|
|
448
454
|
assert.isTrue(err.message.includes('Cant load hook, syntax is not valid'))
|
|
449
455
|
}
|
|
450
456
|
})
|
|
451
|
-
it('should query params from UPDATE_CUSTOM (without "?")', async function () {
|
|
457
|
+
it('should add query params from UPDATE_CUSTOM (without "?")', async function () {
|
|
452
458
|
const myCaps = Object.assign({}, myCapsGet)
|
|
453
459
|
const myMsg = Object.assign({}, msg)
|
|
454
460
|
myMsg.ADD_QUERY_PARAM = {
|
|
@@ -467,7 +473,7 @@ describe('connectors.simplerest.build', function () {
|
|
|
467
473
|
|
|
468
474
|
await container.Clean()
|
|
469
475
|
})
|
|
470
|
-
it('should query params from UPDATE_CUSTOM (with "?")', async function () {
|
|
476
|
+
it('should add query params from UPDATE_CUSTOM (with "?")', async function () {
|
|
471
477
|
const myCaps = Object.assign({}, myCapsGet)
|
|
472
478
|
myCaps.SIMPLEREST_URL = 'http://my-host.com/api/endpoint/messageText?const1=const1'
|
|
473
479
|
const myMsg = Object.assign({}, msg)
|
|
@@ -510,6 +516,26 @@ describe('connectors.simplerest.build', function () {
|
|
|
510
516
|
|
|
511
517
|
await container.Clean()
|
|
512
518
|
})
|
|
519
|
+
it('should add form params from UPDATE_CUSTOM (without "?")', async function () {
|
|
520
|
+
const myCaps = Object.assign({}, myCapsFormPost)
|
|
521
|
+
const myMsg = Object.assign({}, msg)
|
|
522
|
+
myMsg.ADD_FORM_PARAM = {
|
|
523
|
+
formparam1: 'valueparam1',
|
|
524
|
+
formparam2: '{{msg.messageText}}'
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const driver = new BotDriver(myCaps)
|
|
528
|
+
const container = await driver.Build()
|
|
529
|
+
assert.equal(container.pluginInstance.constructor.name, 'SimpleRestContainer')
|
|
530
|
+
|
|
531
|
+
await container.Start()
|
|
532
|
+
const request = await container.pluginInstance._buildRequest(myMsg)
|
|
533
|
+
assert.isObject(request.form)
|
|
534
|
+
assert.equal(request.form.formparam1, 'valueparam1')
|
|
535
|
+
assert.equal(request.form.formparam2, 'messageText')
|
|
536
|
+
|
|
537
|
+
await container.Clean()
|
|
538
|
+
})
|
|
513
539
|
it('should add header from UPDATE_CUSTOM', async function () {
|
|
514
540
|
const myCaps = Object.assign({}, myCapsGet)
|
|
515
541
|
const myMsg = Object.assign({}, msg)
|
|
@@ -789,6 +815,7 @@ describe('connectors.simplerest.useresponse', function () {
|
|
|
789
815
|
.get('/startencoded').reply(200, { text: JSON.stringify({ prop: 'response from start' }) })
|
|
790
816
|
.get('/startstring').reply(200, 'response from start')
|
|
791
817
|
.get('/msg').reply(200, { text: 'response from msg' })
|
|
818
|
+
.get('/msgfail').reply(400, { error: 'failure text' })
|
|
792
819
|
.persist()
|
|
793
820
|
|
|
794
821
|
const myCaps = Object.assign({
|
|
@@ -914,6 +941,19 @@ describe('connectors.simplerest.useresponse', function () {
|
|
|
914
941
|
assert.equal(transcript.steps.length, 1)
|
|
915
942
|
assert.equal(transcript.steps[0].actual.messageText, 'response from start')
|
|
916
943
|
})
|
|
944
|
+
|
|
945
|
+
it('should use error body content', async function () {
|
|
946
|
+
await this.init({
|
|
947
|
+
[Capabilities.SIMPLEREST_URL]: 'https://mock.com/msgfail'
|
|
948
|
+
})
|
|
949
|
+
|
|
950
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'hello.convo.txt')
|
|
951
|
+
try {
|
|
952
|
+
await this.compiler.convos[0].Run(this.container)
|
|
953
|
+
} catch (err) {
|
|
954
|
+
assert.isTrue(err.message.indexOf('failure text') >= 0)
|
|
955
|
+
}
|
|
956
|
+
})
|
|
917
957
|
})
|
|
918
958
|
|
|
919
959
|
describe('connectors.simplerest.inbound', function () {
|