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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botium-core",
3
- "version": "1.12.2",
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.16.7",
35
+ "@babel/runtime": "^7.17.9",
36
36
  "async": "^3.2.3",
37
- "body-parser": "^1.19.1",
38
- "boolean": "^3.1.4",
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.3",
41
+ "debug": "^4.3.4",
42
42
  "esprima": "^4.0.1",
43
- "express": "^4.17.2",
43
+ "express": "^4.17.3",
44
44
  "globby": "11.0.4",
45
- "ioredis": "^4.28.3",
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.34",
51
+ "mime-types": "^2.1.35",
52
52
  "mkdirp": "^1.0.4",
53
- "moment": "^2.29.1",
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.0",
65
+ "swagger-jsdoc": "^6.2.1",
66
66
  "swagger-ui-express": "^4.3.0",
67
67
  "uuid": "^8.3.2",
68
- "vm2": "^3.9.5",
68
+ "vm2": "^3.9.9",
69
69
  "write-yaml": "^1.0.0",
70
- "xlsx": "^0.17.5",
70
+ "xlsx": "^0.18.5",
71
71
  "xregexp": "^5.1.0",
72
- "yaml": "^1.10.2"
72
+ "yaml": "^2.0.1"
73
73
  },
74
74
  "devDependencies": {
75
- "@babel/core": "^7.16.12",
75
+ "@babel/core": "^7.17.9",
76
76
  "@babel/node": "^7.16.8",
77
- "@babel/plugin-transform-runtime": "^7.16.10",
77
+ "@babel/plugin-transform-runtime": "^7.17.0",
78
78
  "@babel/preset-env": "^7.16.11",
79
- "chai": "^4.3.4",
79
+ "chai": "^4.3.6",
80
80
  "chai-as-promised": "^7.1.1",
81
81
  "cross-env": "^7.0.3",
82
- "eslint": "^8.7.0",
83
- "eslint-config-standard": "^16.0.3",
84
- "eslint-plugin-import": "^2.25.4",
85
- "eslint-plugin-node": "^11.1.0",
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.0",
91
- "nock": "^13.2.2",
92
- "npm-check-updates": "^12.2.1",
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.66.0",
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: ${util.inspect(this.caps)}`)
113
- debug(`Build - Sources : ${util.inspect(this.sources)}`)
114
- debug(`Build - Envs : ${util.inspect(this.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 (this.tempDirectory) {
160
- rimraf(this.tempDirectory, (err) => {
161
- if (err) debug(`Cleanup temp dir ${this.tempDirectory} failed: ${util.inspect(err)}`)
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(this.tempDirectory, this.sources)
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(this.tempDirectory, this.sources)
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(this.tempDirectory, this.sources)
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, this.tempDirectory, repo, this.caps, this.envs)
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, this.tempDirectory, repo, this.caps, this.envs)
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, this.tempDirectory, repo, this.caps, this.envs)
361
+ return new PluginConnectorContainer(this.eventEmitter, tempDirectory, repo, this.caps, this.envs)
357
362
  }
358
363
  }
@@ -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 media = []
313
- const buttons = []
314
-
315
- const jsonPathsMedia = getAllCapValues(Capabilities.SIMPLEREST_MEDIA_JSONPATH, this.caps)
316
- jsonPathsMedia.forEach(jsonPath => {
317
- const responseMedia = jp.query(jsonPathRoot, jsonPath)
318
- if (responseMedia) {
319
- (_.isArray(responseMedia) ? _.flattenDeep(responseMedia) : [responseMedia]).forEach(m =>
320
- media.push({
321
- mediaUri: m,
322
- mimeType: mime.lookup(m) || 'application/unknown'
323
- })
324
- )
325
- debug(`found response media: ${util.inspect(media)}`)
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
- const jsonPathsButtons = getAllCapValues(Capabilities.SIMPLEREST_BUTTONS_JSONPATH, this.caps)
329
- jsonPathsButtons.forEach(jsonPath => {
330
- const responseButtons = jp.query(jsonPathRoot, jsonPath)
331
- if (responseButtons) {
332
- (_.isArray(responseButtons) ? _.flattenDeep(responseButtons) : [responseButtons]).forEach(b =>
333
- buttons.push({
334
- text: b
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
- debug(`found response buttons: ${util.inspect(buttons)}`)
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: uri,
758
+ uri,
709
759
  followAllRedirects: true,
710
- timeout: 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: uri,
842
+ uri,
791
843
  followAllRedirects: true,
792
- timeout: 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
  }
@@ -69,7 +69,7 @@ const tryLoadPlugin = (containermode, modulepath, args) => {
69
69
  source: 'src/containers/plugins/index.js',
70
70
  cause: {
71
71
  SECURITY_ALLOW_UNSAFE: caps[Capabilities.SECURITY_ALLOW_UNSAFE],
72
- mode: mode,
72
+ mode,
73
73
  ...cause
74
74
  }
75
75
  }
@@ -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: body } : { 'content-type': 'text/plain', body: json }
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: 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: values })
373
+ scriptResults.push({ header: { name: caseName }, values })
374
374
  } else {
375
375
  break
376
376
  }
@@ -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: 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: 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: 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: hash,
1195
+ hash,
1196
1196
  convoNodes: convoNodeValues,
1197
1197
  convos: [_.cloneDeep(convoNodeHeader)],
1198
1198
  childNodes: []
@@ -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: values }
497
+ const scriptingMemory = { header: { name: caseName }, values }
498
498
  scriptingMemories.push(scriptingMemory)
499
499
  }
500
500
  } else {
@@ -28,7 +28,7 @@ module.exports = class BaseCountAsserter {
28
28
  args
29
29
  },
30
30
  cause: {
31
- not: not,
31
+ not,
32
32
  expected: check,
33
33
  actual: count
34
34
  }