botium-core 1.12.2 → 1.12.5
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/LICENSES-3RDPARTY.txt +901 -751
- package/dist/botium-cjs.js +211 -90
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +211 -90
- package/dist/botium-es.js.map +1 -1
- package/package.json +24 -24
- package/src/BotDriver.js +27 -22
- package/src/Capabilities.js +6 -0
- package/src/Defaults.js +1 -1
- package/src/containers/plugins/SimpleRestContainer.js +117 -35
- package/src/containers/plugins/index.js +1 -1
- package/src/helpers/Utils.js +1 -1
- package/src/scripting/CompilerXlsx.js +2 -2
- package/src/scripting/Convo.js +6 -6
- package/src/scripting/ScriptingProvider.js +1 -1
- package/src/scripting/helper.js +1 -1
- package/src/scripting/logichook/asserter/BaseCountAsserter.js +1 -1
- package/test/connectors/simplerest.spec.js +113 -8
- package/test/logichooks/convos/WAITFORBOT_INFINITE.convo.txt +1 -1
- package/test/logichooks/hookfromsrc.spec.js +1 -1
- package/test/scripting/scriptingProvider.spec.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botium-core",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.5",
|
|
4
4
|
"description": "The Selenium for Chatbots",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/botium-es.js",
|
|
@@ -32,25 +32,25 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://www.botium.ai",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@babel/runtime": "^7.
|
|
35
|
+
"@babel/runtime": "^7.17.9",
|
|
36
36
|
"async": "^3.2.3",
|
|
37
|
-
"body-parser": "^1.
|
|
38
|
-
"boolean": "^3.
|
|
37
|
+
"body-parser": "^1.20.0",
|
|
38
|
+
"boolean": "^3.2.0",
|
|
39
39
|
"bottleneck": "^2.19.5",
|
|
40
40
|
"csv-parse": "^5.0.4",
|
|
41
|
-
"debug": "^4.3.
|
|
41
|
+
"debug": "^4.3.4",
|
|
42
42
|
"esprima": "^4.0.1",
|
|
43
|
-
"express": "^4.17.
|
|
43
|
+
"express": "^4.17.3",
|
|
44
44
|
"globby": "11.0.4",
|
|
45
|
-
"ioredis": "^
|
|
45
|
+
"ioredis": "^5.0.4",
|
|
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
50
|
"markdown-it": "^12.3.2",
|
|
51
|
-
"mime-types": "^2.1.
|
|
51
|
+
"mime-types": "^2.1.35",
|
|
52
52
|
"mkdirp": "^1.0.4",
|
|
53
|
-
"moment": "^2.29.
|
|
53
|
+
"moment": "^2.29.3",
|
|
54
54
|
"mustache": "^4.2.0",
|
|
55
55
|
"promise-retry": "^2.0.1",
|
|
56
56
|
"promise.allsettled": "^1.0.5",
|
|
@@ -62,36 +62,36 @@
|
|
|
62
62
|
"socket.io": "^4.4.1",
|
|
63
63
|
"socket.io-client": "^4.4.1",
|
|
64
64
|
"socketio-auth": "^0.1.1",
|
|
65
|
-
"swagger-jsdoc": "^6.1
|
|
65
|
+
"swagger-jsdoc": "^6.2.1",
|
|
66
66
|
"swagger-ui-express": "^4.3.0",
|
|
67
67
|
"uuid": "^8.3.2",
|
|
68
|
-
"vm2": "^3.9.
|
|
68
|
+
"vm2": "^3.9.9",
|
|
69
69
|
"write-yaml": "^1.0.0",
|
|
70
|
-
"xlsx": "^0.
|
|
70
|
+
"xlsx": "^0.18.5",
|
|
71
71
|
"xregexp": "^5.1.0",
|
|
72
|
-
"yaml": "^
|
|
72
|
+
"yaml": "^2.0.1"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@babel/core": "^7.
|
|
75
|
+
"@babel/core": "^7.17.9",
|
|
76
76
|
"@babel/node": "^7.16.8",
|
|
77
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
77
|
+
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
78
78
|
"@babel/preset-env": "^7.16.11",
|
|
79
|
-
"chai": "^4.3.
|
|
79
|
+
"chai": "^4.3.6",
|
|
80
80
|
"chai-as-promised": "^7.1.1",
|
|
81
81
|
"cross-env": "^7.0.3",
|
|
82
|
-
"eslint": "^8.
|
|
83
|
-
"eslint-config-standard": "^
|
|
84
|
-
"eslint-plugin-import": "^2.
|
|
85
|
-
"eslint-plugin-
|
|
82
|
+
"eslint": "^8.13.0",
|
|
83
|
+
"eslint-config-standard": "^17.0.0",
|
|
84
|
+
"eslint-plugin-import": "^2.26.0",
|
|
85
|
+
"eslint-plugin-n": "^15.1.0",
|
|
86
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.2.
|
|
91
|
-
"nock": "^13.2.
|
|
92
|
-
"npm-check-updates": "^12.
|
|
90
|
+
"mocha": "^9.2.2",
|
|
91
|
+
"nock": "^13.2.4",
|
|
92
|
+
"npm-check-updates": "^12.5.9",
|
|
93
93
|
"nyc": "^15.1.0",
|
|
94
|
-
"rollup": "^2.
|
|
94
|
+
"rollup": "^2.70.2",
|
|
95
95
|
"rollup-plugin-babel": "^4.4.0",
|
|
96
96
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
97
97
|
"rollup-plugin-json": "^4.0.0",
|
package/src/BotDriver.js
CHANGED
|
@@ -109,12 +109,13 @@ module.exports = class BotDriver {
|
|
|
109
109
|
|
|
110
110
|
Build () {
|
|
111
111
|
debug(`Build - Botium Core Version: ${version}`)
|
|
112
|
-
debug(`Build - Capabilites: ${
|
|
113
|
-
debug(`Build - Sources
|
|
114
|
-
debug(`Build - Envs
|
|
112
|
+
debug(`Build - Capabilites: ${JSON.stringify(_.pickBy(this.caps, (value, key) => Defaults.Capabilities[key] !== value), null, 2)}`)
|
|
113
|
+
debug(`Build - Sources: ${JSON.stringify(_.pickBy(this.sources, (value, key) => Defaults.Sources[key] !== value), null, 2)}`)
|
|
114
|
+
debug(`Build - Envs: ${JSON.stringify(_.pickBy(this.envs, (value, key) => Defaults.Envs[key] !== value), null, 2)}`)
|
|
115
115
|
this.eventEmitter.emit(Events.CONTAINER_BUILDING)
|
|
116
116
|
|
|
117
117
|
return new Promise((resolve, reject) => {
|
|
118
|
+
let tempDirectory = null
|
|
118
119
|
let repo = null
|
|
119
120
|
let container = null
|
|
120
121
|
|
|
@@ -126,9 +127,19 @@ module.exports = class BotDriver {
|
|
|
126
127
|
.catch(driverValidated)
|
|
127
128
|
},
|
|
128
129
|
|
|
130
|
+
(tempDirectoryCreated) => {
|
|
131
|
+
tempDirectory = path.resolve(process.cwd(), this.caps[Capabilities.TEMPDIR], sanitize(`${this.caps[Capabilities.PROJECTNAME]} ${moment().format('YYYYMMDD HHmmss')} ${randomize('Aa0', 5)}`))
|
|
132
|
+
try {
|
|
133
|
+
mkdirp.sync(tempDirectory)
|
|
134
|
+
tempDirectoryCreated()
|
|
135
|
+
} catch (err) {
|
|
136
|
+
tempDirectoryCreated(new Error(`Unable to create temp directory ${tempDirectory}: ${err.message}`))
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
129
140
|
(repoValidated) => {
|
|
130
141
|
try {
|
|
131
|
-
repo = this._getRepo()
|
|
142
|
+
repo = this._getRepo(tempDirectory)
|
|
132
143
|
} catch (err) {
|
|
133
144
|
return repoValidated(err)
|
|
134
145
|
}
|
|
@@ -141,7 +152,7 @@ module.exports = class BotDriver {
|
|
|
141
152
|
|
|
142
153
|
(containerValidated) => {
|
|
143
154
|
try {
|
|
144
|
-
container = this._getContainer(repo)
|
|
155
|
+
container = this._getContainer(tempDirectory, repo)
|
|
145
156
|
} catch (err) {
|
|
146
157
|
return containerValidated(err)
|
|
147
158
|
}
|
|
@@ -156,9 +167,9 @@ module.exports = class BotDriver {
|
|
|
156
167
|
if (err) {
|
|
157
168
|
debug(`BotDriver Build error: ${err}`)
|
|
158
169
|
this.eventEmitter.emit(Events.CONTAINER_BUILD_ERROR, err)
|
|
159
|
-
if (
|
|
160
|
-
rimraf(
|
|
161
|
-
if (err) debug(`Cleanup temp dir ${
|
|
170
|
+
if (tempDirectory) {
|
|
171
|
+
rimraf(tempDirectory, (err) => {
|
|
172
|
+
if (err) debug(`Cleanup temp dir ${tempDirectory} failed: ${util.inspect(err)}`)
|
|
162
173
|
})
|
|
163
174
|
}
|
|
164
175
|
return reject(err)
|
|
@@ -311,12 +322,6 @@ module.exports = class BotDriver {
|
|
|
311
322
|
throw new Error(`Capability '${Capabilities.CONTAINERMODE}' or '${Capabilities.BOTIUMGRIDURL}' missing`)
|
|
312
323
|
}
|
|
313
324
|
|
|
314
|
-
this.tempDirectory = path.resolve(process.cwd(), this.caps[Capabilities.TEMPDIR], sanitize(`${this.caps[Capabilities.PROJECTNAME]} ${moment().format('YYYYMMDD HHmmss')} ${randomize('Aa0', 5)}`))
|
|
315
|
-
try {
|
|
316
|
-
mkdirp.sync(this.tempDirectory)
|
|
317
|
-
} catch (err) {
|
|
318
|
-
throw new Error(`Unable to create temp directory ${this.tempDirectory}: ${err}`)
|
|
319
|
-
}
|
|
320
325
|
resolve(this)
|
|
321
326
|
} catch (err) {
|
|
322
327
|
reject(err)
|
|
@@ -324,35 +329,35 @@ module.exports = class BotDriver {
|
|
|
324
329
|
})
|
|
325
330
|
}
|
|
326
331
|
|
|
327
|
-
_getRepo () {
|
|
332
|
+
_getRepo (tempDirectory) {
|
|
328
333
|
if (this.caps[Capabilities.BOTIUMGRIDURL]) {
|
|
329
334
|
const NoRepo = require('./repos/NoRepo')
|
|
330
|
-
return new NoRepo(
|
|
335
|
+
return new NoRepo(tempDirectory, this.sources)
|
|
331
336
|
}
|
|
332
337
|
if (this.sources[Source.GITURL]) {
|
|
333
338
|
const GitRepo = require('./repos/GitRepo')
|
|
334
|
-
return new GitRepo(
|
|
339
|
+
return new GitRepo(tempDirectory, this.sources)
|
|
335
340
|
}
|
|
336
341
|
if (this.sources[Source.LOCALPATH]) {
|
|
337
342
|
const LocalRepo = require('./repos/LocalRepo')
|
|
338
|
-
return new LocalRepo(
|
|
343
|
+
return new LocalRepo(tempDirectory, this.sources)
|
|
339
344
|
}
|
|
340
345
|
throw new Error(`No Repo provider found for Sources ${util.inspect(this.sources)}`)
|
|
341
346
|
}
|
|
342
347
|
|
|
343
|
-
_getContainer (repo) {
|
|
348
|
+
_getContainer (tempDirectory, repo) {
|
|
344
349
|
if (this.caps[Capabilities.BOTIUMGRIDURL]) {
|
|
345
350
|
const GridContainer = require('./containers/GridContainer')
|
|
346
|
-
return new GridContainer(this.eventEmitter,
|
|
351
|
+
return new GridContainer(this.eventEmitter, tempDirectory, repo, this.caps, this.envs)
|
|
347
352
|
}
|
|
348
353
|
if (!this.caps[Capabilities.CONTAINERMODE]) {
|
|
349
354
|
throw new Error(`Capability '${Capabilities.CONTAINERMODE}' missing`)
|
|
350
355
|
}
|
|
351
356
|
if (this.caps[Capabilities.CONTAINERMODE] === 'inprocess') {
|
|
352
357
|
const InProcessContainer = require('./containers/InProcessContainer')
|
|
353
|
-
return new InProcessContainer(this.eventEmitter,
|
|
358
|
+
return new InProcessContainer(this.eventEmitter, tempDirectory, repo, this.caps, this.envs)
|
|
354
359
|
}
|
|
355
360
|
const PluginConnectorContainer = require('./containers/PluginConnectorContainer')
|
|
356
|
-
return new PluginConnectorContainer(this.eventEmitter,
|
|
361
|
+
return new PluginConnectorContainer(this.eventEmitter, tempDirectory, repo, this.caps, this.envs)
|
|
357
362
|
}
|
|
358
363
|
}
|
package/src/Capabilities.js
CHANGED
|
@@ -73,6 +73,11 @@ module.exports = {
|
|
|
73
73
|
SIMPLEREST_RESPONSE_HOOK: 'SIMPLEREST_RESPONSE_HOOK',
|
|
74
74
|
SIMPLEREST_MEDIA_JSONPATH: 'SIMPLEREST_MEDIA_JSONPATH',
|
|
75
75
|
SIMPLEREST_BUTTONS_JSONPATH: 'SIMPLEREST_BUTTONS_JSONPATH',
|
|
76
|
+
SIMPLEREST_CARDS_JSONPATH: 'SIMPLEREST_CARDS_JSONPATH',
|
|
77
|
+
SIMPLEREST_CARD_TEXT_JSONPATH: 'SIMPLEREST_CARD_TEXT_JSONPATH',
|
|
78
|
+
SIMPLEREST_CARD_SUBTEXT_JSONPATH: 'SIMPLEREST_CARD_SUBTEXT_JSONPATH',
|
|
79
|
+
SIMPLEREST_CARD_BUTTONS_JSONPATH: 'SIMPLEREST_CARD_BUTTONS_JSONPATH',
|
|
80
|
+
SIMPLEREST_CARD_ATTACHMENTS_JSONPATH: 'SIMPLEREST_CARD_ATTACHMENTS_JSONPATH',
|
|
76
81
|
SIMPLEREST_CONTEXT_JSONPATH: 'SIMPLEREST_CONTEXT_JSONPATH',
|
|
77
82
|
SIMPLEREST_CONTEXT_MERGE_OR_REPLACE: 'SIMPLEREST_CONTEXT_MERGE_OR_REPLACE',
|
|
78
83
|
SIMPLEREST_CONVERSATION_ID_TEMPLATE: 'SIMPLEREST_CONVERSATION_ID_TEMPLATE',
|
|
@@ -86,6 +91,7 @@ module.exports = {
|
|
|
86
91
|
SIMPLEREST_REDIS_TOPIC: 'SIMPLEREST_REDIS_TOPIC',
|
|
87
92
|
SIMPLEREST_INBOUND_ORDER_UNSETTLED_EVENTS_JSONPATH: 'SIMPLEREST_INBOUND_ORDER_UNSETTLED_EVENTS_JSONPATH',
|
|
88
93
|
SIMPLEREST_INBOUND_DEBOUNCE_TIMEOUT: 'SIMPLEREST_INBOUND_DEBOUNCE_TIMEOUT',
|
|
94
|
+
SIMPLEREST_COOKIE_REPLICATION: 'SIMPLEREST_COOKIE_REPLICATION',
|
|
89
95
|
// Script Compiler
|
|
90
96
|
SCRIPTING_TXT_EOL: 'SCRIPTING_TXT_EOL',
|
|
91
97
|
// ROW_PER_MESSAGE or QUESTION_ANSWER
|
package/src/Defaults.js
CHANGED
|
@@ -31,10 +31,10 @@ module.exports = {
|
|
|
31
31
|
[Capabilities.SIMPLEREST_METHOD]: 'GET',
|
|
32
32
|
[Capabilities.SIMPLEREST_IGNORE_EMPTY]: true,
|
|
33
33
|
[Capabilities.SIMPLEREST_TIMEOUT]: 10000,
|
|
34
|
-
[Capabilities.SIMPLEREST_EXTRA_OPTIONS]: {},
|
|
35
34
|
[Capabilities.SIMPLEREST_STRICT_SSL]: true,
|
|
36
35
|
[Capabilities.SIMPLEREST_INBOUND_UPDATE_CONTEXT]: true,
|
|
37
36
|
[Capabilities.SIMPLEREST_CONTEXT_MERGE_OR_REPLACE]: 'MERGE',
|
|
37
|
+
[Capabilities.SIMPLEREST_COOKIE_REPLICATION]: true,
|
|
38
38
|
[Capabilities.SCRIPTING_TXT_EOL]: '\n',
|
|
39
39
|
[Capabilities.SCRIPTING_XLSX_EOL_WRITE]: '\r\n',
|
|
40
40
|
[Capabilities.SCRIPTING_XLSX_HASHEADERS]: true,
|
|
@@ -28,6 +28,7 @@ module.exports = class SimpleRestContainer {
|
|
|
28
28
|
this.bottleneck = bottleneck || ((fn) => fn())
|
|
29
29
|
this.processInbound = false
|
|
30
30
|
this.redisTopic = this.caps[Capabilities.SIMPLEREST_REDIS_TOPIC] || 'SIMPLEREST_INBOUND_SUBSCRIPTION'
|
|
31
|
+
this.cookies = {}
|
|
31
32
|
|
|
32
33
|
if (this.caps[Capabilities.SIMPLEREST_INBOUND_ORDER_UNSETTLED_EVENTS_JSONPATH]) {
|
|
33
34
|
const debounceTimeout = this.caps[Capabilities.SIMPLEREST_INBOUND_DEBOUNCE_TIMEOUT] || 500
|
|
@@ -309,34 +310,82 @@ module.exports = class SimpleRestContainer {
|
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
for (const jsonPathRoot of jsonPathRoots) {
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
313
|
+
const _retrieveMedia = (jsonPathMediaRoot, jsonPathsMedia) => {
|
|
314
|
+
const retrievedMedia = []
|
|
315
|
+
jsonPathsMedia.forEach(jsonPath => {
|
|
316
|
+
const responseMedia = jp.query(jsonPathMediaRoot, jsonPath)
|
|
317
|
+
if (responseMedia) {
|
|
318
|
+
(_.isArray(responseMedia) ? _.flattenDeep(responseMedia) : [responseMedia]).forEach(m =>
|
|
319
|
+
retrievedMedia.push({
|
|
320
|
+
mediaUri: m,
|
|
321
|
+
mimeType: mime.lookup(m) || 'application/unknown'
|
|
322
|
+
})
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
return retrievedMedia
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const _retrieveButtons = (jsonPathButtonRoot, jsonPathsButtons) => {
|
|
330
|
+
const retrievedButtons = []
|
|
331
|
+
jsonPathsButtons.forEach(jsonPath => {
|
|
332
|
+
const responseButtons = jp.query(jsonPathButtonRoot, jsonPath)
|
|
333
|
+
if (responseButtons) {
|
|
334
|
+
(_.isArray(responseButtons) ? _.flattenDeep(responseButtons) : [responseButtons]).forEach(b =>
|
|
335
|
+
retrievedButtons.push({
|
|
336
|
+
text: b
|
|
337
|
+
})
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
return retrievedButtons
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const _getCardText = (responseCardText) => {
|
|
345
|
+
if (responseCardText) {
|
|
346
|
+
const texts = _.isArray(responseCardText) ? _.flattenDeep(responseCardText) : [responseCardText]
|
|
347
|
+
if (texts.length > 1) {
|
|
348
|
+
debug(`more than one text found for card: ${util.inspect(texts)}`)
|
|
349
|
+
}
|
|
350
|
+
if (texts.length > 0) {
|
|
351
|
+
return texts[0]
|
|
352
|
+
}
|
|
326
353
|
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const media = _retrieveMedia(jsonPathRoot, getAllCapValues(Capabilities.SIMPLEREST_MEDIA_JSONPATH, this.caps))
|
|
357
|
+
debug(`found response media: ${util.inspect(media)}`)
|
|
358
|
+
const buttons = _retrieveButtons(jsonPathRoot, getAllCapValues(Capabilities.SIMPLEREST_BUTTONS_JSONPATH, this.caps))
|
|
359
|
+
debug(`found response buttons: ${util.inspect(buttons)}`)
|
|
360
|
+
const cards = []
|
|
361
|
+
|
|
362
|
+
const jsonPathsCards = getAllCapValues(Capabilities.SIMPLEREST_CARDS_JSONPATH, this.caps)
|
|
363
|
+
jsonPathsCards.forEach(jsonPath => {
|
|
364
|
+
const responseCards = jp.query(jsonPathRoot, jsonPath)
|
|
365
|
+
if (responseCards) {
|
|
366
|
+
(_.isArray(responseCards) ? _.flattenDeep(responseCards) : [responseCards]).forEach(c => {
|
|
367
|
+
const card = {}
|
|
368
|
+
|
|
369
|
+
const jsonPathsCardText = getAllCapValues(Capabilities.SIMPLEREST_CARD_TEXT_JSONPATH, this.caps)
|
|
370
|
+
jsonPathsCardText.forEach(jsonPath => {
|
|
371
|
+
card.text = _getCardText(jp.query(c, jsonPath))
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
const jsonPathsCardSubText = getAllCapValues(Capabilities.SIMPLEREST_CARD_SUBTEXT_JSONPATH, this.caps)
|
|
375
|
+
jsonPathsCardSubText.forEach(jsonPath => {
|
|
376
|
+
card.subtext = _getCardText(jp.query(c, jsonPath))
|
|
335
377
|
})
|
|
336
|
-
|
|
337
|
-
|
|
378
|
+
|
|
379
|
+
card.buttons = _retrieveButtons(c, getAllCapValues(Capabilities.SIMPLEREST_CARD_BUTTONS_JSONPATH, this.caps))
|
|
380
|
+
card.media = _retrieveMedia(c, getAllCapValues(Capabilities.SIMPLEREST_CARD_ATTACHMENTS_JSONPATH, this.caps))
|
|
381
|
+
|
|
382
|
+
if (_.keys(card).length > 0) {
|
|
383
|
+
cards.push(card)
|
|
384
|
+
}
|
|
385
|
+
})
|
|
338
386
|
}
|
|
339
387
|
})
|
|
388
|
+
debug(`found response cards: ${util.inspect(cards)}`)
|
|
340
389
|
|
|
341
390
|
let hasMessageText = false
|
|
342
391
|
const jsonPathsTexts = getAllCapValues(Capabilities.SIMPLEREST_RESPONSE_JSONPATH, this.caps)
|
|
@@ -351,18 +400,18 @@ module.exports = class SimpleRestContainer {
|
|
|
351
400
|
if (!messageText) continue
|
|
352
401
|
|
|
353
402
|
hasMessageText = true
|
|
354
|
-
const botMsg = { sourceData: body, messageText, media, buttons }
|
|
403
|
+
const botMsg = { sourceData: body, messageText, media, buttons, cards }
|
|
355
404
|
await executeHook(this.caps, this.responseHook, Object.assign({ botMsg, botMsgRoot: jsonPathRoot, messageTextIndex }, this.view))
|
|
356
405
|
result.push(botMsg)
|
|
357
406
|
}
|
|
358
407
|
}
|
|
359
408
|
|
|
360
409
|
if (!hasMessageText) {
|
|
361
|
-
const botMsg = { messageText: '', sourceData: body, media, buttons }
|
|
410
|
+
const botMsg = { messageText: '', sourceData: body, media, buttons, cards }
|
|
362
411
|
const beforeHookKeys = Object.keys(botMsg)
|
|
363
412
|
await executeHook(this.caps, this.responseHook, Object.assign({ botMsg, botMsgRoot: jsonPathRoot }, this.view))
|
|
364
413
|
const afterHookKeys = Object.keys(botMsg)
|
|
365
|
-
if (beforeHookKeys.length !== afterHookKeys.length || !!(botMsg.messageText && botMsg.messageText.length > 0) || botMsg.media.length > 0 || botMsg.buttons.length > 0 || !this.caps[Capabilities.SIMPLEREST_IGNORE_EMPTY]) {
|
|
414
|
+
if (beforeHookKeys.length !== afterHookKeys.length || !!(botMsg.messageText && botMsg.messageText.length > 0) || botMsg.media.length > 0 || botMsg.buttons.length > 0 || botMsg.cards.length > 0 || !this.caps[Capabilities.SIMPLEREST_IGNORE_EMPTY]) {
|
|
366
415
|
result.push(botMsg)
|
|
367
416
|
}
|
|
368
417
|
}
|
|
@@ -403,7 +452,7 @@ module.exports = class SimpleRestContainer {
|
|
|
403
452
|
|
|
404
453
|
if (body) {
|
|
405
454
|
debug(`got response code: ${response.statusCode}, body: ${botiumUtils.shortenJsonString(body)}`)
|
|
406
|
-
|
|
455
|
+
this._storeCookiesFromResponse(response)
|
|
407
456
|
try {
|
|
408
457
|
body = await this._parseResponseBody(body)
|
|
409
458
|
} catch (err) {
|
|
@@ -512,8 +561,8 @@ module.exports = class SimpleRestContainer {
|
|
|
512
561
|
}
|
|
513
562
|
}
|
|
514
563
|
this._addRequestOptions(requestOptions)
|
|
515
|
-
|
|
516
564
|
await executeHook(this.caps, this.requestHook, Object.assign({ requestOptions }, this.view))
|
|
565
|
+
this._addRequestCookies(requestOptions)
|
|
517
566
|
|
|
518
567
|
return requestOptions
|
|
519
568
|
}
|
|
@@ -545,6 +594,7 @@ module.exports = class SimpleRestContainer {
|
|
|
545
594
|
await timeout(pingConfig.timeout)
|
|
546
595
|
} else {
|
|
547
596
|
debug(`_waitForUrlResponse success on url check ${pingConfig.uri}: ${response.statusCode}/${response.statusMessage}`)
|
|
597
|
+
this._storeCookiesFromResponse(response)
|
|
548
598
|
if (debug.enabled && body) {
|
|
549
599
|
debug(botiumUtils.shortenJsonString(body))
|
|
550
600
|
}
|
|
@@ -705,9 +755,9 @@ module.exports = class SimpleRestContainer {
|
|
|
705
755
|
const timeout = this._getCapValue(Capabilities.SIMPLEREST_POLL_TIMEOUT)
|
|
706
756
|
const pollConfig = {
|
|
707
757
|
method: verb,
|
|
708
|
-
uri
|
|
758
|
+
uri,
|
|
709
759
|
followAllRedirects: true,
|
|
710
|
-
timeout
|
|
760
|
+
timeout
|
|
711
761
|
}
|
|
712
762
|
if (this.caps[Capabilities.SIMPLEREST_POLL_HEADERS]) {
|
|
713
763
|
try {
|
|
@@ -735,6 +785,8 @@ module.exports = class SimpleRestContainer {
|
|
|
735
785
|
debug(`_runPolling: exeucting request hook failed - (${err.message})`)
|
|
736
786
|
return
|
|
737
787
|
}
|
|
788
|
+
this._addRequestCookies(pollConfig)
|
|
789
|
+
|
|
738
790
|
request(pollConfig, async (err, response, body) => {
|
|
739
791
|
if (err) {
|
|
740
792
|
debug(`_runPolling: rest request failed: ${err.message}, request: ${JSON.stringify(pollConfig)}`)
|
|
@@ -746,7 +798,7 @@ module.exports = class SimpleRestContainer {
|
|
|
746
798
|
}
|
|
747
799
|
} else if (body) {
|
|
748
800
|
debug(`_runPolling: got response code: ${response.statusCode}, body: ${botiumUtils.shortenJsonString(body)}`)
|
|
749
|
-
|
|
801
|
+
this._storeCookiesFromResponse(response)
|
|
750
802
|
try {
|
|
751
803
|
body = await this._parseResponseBody(body)
|
|
752
804
|
} catch (err) {
|
|
@@ -787,9 +839,9 @@ module.exports = class SimpleRestContainer {
|
|
|
787
839
|
const timeout = this._getCapValue(`${capPrefix}_TIMEOUT`) || this._getCapValue(Capabilities.SIMPLEREST_TIMEOUT)
|
|
788
840
|
const httpConfig = {
|
|
789
841
|
method: verb,
|
|
790
|
-
uri
|
|
842
|
+
uri,
|
|
791
843
|
followAllRedirects: true,
|
|
792
|
-
timeout
|
|
844
|
+
timeout
|
|
793
845
|
}
|
|
794
846
|
if (this.caps[`${capPrefix}_HEADERS`]) {
|
|
795
847
|
try {
|
|
@@ -808,8 +860,8 @@ module.exports = class SimpleRestContainer {
|
|
|
808
860
|
}
|
|
809
861
|
}
|
|
810
862
|
this._addRequestOptions(httpConfig)
|
|
811
|
-
|
|
812
863
|
await executeHook(this.caps, this.requestHooks[capPrefix], Object.assign({ requestOptions: httpConfig }, this.view))
|
|
864
|
+
this._addRequestCookies(httpConfig)
|
|
813
865
|
|
|
814
866
|
const retries = this._getCapValue(`${capPrefix}_RETRIES`)
|
|
815
867
|
debug(`_makeCall(${capPrefix}): rest request: ${JSON.stringify(httpConfig)}`)
|
|
@@ -826,4 +878,34 @@ module.exports = class SimpleRestContainer {
|
|
|
826
878
|
_.merge(httpConfig, this.caps[Capabilities.SIMPLEREST_EXTRA_OPTIONS])
|
|
827
879
|
}
|
|
828
880
|
}
|
|
881
|
+
|
|
882
|
+
_addRequestCookies (requestOptions) {
|
|
883
|
+
if (!this.caps[Capabilities.SIMPLEREST_COOKIE_REPLICATION] || !requestOptions) {
|
|
884
|
+
return
|
|
885
|
+
}
|
|
886
|
+
const url = new URL(requestOptions.uri)
|
|
887
|
+
if (!requestOptions.headers) {
|
|
888
|
+
requestOptions.headers = {}
|
|
889
|
+
}
|
|
890
|
+
requestOptions.headers.Cookie = requestOptions.headers.Cookie ? `${requestOptions.headers.Cookie}; ${this.cookies[url.host]}` : this.cookies[url.host]
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
_storeCookiesFromResponse (response) {
|
|
894
|
+
if (!this.caps[Capabilities.SIMPLEREST_COOKIE_REPLICATION] || !response) {
|
|
895
|
+
return
|
|
896
|
+
}
|
|
897
|
+
const responseCookies = response.headers['set-cookie']
|
|
898
|
+
if (!responseCookies) {
|
|
899
|
+
return
|
|
900
|
+
}
|
|
901
|
+
const host = _.get(response, 'request.uri.host')
|
|
902
|
+
let cookie
|
|
903
|
+
responseCookies.forEach(cookieString => {
|
|
904
|
+
cookie = cookie ? `${cookie}; ${cookieString}` : cookieString
|
|
905
|
+
})
|
|
906
|
+
|
|
907
|
+
if (cookie) {
|
|
908
|
+
this.cookies[host] = cookie
|
|
909
|
+
}
|
|
910
|
+
}
|
|
829
911
|
}
|
package/src/helpers/Utils.js
CHANGED
|
@@ -46,7 +46,7 @@ const toJsonWeak = (stringOrNot) => {
|
|
|
46
46
|
|
|
47
47
|
const optionalJson = (json) => {
|
|
48
48
|
const body = isJson(json)
|
|
49
|
-
return body ? { 'content-type': 'application/json', body
|
|
49
|
+
return body ? { 'content-type': 'application/json', body } : { 'content-type': 'text/plain', body: json }
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const shortenJsonString = (obj) => {
|
|
@@ -339,7 +339,7 @@ module.exports = class CompilerXlsx extends CompilerBase {
|
|
|
339
339
|
agg[varName] = varValues[varIndex][caseIndex] || null
|
|
340
340
|
return agg
|
|
341
341
|
}, {})
|
|
342
|
-
scriptResults.push({ header: { name: caseName }, values
|
|
342
|
+
scriptResults.push({ header: { name: caseName }, values })
|
|
343
343
|
}
|
|
344
344
|
} else {
|
|
345
345
|
const variableNames = []
|
|
@@ -370,7 +370,7 @@ module.exports = class CompilerXlsx extends CompilerBase {
|
|
|
370
370
|
}
|
|
371
371
|
rowindex += 1
|
|
372
372
|
|
|
373
|
-
scriptResults.push({ header: { name: caseName }, values
|
|
373
|
+
scriptResults.push({ header: { name: caseName }, values })
|
|
374
374
|
} else {
|
|
375
375
|
break
|
|
376
376
|
}
|
package/src/scripting/Convo.js
CHANGED
|
@@ -235,14 +235,14 @@ class Convo {
|
|
|
235
235
|
await this.runConversation(container, scriptingMemory, transcript)
|
|
236
236
|
await this._checkBotRepliesConsumed(container)
|
|
237
237
|
try {
|
|
238
|
-
await this.scriptingEvents.onConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory
|
|
238
|
+
await this.scriptingEvents.onConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory })
|
|
239
239
|
} catch (err) {
|
|
240
240
|
throw new TranscriptError(botiumErrorFromErr(`${this.header.name}: ${err.message}`, err), transcript)
|
|
241
241
|
}
|
|
242
242
|
if (transcript.err && container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
|
|
243
243
|
let assertConvoEndErr = null
|
|
244
244
|
try {
|
|
245
|
-
await this.scriptingEvents.assertConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory
|
|
245
|
+
await this.scriptingEvents.assertConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory })
|
|
246
246
|
} catch (err) {
|
|
247
247
|
assertConvoEndErr = botiumErrorFromErr(`${this.header.name}: ${err.message}`, err)
|
|
248
248
|
}
|
|
@@ -257,7 +257,7 @@ class Convo {
|
|
|
257
257
|
throw new TranscriptError(transcript.err, transcript)
|
|
258
258
|
}
|
|
259
259
|
try {
|
|
260
|
-
await this.scriptingEvents.assertConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory
|
|
260
|
+
await this.scriptingEvents.assertConvoEnd({ convo: this, convoStep: { stepTag: '#end' }, container, transcript, scriptingMemory })
|
|
261
261
|
} catch (err) {
|
|
262
262
|
transcript.err = botiumErrorFromErr(`${this.header.name}: ${err.message}`, err)
|
|
263
263
|
throw new TranscriptError(transcript.err, transcript)
|
|
@@ -307,9 +307,9 @@ class Convo {
|
|
|
307
307
|
transcriptStep.actual = meMsg
|
|
308
308
|
|
|
309
309
|
try {
|
|
310
|
-
await this.scriptingEvents.setUserInput({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep })
|
|
311
|
-
await this.scriptingEvents.onMeStart({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep })
|
|
312
|
-
await this.scriptingEvents.onMePrepare({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep })
|
|
310
|
+
await this.scriptingEvents.setUserInput({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep, transcriptSteps })
|
|
311
|
+
await this.scriptingEvents.onMeStart({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep, transcriptSteps })
|
|
312
|
+
await this.scriptingEvents.onMePrepare({ convo: this, convoStep, container, scriptingMemory, meMsg, transcript, transcriptStep, transcriptSteps })
|
|
313
313
|
|
|
314
314
|
await this._checkBotRepliesConsumed(container)
|
|
315
315
|
|
|
@@ -1192,7 +1192,7 @@ module.exports = class ScriptingProvider {
|
|
|
1192
1192
|
const node = {
|
|
1193
1193
|
sender: convoNode.sender,
|
|
1194
1194
|
key: randomize('0', 20),
|
|
1195
|
-
hash
|
|
1195
|
+
hash,
|
|
1196
1196
|
convoNodes: convoNodeValues,
|
|
1197
1197
|
convos: [_.cloneDeep(convoNodeHeader)],
|
|
1198
1198
|
childNodes: []
|
package/src/scripting/helper.js
CHANGED
|
@@ -494,7 +494,7 @@ const linesToScriptingMemories = (lines, columnMode = null) => {
|
|
|
494
494
|
agg[varName] = varValues[varIndex][caseIndex] || null
|
|
495
495
|
return agg
|
|
496
496
|
}, {})
|
|
497
|
-
const scriptingMemory = { header: { name: caseName }, values
|
|
497
|
+
const scriptingMemory = { header: { name: caseName }, values }
|
|
498
498
|
scriptingMemories.push(scriptingMemory)
|
|
499
499
|
}
|
|
500
500
|
} else {
|