botium-core 1.15.10 → 1.15.13

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.
Files changed (84) hide show
  1. package/dist/botium-cjs.js +91 -51
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +91 -50
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +35 -40
  6. package/src/BotDriver.js +1 -1
  7. package/src/Events.js +1 -3
  8. package/src/containers/GridContainer.js +0 -4
  9. package/src/mocks/BotiumMockScripting.js +3 -0
  10. package/src/scripting/Convo.js +10 -0
  11. package/src/utils/boolean.js +39 -0
  12. package/test/compiler/compilercsv.spec.js +34 -0
  13. package/test/compiler/compilermarkdown.spec.js +11 -0
  14. package/test/compiler/compilertxt.spec.js +21 -0
  15. package/test/compiler/compilerxlsx.spec.js +27 -0
  16. package/test/compiler/precompilerjson.spec.js +1 -0
  17. package/test/compiler/precompilermarkdownrasa.spec.js +1 -0
  18. package/test/connectors/pluginconnectorcontainer.spec.js +1 -0
  19. package/test/connectors/simplerest.spec.js +3 -1
  20. package/test/convo/failure.spec.js +1 -0
  21. package/test/convo/fillAndApplyScriptingMemory.spec.js +56 -0
  22. package/test/convo/partialconvo.spec.js +3 -0
  23. package/test/convo/retry.spec.js +9 -0
  24. package/test/convo/retryasserter.spec.js +9 -0
  25. package/test/convo/transcript.spec.js +33 -0
  26. package/test/convo/tree.spec.js +5 -0
  27. package/test/driver/capabilities.spec.js +16 -0
  28. package/test/helpers/capabilitiesutils.spec.js +8 -0
  29. package/test/helpers/transcriptutils.spec.js +1 -0
  30. package/test/hooks/customhooks.spec.js +3 -0
  31. package/test/logichooks/hookfromsrc.spec.js +3 -0
  32. package/test/logichooks/textfromhook.spec.js +1 -0
  33. package/test/plugins/plugins.spec.js +3 -0
  34. package/test/scripting/asserters/buttonsAsserter.spec.js +15 -0
  35. package/test/scripting/asserters/cardsAsserter.spec.js +12 -0
  36. package/test/scripting/asserters/convoStepParameters.spec.js +11 -0
  37. package/test/scripting/asserters/entitiesAsserter.spec.js +1 -0
  38. package/test/scripting/asserters/entityValuesAsserter.spec.js +7 -0
  39. package/test/scripting/asserters/formsAsserter.spec.js +10 -0
  40. package/test/scripting/asserters/intentAsserter.spec.js +4 -0
  41. package/test/scripting/asserters/intentUniqueAsserter.spec.js +2 -0
  42. package/test/scripting/asserters/jsonpathAsserter.spec.js +25 -0
  43. package/test/scripting/asserters/mediaAsserter.spec.js +20 -0
  44. package/test/scripting/asserters/responseLengthAsserter.spec.js +4 -0
  45. package/test/scripting/asserters/textAsserter.spec.js +1 -0
  46. package/test/scripting/asserters/textContainsAllAsserter.spec.js +1 -0
  47. package/test/scripting/asserters/textContainsAnyAsserter.spec.js +1 -0
  48. package/test/scripting/asserters/textEqualsAsserter.spec.js +1 -0
  49. package/test/scripting/asserters/textRegexpAllAsserter.spec.js +1 -0
  50. package/test/scripting/asserters/textRegexpAnyAsserter.spec.js +1 -0
  51. package/test/scripting/asserters/textWildcardAllAsserter.spec.js +1 -0
  52. package/test/scripting/asserters/textWildcardAnyAsserter.spec.js +1 -0
  53. package/test/scripting/asserters/textWildcardExactAllAsserter.spec.js +1 -0
  54. package/test/scripting/asserters/textWildcardExactAnyAsserter.spec.js +1 -0
  55. package/test/scripting/asserters/werAsserter.spec.js +6 -0
  56. package/test/scripting/logichooks/convos/scripting_memory_resolved_args.convo.txt +11 -0
  57. package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +2 -0
  58. package/test/scripting/logichooks/localvsglobal.spec.js +1 -0
  59. package/test/scripting/logichooks/pauseLogic.spec.js +4 -0
  60. package/test/scripting/logichooks/setClearScriptingMemory.spec.js +17 -0
  61. package/test/scripting/logichooks/updateCustom.spec.js +2 -0
  62. package/test/scripting/matching/matchingmode.spec.js +48 -0
  63. package/test/scripting/scriptingModificator.spec.js +1 -0
  64. package/test/scripting/scriptingmemory/fillScriptingMemoryFromFile.spec.js +4 -0
  65. package/test/scripting/scriptingmemory/regexp.spec.js +1 -0
  66. package/test/scripting/scriptingmemory/useScriptingMemoryForAssertion.spec.js +3 -0
  67. package/test/scripting/txt/decompile.spec.js +20 -0
  68. package/test/scripting/userinputs/buttonInputConvos.spec.js +1 -0
  69. package/test/scripting/userinputs/defaultUserInputs.spec.js +13 -0
  70. package/test/scripting/userinputs/mediaInputConvos.spec.js +10 -0
  71. package/test/scripting/utteranceexpansion/associateByIndex.spec.js +2 -0
  72. package/test/security/allowUnsafe.spec.js +5 -0
  73. package/test/utils.spec.js +2 -0
  74. package/samples/postman/Botium Agent Sample.postman_collection.json +0 -834
  75. package/samples/postman/README.md +0 -5
  76. package/samples/postman/botiumFluent.js +0 -37
  77. package/src/grid/agent/AgentWorker.js +0 -204
  78. package/src/grid/agent/agent.js +0 -96
  79. package/src/grid/agent/agentworkerpool.js +0 -58
  80. package/src/grid/agent/routes.js +0 -353
  81. package/src/grid/agent/swagger.json +0 -327
  82. package/src/grid/agent/swaggerDef.json +0 -8
  83. package/src/grid/agent/views/index.html +0 -39
  84. package/test/grid/agent/client.js +0 -65
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botium-core",
3
- "version": "1.15.10",
3
+ "version": "1.15.13",
4
4
  "description": "The Selenium for Chatbots",
5
5
  "main": "index.js",
6
6
  "module": "dist/botium-es.js",
@@ -13,8 +13,6 @@
13
13
  "eslint": "eslint \"./src/**/*.js\" \"./test/**/*.js\"",
14
14
  "eslint-fix": "eslint --fix \"./src/**/*.js\" \"./test/**/*.js\"",
15
15
  "newpatch": "npm version patch",
16
- "agent": "node ./src/grid/agent/agent.js",
17
- "agent-jsdoc": "swagger-jsdoc -d ./src/grid/agent/swaggerDef.json -o ./src/grid/agent/swagger.json ./src/grid/agent/routes.js",
18
16
  "link": "npm link botium-connector-dialogflow botium-connector-webdriverio botium-connector-directline3 botium-connector-watson botium-connector-alexa-smapi botium-connector-echo",
19
17
  "test": "cross-env NODE_PATH=\"./test/plugins/plugindir/fromfolder:./test/plugins/plugindir/fromfile:./test/security/resources\" mocha \"./test/**/*.spec.js\"",
20
18
  "coverage:report": "nyc report --reporter=lcov npm test",
@@ -31,66 +29,63 @@
31
29
  },
32
30
  "homepage": "https://www.botium.ai",
33
31
  "dependencies": {
34
- "@babel/runtime": "^7.23.9",
35
- "async": "^3.2.5",
36
- "body-parser": "^1.20.2",
37
- "boolean": "^3.2.0",
32
+ "@babel/runtime": "^7.28.6",
33
+ "async": "^3.2.6",
34
+ "body-parser": "^2.2.2",
38
35
  "bottleneck": "^2.19.5",
39
- "csv-parse": "^5.5.3",
40
- "debug": "^4.3.4",
41
- "express": "^4.18.2",
36
+ "csv-parse": "^6.1.0",
37
+ "debug": "^4.4.3",
38
+ "express": "^5.2.1",
42
39
  "globby": "11.0.4",
43
- "ioredis": "^5.3.2",
40
+ "ioredis": "^5.10.0",
44
41
  "is-class": "^0.0.9",
45
42
  "is-json": "^2.0.1",
46
- "jsonpath": "^1.1.1",
47
- "lodash": "^4.17.21",
48
- "markdown-it": "^14.0.0",
49
- "mime-types": "^2.1.35",
43
+ "jsonpath": "^1.3.0",
44
+ "lodash": "^4.17.23",
45
+ "markdown-it": "^14.1.1",
46
+ "mime-types": "^3.0.2",
50
47
  "mkdirp": "^3.0.1",
51
48
  "moment": "^2.30.1",
52
- "moment-timezone": "^0.5.45",
49
+ "moment-timezone": "^0.6.0",
53
50
  "mustache": "^4.2.0",
54
51
  "promise-retry": "^2.0.1",
55
52
  "promise.allsettled": "^1.0.7",
56
53
  "randomatic": "^3.1.1",
57
- "rimraf": "^5.0.5",
54
+ "rimraf": "^6.1.3",
58
55
  "sanitize-filename": "^1.6.3",
59
56
  "slugify": "^1.6.6",
60
- "socket.io": "^4.7.4",
61
- "socket.io-client": "^4.7.4",
57
+ "socket.io": "^4.8.3",
58
+ "socket.io-client": "^4.8.3",
62
59
  "socketio-auth": "^0.1.1",
63
- "swagger-jsdoc": "^6.2.8",
64
- "swagger-ui-express": "^5.0.0",
65
- "tinyglobby": "^0.2.10",
66
- "undici": "^6.21.0",
60
+ "tinyglobby": "^0.2.15",
61
+ "undici": "^7.22.0",
67
62
  "uuid": "^9.0.1",
68
63
  "word-error-rate": "0.0.7",
69
64
  "write-yaml": "^1.0.0",
70
65
  "xlsx": "^0.18.5",
71
- "xregexp": "^5.1.1",
72
- "yaml": "^2.3.4"
66
+ "xregexp": "^5.1.2",
67
+ "yaml": "^2.8.2"
73
68
  },
74
69
  "devDependencies": {
75
- "@babel/core": "^7.23.9",
76
- "@babel/node": "^7.23.9",
77
- "@babel/plugin-transform-runtime": "^7.23.9",
78
- "@babel/preset-env": "^7.23.9",
70
+ "@babel/core": "^7.29.0",
71
+ "@babel/node": "^7.29.0",
72
+ "@babel/plugin-transform-runtime": "^7.29.0",
73
+ "@babel/preset-env": "^7.29.0",
79
74
  "chai": "4.3.10",
80
- "chai-as-promised": "^7.1.1",
81
- "cross-env": "^7.0.3",
82
- "eslint": "^8.56.0",
75
+ "chai-as-promised": "^7.1.2",
76
+ "cross-env": "^10.1.0",
77
+ "eslint": "^8.57.1",
83
78
  "eslint-config-standard": "^17.1.0",
84
- "eslint-plugin-import": "^2.29.1",
85
- "eslint-plugin-mocha": "^10.2.0",
79
+ "eslint-plugin-import": "^2.32.0",
80
+ "eslint-plugin-mocha": "^10.5.0",
86
81
  "eslint-plugin-n": "^16.6.2",
87
- "eslint-plugin-promise": "^6.1.1",
82
+ "eslint-plugin-promise": "^6.6.0",
88
83
  "eslint-plugin-standard": "^4.1.0",
89
- "mocha": "^10.3.0",
90
- "nock": "^14.0.0-beta.19",
91
- "npm-check-updates": "^16.14.15",
92
- "nyc": "^15.1.0",
93
- "rollup": "2.79.1",
84
+ "mocha": "^11.7.5",
85
+ "nock": "^14.0.11",
86
+ "npm-check-updates": "^19.6.3",
87
+ "nyc": "^18.0.0",
88
+ "rollup": "2.80.0",
94
89
  "rollup-plugin-babel": "^4.4.0",
95
90
  "rollup-plugin-commonjs": "^10.1.0",
96
91
  "rollup-plugin-json": "^4.0.0",
package/src/BotDriver.js CHANGED
@@ -8,7 +8,7 @@ const sanitize = require('sanitize-filename')
8
8
  const moment = require('moment')
9
9
  const randomize = require('randomatic')
10
10
  const _ = require('lodash')
11
- const { boolean } = require('boolean')
11
+ const { boolean } = require('./utils/boolean')
12
12
  const EventEmitter = require('events')
13
13
  const debug = require('debug')('botium-core-BotDriver')
14
14
 
package/src/Events.js CHANGED
@@ -20,7 +20,5 @@ module.exports = {
20
20
  MESSAGE_RECEIVEDFROMBOT: 'MESSAGE_RECEIVEDFROMBOT',
21
21
  MESSAGE_RECEIVEFROMBOT_ERROR: 'MESSAGE_RECEIVEFROMBOT_ERROR',
22
22
  MESSAGE_ATTACHMENT: 'MESSAGE_ATTACHMENT',
23
- MESSAGE_TRANSCRIPT: 'MESSAGE_TRANSCRIPT',
24
- // Botium Agent Events
25
- TOOMUCHWORKERS_ERROR: 'TOOMUCHWORKERS_ERROR'
23
+ MESSAGE_TRANSCRIPT: 'MESSAGE_TRANSCRIPT'
26
24
  }
@@ -49,10 +49,6 @@ module.exports = class GridContainer extends BaseContainer {
49
49
  debug(`unauthorized ${err.message}`)
50
50
  socketComplete(`Grid Access not authorized: ${err.message}`)
51
51
  })
52
- this.socket.on(Events.TOOMUCHWORKERS_ERROR, (err) => {
53
- debug(`TOOMUCHWORKERS_ERROR ${err.message}`)
54
- socketComplete(`Grid Access not possible: ${err.message}`)
55
- })
56
52
  this.socket.on(Events.CONTAINER_BUILT, () => {
57
53
  debug(Events.CONTAINER_BUILT)
58
54
  socketComplete()
@@ -5,18 +5,21 @@ class BotiumMockAsserter {
5
5
  this.name = fromJson.name
6
6
  this.args = _.cloneDeep(fromJson.args)
7
7
  this.not = fromJson.not
8
+ this.resolvedArgs = fromJson.resolvedArgs || null
8
9
  }
9
10
  }
10
11
  class BotiumMockUserInput {
11
12
  constructor (fromJson = {}) {
12
13
  this.name = fromJson.name
13
14
  this.args = _.cloneDeep(fromJson.args)
15
+ this.resolvedArgs = fromJson.resolvedArgs || null
14
16
  }
15
17
  }
16
18
  class BotiumMockLogicHook {
17
19
  constructor (fromJson = {}) {
18
20
  this.name = fromJson.name
19
21
  this.args = _.cloneDeep(fromJson.args)
22
+ this.resolvedArgs = fromJson.resolvedArgs || null
20
23
  }
21
24
  }
22
25
 
@@ -703,6 +703,16 @@ class Convo {
703
703
  } finally {
704
704
  if (convoStep.sender !== 'begin' && convoStep.sender !== 'end' && !skipTranscriptStep) {
705
705
  transcriptStep.scriptingMemory = Object.assign({}, scriptingMemory)
706
+ if (container.caps[Capabilities.SCRIPTING_ENABLE_MEMORY] && transcriptStep.expected) {
707
+ const _resolveItemArgs = (items) => {
708
+ (items || []).forEach(item => {
709
+ item.resolvedArgs = ScriptingMemory.applyToArgs(item.args, scriptingMemory, container.caps)
710
+ })
711
+ }
712
+ _resolveItemArgs(transcriptStep.expected.asserters)
713
+ _resolveItemArgs(transcriptStep.expected.logicHooks)
714
+ _resolveItemArgs(transcriptStep.expected.userInputs)
715
+ }
706
716
  transcriptStep.stepEnd = new Date()
707
717
  transcriptSteps.push(transcriptStep)
708
718
  }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Converts a value to a boolean.
3
+ * Similar to the 'boolean' npm package implementation.
4
+ *
5
+ * @param {*} value - The value to convert to boolean
6
+ * @returns {boolean} The boolean representation of the value
7
+ */
8
+ function boolean (value) {
9
+ // Handle null and undefined
10
+ if (value == null) {
11
+ return false
12
+ }
13
+
14
+ // Handle boolean values
15
+ if (typeof value === 'boolean') {
16
+ return value
17
+ }
18
+
19
+ // Handle numbers
20
+ if (typeof value === 'number') {
21
+ return value !== 0 && !isNaN(value)
22
+ }
23
+
24
+ // Handle strings
25
+ if (typeof value === 'string') {
26
+ const normalized = value.trim().toLowerCase()
27
+ if (normalized === 'true' || normalized === 'yes' || normalized === 'on' || normalized === '1') {
28
+ return true
29
+ }
30
+ if (normalized === 'false' || normalized === 'no' || normalized === 'off' || normalized === '0' || normalized === '') {
31
+ return false
32
+ }
33
+ }
34
+
35
+ // For all other values, use JavaScript's truthiness
36
+ return Boolean(value)
37
+ }
38
+
39
+ module.exports = { boolean }
@@ -82,6 +82,7 @@ describe('compiler.compilercsv', function () {
82
82
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
83
83
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
84
84
  })
85
+
85
86
  it('should read different sequence and extra row', async function () {
86
87
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_sequence_and_extra_row.csv'))
87
88
  const context = buildContext()
@@ -100,6 +101,7 @@ describe('compiler.compilercsv', function () {
100
101
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
101
102
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
102
103
  })
104
+
103
105
  it('should read by cap', async function () {
104
106
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_sequence_and_extra_row_no_def_colname.csv'))
105
107
  const context = buildContext()
@@ -118,6 +120,7 @@ describe('compiler.compilercsv', function () {
118
120
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
119
121
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
120
122
  })
123
+
121
124
  it('should read by index', async function () {
122
125
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_sequence_and_extra_row_no_def_colname.csv'))
123
126
  const context = buildContext()
@@ -136,6 +139,7 @@ describe('compiler.compilercsv', function () {
136
139
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
137
140
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
138
141
  })
142
+
139
143
  it('should read by index, no header', async function () {
140
144
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_no_header.csv'))
141
145
  const context = buildContext()
@@ -152,6 +156,7 @@ describe('compiler.compilercsv', function () {
152
156
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
153
157
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
154
158
  })
159
+
155
160
  it('should read more convos', async function () {
156
161
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_more_convos.csv'))
157
162
  const context = buildContext()
@@ -170,6 +175,7 @@ describe('compiler.compilercsv', function () {
170
175
  assert.equal(context.convos[1].conversation[1].messageText, 'test 4')
171
176
  assert.equal(context.convos[1].conversation[1].sender, 'bot')
172
177
  })
178
+
173
179
  it('should read no text', async function () {
174
180
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_sender_no_text.csv'))
175
181
  const context = buildContext()
@@ -185,6 +191,7 @@ describe('compiler.compilercsv', function () {
185
191
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
186
192
  })
187
193
  })
194
+
188
195
  describe('QUESTION_ANSWER mode', function () {
189
196
  it('should read basic case', async function () {
190
197
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_basic.csv'))
@@ -200,6 +207,7 @@ describe('compiler.compilercsv', function () {
200
207
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
201
208
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
202
209
  })
210
+
203
211
  it('should read different sequence', async function () {
204
212
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_sequence.csv'))
205
213
  const context = buildContext()
@@ -217,6 +225,7 @@ describe('compiler.compilercsv', function () {
217
225
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
218
226
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
219
227
  })
228
+
220
229
  it('should read by name', async function () {
221
230
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_sequence_no_def_colname.csv'))
222
231
  const context = buildContext()
@@ -234,6 +243,7 @@ describe('compiler.compilercsv', function () {
234
243
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
235
244
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
236
245
  })
246
+
237
247
  it('should read by index', async function () {
238
248
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_sequence_no_def_colname.csv'))
239
249
  const context = buildContext()
@@ -251,6 +261,7 @@ describe('compiler.compilercsv', function () {
251
261
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
252
262
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
253
263
  })
264
+
254
265
  it('should read by index, no header', async function () {
255
266
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_no_header.csv'))
256
267
  const context = buildContext()
@@ -267,6 +278,7 @@ describe('compiler.compilercsv', function () {
267
278
  assert.equal(context.convos[0].conversation[1].messageText, 'test 2')
268
279
  assert.equal(context.convos[0].conversation[1].sender, 'bot')
269
280
  })
281
+
270
282
  it('should read more convos', async function () {
271
283
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_more_convos.csv'))
272
284
  const context = buildContext()
@@ -285,6 +297,7 @@ describe('compiler.compilercsv', function () {
285
297
  assert.equal(context.convos[1].conversation[1].messageText, 'test 4')
286
298
  assert.equal(context.convos[1].conversation[1].sender, 'bot')
287
299
  })
300
+
288
301
  it('should read user and bot columns', async function () {
289
302
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_column_me_bot.csv'))
290
303
  const context = buildContext()
@@ -374,6 +387,7 @@ describe('compiler.compilercsv', function () {
374
387
  assert.lengthOf(context.convos, 0)
375
388
  })
376
389
  })
390
+
377
391
  describe('Convo mode', function () {
378
392
  it('should not read oldscool single column format', async function () {
379
393
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_singlecolumn.csv'))
@@ -385,6 +399,7 @@ describe('compiler.compilercsv', function () {
385
399
  compiler.Compile(scriptBuffer, 'SCRIPTING_TYPE_CONVO')
386
400
  assert.lengthOf(context.utterances, 0)
387
401
  })
402
+
388
403
  it('should not parse multi column uttrances as convos ???', async function () {
389
404
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn3col.csv'))
390
405
  const context = buildContext()
@@ -399,6 +414,7 @@ describe('compiler.compilercsv', function () {
399
414
  assert.equal(err.message, 'Failed to parse conversation. Section "goodbye" unknown.')
400
415
  }
401
416
  })
417
+
402
418
  it('should not parse multi column uttrances as convos ??? 2', async function () {
403
419
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn5col.csv'))
404
420
  const context = buildContext()
@@ -413,6 +429,7 @@ describe('compiler.compilercsv', function () {
413
429
  assert.equal(err.message, 'Failed to parse conversation. Section "goodbye" unknown.')
414
430
  }
415
431
  })
432
+
416
433
  it('should NOT read liveperson format with SCRIPTING_CSV_UTTERANCE_STARTROW???', async function () {
417
434
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
418
435
  const context = buildContext()
@@ -429,6 +446,7 @@ describe('compiler.compilercsv', function () {
429
446
  assert.equal(err.message, 'Failed to parse conversation. Section "DisplayName" unknown.')
430
447
  }
431
448
  })
449
+
432
450
  it('should NOT read liveperson format with SCRIPTING_CSV_STARTROWHEADER', async function () {
433
451
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
434
452
  const context = buildContext()
@@ -447,6 +465,7 @@ describe('compiler.compilercsv', function () {
447
465
  })
448
466
  })
449
467
  })
468
+
450
469
  describe('In non-legacy mode', function () {
451
470
  describe('Utterance mode', function () {
452
471
  it('should read oldscool single column format', async function () {
@@ -466,6 +485,7 @@ describe('compiler.compilercsv', function () {
466
485
  utterances: ['hello', 'hi']
467
486
  })
468
487
  })
488
+
469
489
  it('BUG, 3 column utterance is not well supported', async function () {
470
490
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn3col.csv'))
471
491
  const context = buildContext()
@@ -480,6 +500,7 @@ describe('compiler.compilercsv', function () {
480
500
  assert.lengthOf(context.utterances, 0)
481
501
  assert.lengthOf(context.convos, 0)
482
502
  })
503
+
483
504
  it('should read multi column format 5 col', async function () {
484
505
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn5col.csv'))
485
506
  const context = buildContext()
@@ -501,6 +522,7 @@ describe('compiler.compilercsv', function () {
501
522
  ]
502
523
  })
503
524
  })
525
+
504
526
  it('should read liveperson format with SCRIPTING_CSV_STARTROW', async function () {
505
527
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
506
528
  const context = buildContext()
@@ -523,6 +545,7 @@ describe('compiler.compilercsv', function () {
523
545
  ]
524
546
  })
525
547
  })
548
+
526
549
  it('should read liveperson format 2 with SCRIPTING_CSV_STARTROW', async function () {
527
550
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson2.csv'))
528
551
  const context = buildContext()
@@ -537,6 +560,7 @@ describe('compiler.compilercsv', function () {
537
560
  compiler.Compile(scriptBuffer, 'SCRIPTING_TYPE_UTTERANCES')
538
561
  assertLivepersonV2(context)
539
562
  })
563
+
540
564
  it('should read liveperson format with SCRIPTING_CSV_STARTROW without stop', async function () {
541
565
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
542
566
  const context = buildContext()
@@ -551,6 +575,7 @@ describe('compiler.compilercsv', function () {
551
575
  // description fields are pared as utterances. even metaintents
552
576
  assert.lengthOf(context.utterances, 21)
553
577
  })
578
+
554
579
  it('should read liveperson format with SCRIPTING_CSV_STARTROWHEADER', async function () {
555
580
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
556
581
  const context = buildContext()
@@ -574,6 +599,7 @@ describe('compiler.compilercsv', function () {
574
599
  ]
575
600
  })
576
601
  })
602
+
577
603
  it('should read liveperson format 2 with SCRIPTING_CSV_STARTROWHEADER', async function () {
578
604
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson2.csv'))
579
605
  const context = buildContext()
@@ -589,6 +615,7 @@ describe('compiler.compilercsv', function () {
589
615
  compiler.Compile(scriptBuffer, 'SCRIPTING_TYPE_UTTERANCES')
590
616
  assertLivepersonV2(context)
591
617
  })
618
+
592
619
  it('should read liveperson format with SCRIPTING_CSV_STARTROWHEADER 2', async function () {
593
620
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
594
621
  const context = buildContext()
@@ -612,6 +639,7 @@ describe('compiler.compilercsv', function () {
612
639
  ]
613
640
  })
614
641
  })
642
+
615
643
  it('should read liveperson format 2 with SCRIPTING_CSV_STARTROWHEADER 2', async function () {
616
644
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson2.csv'))
617
645
  const context = buildContext()
@@ -627,6 +655,7 @@ describe('compiler.compilercsv', function () {
627
655
  compiler.Compile(scriptBuffer, 'SCRIPTING_TYPE_UTTERANCES')
628
656
  assertLivepersonV2(context)
629
657
  })
658
+
630
659
  it('should work with variable length csv', async function () {
631
660
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_variable_row_len.csv'))
632
661
  const context = buildContext()
@@ -645,6 +674,7 @@ describe('compiler.compilercsv', function () {
645
674
  })
646
675
  })
647
676
  })
677
+
648
678
  describe('Convo mode', function () {
649
679
  it('should not read oldscool single column format', async function () {
650
680
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_singlecolumn.csv'))
@@ -658,6 +688,7 @@ describe('compiler.compilercsv', function () {
658
688
  compiler.Compile(scriptBuffer, 'SCRIPTING_TYPE_CONVO')
659
689
  assert.lengthOf(context.utterances, 0)
660
690
  })
691
+
661
692
  it('BUG, 3 column utterance is not well supported', async function () {
662
693
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn3col.csv'))
663
694
  const context = buildContext()
@@ -677,6 +708,7 @@ describe('compiler.compilercsv', function () {
677
708
  assert.equal(err.message, 'Failed to parse conversation. Section "goodbye" unknown.')
678
709
  }
679
710
  })
711
+
680
712
  it('should not parse multi column uttrances as convos', async function () {
681
713
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_multicolumn5col.csv'))
682
714
  const context = buildContext()
@@ -690,6 +722,7 @@ describe('compiler.compilercsv', function () {
690
722
  assert.lengthOf(context.utterances, 0)
691
723
  assert.lengthOf(context.convos, 0)
692
724
  })
725
+
693
726
  it('should NOT read liveperson format with SCRIPTING_CSV_UTTERANCE_STARTROW', async function () {
694
727
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
695
728
  const context = buildContext()
@@ -704,6 +737,7 @@ describe('compiler.compilercsv', function () {
704
737
  assert.lengthOf(context.utterances, 0)
705
738
  assert.lengthOf(context.convos, 0)
706
739
  })
740
+
707
741
  it('should NOT read liveperson format with SCRIPTING_CSV_STARTROWHEADER', async function () {
708
742
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'utterances_liveperson.csv'))
709
743
  const context = buildContext()
@@ -116,6 +116,7 @@ describe('compiler.compilermarkdown', function () {
116
116
  }
117
117
  assert.fail('should have failed')
118
118
  })
119
+
119
120
  describe('negating', function () {
120
121
  it('should read ! as not', async function () {
121
122
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_exclamation.md'))
@@ -130,6 +131,7 @@ describe('compiler.compilermarkdown', function () {
130
131
  assert.equal(context.convos[0].conversation[1].not, true)
131
132
  assert.equal(context.convos[0].conversation[1].asserters[0].not, true)
132
133
  })
134
+
133
135
  it('should read !! as !', async function () {
134
136
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_two_exclamation.md'))
135
137
  const context = buildContext()
@@ -141,6 +143,7 @@ describe('compiler.compilermarkdown', function () {
141
143
  assert.equal(context.convos[0].conversation[1].messageText, '!hello meat bag')
142
144
  assert.equal(context.convos[0].conversation[1].not, false)
143
145
  })
146
+
144
147
  it('should read n*! as (n-1)*!', async function () {
145
148
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_four_exclamation.md'))
146
149
  const context = buildContext()
@@ -153,6 +156,7 @@ describe('compiler.compilermarkdown', function () {
153
156
  assert.equal(context.convos[0].conversation[1].messageText, '!!!hello meat bag')
154
157
  assert.equal(context.convos[0].conversation[1].not, false)
155
158
  })
159
+
156
160
  it('should read ! as ! in second line', async function () {
157
161
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_exclamation_secline.md'))
158
162
  const context = buildContext()
@@ -165,6 +169,7 @@ describe('compiler.compilermarkdown', function () {
165
169
  assert.equal(context.convos[0].conversation[1].not, true)
166
170
  })
167
171
  })
172
+
168
173
  describe('optional', function () {
169
174
  it('should read ? as optional', async function () {
170
175
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_question.md'))
@@ -179,6 +184,7 @@ describe('compiler.compilermarkdown', function () {
179
184
  assert.equal(context.convos[0].conversation[1].optional, true)
180
185
  assert.equal(context.convos[0].conversation[1].asserters[0].optional, true)
181
186
  })
187
+
182
188
  it('should fail if not all item optional in the same block', async function () {
183
189
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_question_invalid.md'))
184
190
  const context = buildContext()
@@ -194,6 +200,7 @@ describe('compiler.compilermarkdown', function () {
194
200
  assert.equal(err.message, 'Failed to parse conversation. All element in convo step has to be optional or not optional: ["?hello meat bag","BUTTONS checkbutton|checkbutton2"]')
195
201
  }
196
202
  })
203
+
197
204
  it('should read ?? as ?', async function () {
198
205
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_two_question.md'))
199
206
  const context = buildContext()
@@ -205,6 +212,7 @@ describe('compiler.compilermarkdown', function () {
205
212
  assert.equal(context.convos[0].conversation[1].messageText, '?hello meat bag')
206
213
  assert.equal(context.convos[0].conversation[1].optional, false)
207
214
  })
215
+
208
216
  it('should read n*? as (n-1)*?', async function () {
209
217
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_four_question.md'))
210
218
  const context = buildContext()
@@ -217,6 +225,7 @@ describe('compiler.compilermarkdown', function () {
217
225
  assert.equal(context.convos[0].conversation[1].messageText, '???hello meat bag')
218
226
  assert.equal(context.convos[0].conversation[1].optional, false)
219
227
  })
228
+
220
229
  it('should read ? as ? in second line', async function () {
221
230
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_question_secline.md'))
222
231
  const context = buildContext()
@@ -229,6 +238,7 @@ describe('compiler.compilermarkdown', function () {
229
238
  assert.equal(context.convos[0].conversation[1].optional, true)
230
239
  })
231
240
  })
241
+
232
242
  describe('optional and negate', function () {
233
243
  it('should read ?! as optional and not', async function () {
234
244
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_question_exclamation.md'))
@@ -242,6 +252,7 @@ describe('compiler.compilermarkdown', function () {
242
252
  assert.equal(context.convos[0].conversation[1].optional, true)
243
253
  assert.equal(context.convos[0].conversation[1].not, true)
244
254
  })
255
+
245
256
  it('should read ??! as ?!', async function () {
246
257
  const scriptBuffer = fs.readFileSync(path.resolve(__dirname, CONVOS_DIR, 'convos_with_two_question_exclamation.md'))
247
258
  const context = buildContext()