├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bin
└── botium-bindings.js
├── docs
├── architecture_nodocker.png
├── architecture_nodocker.xml
├── architecture_withdocker.png
├── architecture_withdocker.xml
├── botium-logo.png
├── manual
│ ├── ide_chat.png
│ └── ide_savetestcase.png
├── screenshots
│ ├── chat.png
│ └── ide_demo.png
├── testmybot_logo.jpg.jpg
├── testmybot_logo.pdf
├── testmybot_logo.png.png
├── testmybot_logo_fbheader.png
└── testmybot_logo_square.png
├── index.js
├── package.json
├── report.js
├── rollup.config.js
├── samples
└── hello
│ ├── botium.json
│ ├── package.json
│ └── spec
│ ├── botium.spec.js
│ └── convo
│ ├── give_me_a_picture.convo.txt
│ ├── shopping_cart.convo.txt
│ ├── should_fail.convo.txt
│ └── should_fail_delivery.convo.txt
└── src
├── BotiumBindings.js
├── cli
└── index.js
├── helpers
├── jasmine.js
├── jest.js
└── mocha.js
└── metrics.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules/*
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "extends": "standard"
3 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | botiumwork
61 | dist
62 | package-lock.json
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Guidelines for posting issues
2 |
3 | * Please review the [Troubleshooting Guide in the Botium Wiki](https://github.com/codeforequity-at/botium-core/wiki/Troubleshooting)
4 | * In case you have some troubles, please __ALWAYS__ attach the debug output from Botium (see "Enable Logging" in the Troubleshooting Guide)
5 | * Please don't post any secret information (like access keys for Dialogflow or IBM Watson)
6 |
7 | # Guidelines for code contributions
8 |
9 | Of course, code contributions are welcome!
10 |
11 | * Please fork the repository
12 | * Please create an issue and refer to it in the pull request
13 | * The NPM script "npm run build" has to succeed before posting a pull request
14 | ** it will enforce eslint and rollup build
15 |
16 | These points are subject to possible change at any time.
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Code For Equity
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Botium Bindings
2 | ===============
3 |
4 | [](https://nodei.co/npm/botium-bindings/)
5 |
6 | [ ](https://app.codeship.com/projects/225703)
7 | [](https://badge.fury.io/js/botium-bindings)
8 | []()
9 | [](https://botium-docs.readthedocs.io/)
10 |
11 | **UPDATE 2020/11/05:** Botium has a FREE, hosted plan available! The new Botium Box Mini is our ❤️ to the community. [Take it for a test drive 🚗 ...](https://www.botium.ai/pricing/)
12 |
13 | [](https://www.youtube.com/watch?v=ciVxojvRfng "Botium Box Mini")
14 |
15 | __This project was formerly known as "TestMyBot" - same scope, different name__
16 |
17 | Botium is the Selenium for chatbots. Botium Bindings is the glue to bind Botium to test runners like Mocha, Jasmine and Jest.
18 |
19 | # Documentation
20 |
21 | See [here](https://botium-docs.readthedocs.io/) for Botium documentation.
22 |
--------------------------------------------------------------------------------
/bin/botium-bindings.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const yargsCmd = require('yargs')
3 |
4 | const handleConfig = (argv) => {
5 | argv.verbose = argv.v = process.env.BOTIUM_VERBOSE === '1' || argv.verbose
6 |
7 | if (argv.verbose) {
8 | require('debug').enable('botium*')
9 | }
10 |
11 | return true
12 | }
13 |
14 | const wrapHandler = (builder) => {
15 | const origHandler = builder.handler
16 | builder.handler = (argv) => {
17 | if (handleConfig(argv)) {
18 | origHandler(argv)
19 | }
20 | }
21 | return builder
22 | }
23 |
24 | yargsCmd.usage('Botium Bindings\n\nUsage: $0 [options]') // eslint-disable-line
25 | .help('help').alias('help', 'h')
26 | .version('version', require('../package.json').version).alias('version', 'V')
27 | .showHelpOnFail(true)
28 | .strict(true)
29 | .demandCommand(1, 'You need at least one command before moving on')
30 | .command(wrapHandler(require('../src/cli')))
31 | .option('verbose', {
32 | alias: 'v',
33 | describe: 'Enable verbose output (also read from env variable "BOTIUM_VERBOSE" - "1" means verbose)',
34 | default: false
35 | })
36 | .argv
37 |
--------------------------------------------------------------------------------
/docs/architecture_nodocker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/architecture_nodocker.png
--------------------------------------------------------------------------------
/docs/architecture_nodocker.xml:
--------------------------------------------------------------------------------
1 | 5Vhbb9s6DP41eYzhS+ykj2m7bAc4OyjQA2x7KhRbtrXKliHLSbpfP+rmxJc0aZsOBdagsElJtvh9JEV6EtwUu88cVflXlmA68d1kNwluJ77vuW4EF6l50prIW2hFxkliJu0V9+QXtiuNtiEJrjsTBWNUkKqrjFlZ4lh0dIhztu1OSxntvrVCGR4o7mNEh9pvJBG51i78aK//gkmW2zd70ZUeWaP4MeOsKc37Jn6Qqj89XCD7LGNonaOEbQ9UwadJcMMZE/qu2N1gKrG1sOl1qyOj7b45LsU5C+SYXLFBtMF2y2pj4smCASsAdxCuYbeVVMaUNfCA621OBL6vUCyVW3AF0OWioCB5cDvcjNnfBnOBdwcqs7nPmBVY8CeYYkbnZsV2z0IwN9jlBwwErlEiw3zWPmpvPdwYAI6g550GQ5JbnW9Y66JobZ/gPmtwGBlDTOQs3AEAXjQCgOdfAIAXOcPLyT+f/T9ibXDaWuvwpFAJ41pdl3Wlc44LGmSFlOywjAlpHYFM8i9aY3rHaiIIK2F8zYRgxcGEJSWZHBCssk8GKRcCxKU0wl/VAsFUJyMZchIMim01BX8SElJ/1VSUoaSGO9/1pNkuoLlalglnJJlSljGnKrO3UmH9Muy4pTd0y3CEp/ACNM0+Kk11y5NmwtmSR1LghCCH8UyyBXIlZbiPWVGwUpIl8qZYwzWR/3BsrP6D49P5WT8oxupNpgh13Wo37Y9ckM/gqsNnFA74XPjvw6d3XtzpY1Fyl6A6l5wp4SDD1IKzR3zDKOOgKVkpqU8JpVYFh2/oyh/oaY/nGLDD/PWOYF2u2GWyBHJYmpIYQ5Ru4FI7Mdj8UOWwpwekA/IBgrlMENXbvMDR6Lndk2LsqJiNxOTiEhyeEZQngR3E5AG3R0AfY7zPREwEJztnLatAxfAFsG5BM1gHI/lvNnfCIdpz32rfhPf8jJO5TJay9FX1GaprEivEEBdD9QHSeEfEdxlcztwPjfxDyS5EqpbvMIfEpuJFBSEAyZ++Hwo/TpV8NWt4bKtrkwFgbxm2mUWrcNIpzJ+tDJ47cDimcHRuuuX8GAPmDXeMyDO1ja1eFTYLekGjzTGrDuvr3oPag9I6Tj/6NAaDBymHaM0+z0cW7+cjlm/vdXzP/h6+r/xuUvbejW9/2K2soBhfM/YI2q+4rnGZQcj67vLun6MlU8Ia6EwM+3+goQt6AeG5V4NMOsp0dIn+JjodIu/d4HlhF4D50P72a8LFW57wjBTx+gavhfeDNHjW1T5y65CakF1zqA4d6BL6XZ7IcYFl35Cup2oSKWWHUPGf064G8jYWcqJ6kVkBmf1o0/ACuo40gcOmIfRGcvQz6fjsyB0WnJ1OWZd+FkyNY49psFF0PZjjmvwycauYbgSwqb5FymFk6KM4FcdLUogPwP9/KdxOZ6CpZG5XpobXk/BW9iRA5r3ZiGdl8543R5IZ7bVz0UhSGQmzV0QZiPvPk/rY2n8DDj79Bg==
--------------------------------------------------------------------------------
/docs/architecture_withdocker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/architecture_withdocker.png
--------------------------------------------------------------------------------
/docs/architecture_withdocker.xml:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/docs/botium-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/botium-logo.png
--------------------------------------------------------------------------------
/docs/manual/ide_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/manual/ide_chat.png
--------------------------------------------------------------------------------
/docs/manual/ide_savetestcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/manual/ide_savetestcase.png
--------------------------------------------------------------------------------
/docs/screenshots/chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/screenshots/chat.png
--------------------------------------------------------------------------------
/docs/screenshots/ide_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/screenshots/ide_demo.png
--------------------------------------------------------------------------------
/docs/testmybot_logo.jpg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/testmybot_logo.jpg.jpg
--------------------------------------------------------------------------------
/docs/testmybot_logo.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/testmybot_logo.pdf
--------------------------------------------------------------------------------
/docs/testmybot_logo.png.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/testmybot_logo.png.png
--------------------------------------------------------------------------------
/docs/testmybot_logo_fbheader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/testmybot_logo_fbheader.png
--------------------------------------------------------------------------------
/docs/testmybot_logo_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforequity-at/botium-bindings/9e7a69b83914924726559fbe611eb4080437b13c/docs/testmybot_logo_square.png
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./src/BotiumBindings')
2 |
3 | module.exports.helper = {
4 | jasmine: () => require('./src/helpers/jasmine'),
5 | jest: () => require('./src/helpers/jest'),
6 | mocha: () => require('./src/helpers/mocha')
7 | }
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "botium-bindings",
3 | "version": "2.1.15",
4 | "engines": {
5 | "node": ">=14"
6 | },
7 | "bin": {
8 | "botium-bindings": "./bin/botium-bindings.js"
9 | },
10 | "scripts": {
11 | "postinstall": "node ./report.js",
12 | "build": "npm run eslint && rollup -c",
13 | "eslint": "eslint \"./bin/**/*.js\" \"./src/**/*.js\"",
14 | "eslint:fix": "eslint --fix \"./bin/**/*.js\" \"./src/**/*.js\"",
15 | "test": "echo \"no tests specified\" && exit 0",
16 | "update-dependencies": "npm-check-updates --reject rollup -u --timeout 120000"
17 | },
18 | "description": "Binding Botium, the Selenium for Chatbots, to test runners",
19 | "main": "index.js",
20 | "author": "Botium GmbH",
21 | "license": "MIT",
22 | "dependencies": {
23 | "@babel/runtime": "^7.21.0",
24 | "async": "^3.2.4",
25 | "botium-core": "1.13.16",
26 | "debug": "^4.3.4",
27 | "lodash": "^4.17.21",
28 | "mkdirp": "^3.0.0",
29 | "promise-retry": "^2.0.1",
30 | "yargs": "^17.7.1"
31 | },
32 | "devDependencies": {
33 | "@babel/core": "^7.21.4",
34 | "@babel/node": "^7.20.7",
35 | "@babel/plugin-transform-runtime": "^7.21.4",
36 | "@babel/preset-env": "^7.21.4",
37 | "eslint": "^8.38.0",
38 | "eslint-config-standard": "^17.0.0",
39 | "eslint-plugin-import": "^2.27.5",
40 | "eslint-plugin-n": "^15.7.0",
41 | "eslint-plugin-promise": "^6.1.1",
42 | "eslint-plugin-standard": "^5.0.0",
43 | "license-checker": "^25.0.1",
44 | "npm-check-updates": "^16.10.8",
45 | "rollup": "^2.60.0",
46 | "rollup-plugin-babel": "^4.4.0",
47 | "rollup-plugin-commonjs": "^10.1.0",
48 | "rollup-plugin-json": "^4.0.0",
49 | "rollup-plugin-node-resolve": "^5.2.0"
50 | },
51 | "repository": {
52 | "type": "git",
53 | "url": "git+https://github.com/codeforequity-at/botium-bindings.git"
54 | },
55 | "keywords": [
56 | "continuous",
57 | "testing",
58 | "chatbot"
59 | ],
60 | "bugs": {
61 | "url": "https://github.com/codeforequity-at/botium-core/issues"
62 | },
63 | "homepage": "https://www.botium.ai"
64 | }
65 |
--------------------------------------------------------------------------------
/report.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const os = require('os')
3 |
4 | const botiumAnalyticsHost = process.env.BOTIUM_ANALYTICS_HOST || 'v1.license.botium.cyaraportal.us'
5 | const botiumAnalyticsPort = process.env.BOTIUM_ANALYTICS_PORT || 443
6 | const https = botiumAnalyticsPort === 443 ? require('https') : require('http')
7 | const execTimeout = 10000
8 |
9 | function logIfVerbose (toLog, stream) {
10 | if (process.env.BOTIUM_ANALYTICS_VERBOSE === 'true') {
11 | (stream || console.log)(toLog)
12 | }
13 | }
14 |
15 | async function reportPostInstall () {
16 | if (process.env.BOTIUM_ANALYTICS === 'false') return
17 |
18 | const packageJson = require(path.join(__dirname, 'package.json'))
19 |
20 | const infoPayload = {
21 | rawPlatform: os.platform(),
22 | rawArch: os.arch(),
23 | library: packageJson.name,
24 | version: packageJson.version
25 | }
26 |
27 | const data = JSON.stringify(infoPayload)
28 | logIfVerbose(`Botium analytics payload: ${data}`)
29 |
30 | const reqOptions = {
31 | host: botiumAnalyticsHost,
32 | port: botiumAnalyticsPort,
33 | method: 'POST',
34 | path: '/metrics/installation/core',
35 | headers: {
36 | 'Content-Type': 'application/json',
37 | 'Content-Length': data.length
38 | },
39 | timeout: execTimeout
40 | }
41 | await new Promise((resolve, reject) => {
42 | const req = https.request(reqOptions, (res) => {
43 | logIfVerbose(`Response status: ${res.statusCode}`)
44 | resolve()
45 | })
46 |
47 | req.on('error', error => {
48 | logIfVerbose(error, console.error)
49 | reject(error)
50 | })
51 |
52 | req.on('timeout', error => {
53 | logIfVerbose(error, console.error)
54 | reject(error)
55 | })
56 |
57 | req.write(data)
58 | req.end()
59 | })
60 | }
61 |
62 | if (require.main === module) {
63 | try {
64 | reportPostInstall().catch(e => {
65 | logIfVerbose(`\n\n${e}`, console.error)
66 | }).finally(() => {
67 | process.exit(0)
68 | })
69 | } catch (e) {
70 | logIfVerbose(`\n\nTop level error: ${e}`, console.error)
71 | process.exit(0)
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import commonjs from 'rollup-plugin-commonjs'
3 | import json from 'rollup-plugin-json'
4 |
5 | export default {
6 | input: 'index.js',
7 | output: [
8 | {
9 | file: 'dist/botium-bindings-es.js',
10 | format: 'es',
11 | sourcemap: true
12 | },
13 | {
14 | file: 'dist/botium-bindings-cjs.js',
15 | format: 'cjs',
16 | sourcemap: true
17 | }
18 | ],
19 | plugins: [
20 | commonjs({
21 | exclude: 'node_modules/**'
22 | }),
23 | babel({
24 | exclude: 'node_modules/**',
25 | runtimeHelpers: true
26 | }),
27 | json()
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/samples/hello/botium.json:
--------------------------------------------------------------------------------
1 | {
2 | "botium": {
3 | "Capabilities": {
4 | "PROJECTNAME": "hello",
5 | "CONTAINERMODE": "echo",
6 | "RETRY_CONVO_ONERROR_REGEXP": [ "delivery failure" ],
7 | "RETRY_CONVO_NUMRETRIES": 2
8 | },
9 | "Sources": {},
10 | "Envs": {}
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/hello/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "postinstall": "cd ../../ && npm install --no-save botium-connector-echo && cd samples/hello",
6 | "test": "mocha spec"
7 | },
8 | "botium": {
9 | "convodirs": [
10 | "spec/convo"
11 | ],
12 | "expandConvos": true,
13 | "expandUtterancesToConvos": false,
14 | "expandScriptingMemoryToConvos": false
15 | },
16 | "devDependencies": {
17 | "mocha": "latest",
18 | "botium-bindings": "../..",
19 | "botium-connector-echo": "latest"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/hello/spec/botium.spec.js:
--------------------------------------------------------------------------------
1 | const bb = require('botium-bindings')
2 | bb.helper.mocha().setupMochaTestSuite()
3 |
--------------------------------------------------------------------------------
/samples/hello/spec/convo/give_me_a_picture.convo.txt:
--------------------------------------------------------------------------------
1 | give me picture
2 |
3 | #me
4 | Hello, Bot!
5 |
6 | #bot
7 | You said: Hello, Bot!
8 |
9 | #me
10 | give me a picture
11 |
12 | #bot
13 | Here is a picture
14 | MEDIA logo.png
15 |
--------------------------------------------------------------------------------
/samples/hello/spec/convo/shopping_cart.convo.txt:
--------------------------------------------------------------------------------
1 | shopping cart
2 |
3 | #me
4 | add to cart bananas
5 |
6 | #bot
7 | INTENT addtocart
8 | INTENT_CONFIDENCE 50
9 | ENTITIES product|..
10 | ENTITY_VALUES bananas|..
11 |
12 | #me
13 | show cart
14 |
15 | #bot
16 | In your cart: bananas
17 | INTENT showcart
18 | INTENT_CONFIDENCE 50
19 |
20 | #me
21 | clear cart
22 |
23 | #bot
24 | INTENT clearcart
25 | INTENT_CONFIDENCE 50
26 |
--------------------------------------------------------------------------------
/samples/hello/spec/convo/should_fail.convo.txt:
--------------------------------------------------------------------------------
1 | should fail because weak intent
2 |
3 | #me
4 | weak intent
5 |
6 | #bot
7 | INTENT weak
8 | INTENT_CONFIDENCE 50
--------------------------------------------------------------------------------
/samples/hello/spec/convo/should_fail_delivery.convo.txt:
--------------------------------------------------------------------------------
1 | should fail because delivery failure
2 |
3 | #me
4 | fail
5 |
6 | #bot
7 |
--------------------------------------------------------------------------------
/src/BotiumBindings.js:
--------------------------------------------------------------------------------
1 | const util = require('util')
2 | const path = require('path')
3 | const promiseRetry = require('promise-retry')
4 | const debug = require('debug')('botium-bindings-main')
5 | const { reportUsage } = require('./metrics')
6 |
7 | const { BotDriver, RetryHelper } = require('botium-core')
8 |
9 | module.exports = class BotiumBindings {
10 | constructor ({ botiumConfig, ...args } = {}) {
11 | args = Object.assign({}, this.getPackageJsonBotiumSection(), args)
12 | debug(`Botium Bindings args: ${util.inspect(args)}`)
13 |
14 | this.convodirs = args.convodirs || ['./spec/convo']
15 | this.expandConvos = Object.prototype.hasOwnProperty.call(args, 'expandConvos') ? args.expandConvos : true
16 | this.expandUtterancesToConvos = Object.prototype.hasOwnProperty.call(args, 'expandUtterancesToConvos') ? args.expandUtterancesToConvos : false
17 | this.expandScriptingMemoryToConvos = Object.prototype.hasOwnProperty.call(args, 'expandScriptingMemoryToConvos') ? args.expandScriptingMemoryToConvos : false
18 |
19 | this.driver = new BotDriver(botiumConfig && botiumConfig.Capabilities, botiumConfig && botiumConfig.Sources, botiumConfig && botiumConfig.Envs)
20 | this.compiler = this.driver.BuildCompiler()
21 | this.container = null
22 | }
23 |
24 | getPackageJsonBotiumSection () {
25 | try {
26 | return require(path.resolve(process.cwd(), 'package.json')).botium || {}
27 | } catch (e) {
28 | }
29 | return {}
30 | }
31 |
32 | getTestSuiteName () {
33 | try {
34 | const botiumJson = require(process.env.BOTIUM_CONFIG || path.resolve(process.cwd(), 'botium.json'))
35 | return botiumJson.botium.Capabilities.PROJECTNAME
36 | } catch (e) {
37 | }
38 | let packageJson = null
39 | try {
40 | packageJson = require(path.resolve(process.cwd(), 'package.json'))
41 | return 'Botium Test Suite for ' + packageJson.name
42 | } catch (e) {
43 | }
44 | return 'Botium Test Suite'
45 | }
46 |
47 | async beforeAll () {
48 | this.container = await this.driver.Build()
49 | }
50 |
51 | async afterAll () {
52 | if (this.container) {
53 | await this.container.Clean()
54 | }
55 | this.container = null
56 | }
57 |
58 | async beforeEach () {
59 | if (this.container) {
60 | await this.container.Start()
61 | } else {
62 | throw new Error('Botium Initialization failed. Please see error messages above (enable debug logging).')
63 | }
64 | }
65 |
66 | async afterEach () {
67 | if (this.container) {
68 | await this.container.Stop()
69 | }
70 | }
71 |
72 | wrapBotiumError (err) {
73 | if (err.cause && err.cause.prettify) {
74 | return new Error(err.message + '\r\n' + err.cause.prettify())
75 | } else {
76 | return new Error(err.message)
77 | }
78 | }
79 |
80 | setupTestSuite (testcaseCb, assertCb, failCb) {
81 | if (this.convodirs && this.convodirs.length) {
82 | this.convodirs.forEach((convodir) => {
83 | this.compiler.ReadScriptsFromDirectory(convodir)
84 | })
85 | }
86 | if (this.expandUtterancesToConvos) {
87 | this.compiler.ExpandUtterancesToConvos()
88 | }
89 | if (this.expandScriptingMemoryToConvos) {
90 | this.compiler.ExpandScriptingMemoryToConvos()
91 | }
92 | if (this.expandConvos || this.expandUtterancesToConvos || this.expandScriptingMemoryToConvos) {
93 | this.compiler.ExpandConvos()
94 | }
95 |
96 | const usageMetrics = {
97 | metric: 'testexecution',
98 | connector: `${this.compiler.caps.CONTAINERMODE}`,
99 | projectname: `${this.compiler.caps.PROJECTNAME}`,
100 | convoCount: this.compiler.convos.length,
101 | convoStepCount: this.compiler.convos.reduce((sum, convo) => sum + convo.conversation.length, 0),
102 | partialConvoCount: Object.keys(this.compiler.partialConvos).length,
103 | utterancesRefCount: Object.keys(this.compiler.utterances).length,
104 | utterancesCount: Object.keys(this.compiler.utterances).reduce((sum, uttName) => sum + this.compiler.utterances[uttName].utterances.length, 0),
105 | scriptingMemoriesCount: this.compiler.scriptingMemories.length
106 | }
107 | reportUsage(usageMetrics)
108 |
109 | debug(`ready reading convos and utterances, number of test cases: (${this.compiler.convos.length}).`)
110 |
111 | if (assertCb) {
112 | this.compiler.scriptingEvents.assertBotResponse = assertCb
113 | }
114 | if (failCb) {
115 | this.compiler.scriptingEvents.fail = failCb
116 | }
117 |
118 | this.compiler.convos.forEach((convo) => {
119 | debug(`adding test case ${convo.header.toString()}`)
120 | testcaseCb(convo, (testcaseDone) => {
121 | if (this.container) {
122 | debug(`running testcase${convo.header.toString()}`)
123 |
124 | const retryHelper = new RetryHelper(this.container.caps, 'CONVO')
125 | promiseRetry(async (retry, number) => {
126 | try {
127 | await convo.Run(this.container)
128 | } catch (err) {
129 | if (retryHelper.shouldRetry(err)) {
130 | debug(`Running Convo "${convo.header.name}" trial #${number} failed, retry activated`)
131 | await this.container.Stop()
132 | await this.container.Start()
133 | debug(`Restarting container for Convo "${convo.header.name}" trial #${number} completed successfully.`)
134 | retry(err)
135 | } else {
136 | debug(`Running Convo "${convo.header.name}" trial #${number} failed finally`)
137 | throw err
138 | }
139 | }
140 | }, retryHelper.retrySettings)
141 | .then(() => {
142 | debug(`Test Case "${convo.header.name}" ready, calling done function.`)
143 | testcaseDone()
144 | })
145 | .catch((err) => {
146 | debug(`Test Case "${convo.header.name}" failed: ${util.inspect(err)}`)
147 | testcaseDone(this.wrapBotiumError(err))
148 | })
149 | } else {
150 | testcaseDone(new Error('Botium Initialization failed. Please see error messages above (enable debug logging).'))
151 | }
152 | })
153 | })
154 | }
155 |
156 | UserSaysText (...args) {
157 | if (this.container) {
158 | return this.container.UserSaysText(...args)
159 | } else {
160 | return Promise.reject(new Error('Botium Initialization failed. Please see error messages above (enable debug logging).'))
161 | }
162 | }
163 |
164 | UserSays (...args) {
165 | if (this.container) {
166 | return this.container.UserSays(...args)
167 | } else {
168 | return Promise.reject(new Error('Botium Initialization failed. Please see error messages above (enable debug logging).'))
169 | }
170 | }
171 |
172 | WaitBotSays (...args) {
173 | if (this.container) {
174 | return this.container.WaitBotSays(...args)
175 | } else {
176 | return Promise.reject(new Error('Botium Initialization failed. Please see error messages above (enable debug logging).'))
177 | }
178 | }
179 |
180 | WaitBotSaysText (...args) {
181 | if (this.container) {
182 | return this.container.WaitBotSaysText(...args)
183 | } else {
184 | return Promise.reject(new Error('Botium Initialization failed. Please see error messages above (enable debug logging).'))
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/cli/index.js:
--------------------------------------------------------------------------------
1 | const util = require('util')
2 | const fs = require('fs')
3 | const path = require('path')
4 | const { mkdirpSync } = require('mkdirp')
5 | const debug = require('debug')('botium-bindings-cli')
6 |
7 | const testRunnerTypes = [
8 | 'mocha',
9 | 'jest',
10 | 'jasmine'
11 | ]
12 |
13 | const handler = (argv) => {
14 | debug(`command options: ${util.inspect(argv)}`)
15 |
16 | const packageJsonFile = path.resolve(process.cwd(), 'package.json')
17 | if (!fs.existsSync(packageJsonFile)) {
18 | console.log(`No package.json file found at "${packageJsonFile}", exiting.`)
19 | process.exit(1)
20 | }
21 | const botiumSpecDir = path.resolve(process.cwd(), argv.specdir)
22 | if (!fs.existsSync(botiumSpecDir)) {
23 | mkdirpSync(botiumSpecDir)
24 | }
25 | const botiumConvoDir = path.resolve(process.cwd(), argv.convodir)
26 | if (!fs.existsSync(botiumConvoDir)) {
27 | mkdirpSync(botiumConvoDir)
28 | }
29 |
30 | const packageJson = require(path.resolve(process.cwd(), 'package.json'))
31 | if (packageJson.botium) {
32 | console.log(`Botium Section in File "${packageJsonFile}" already present, skipping ...`)
33 | } else {
34 | packageJson.botium = {
35 | convodirs: [
36 | argv.convodir
37 | ],
38 | expandConvos: true,
39 | expandUtterancesToConvos: false,
40 | expandScriptingMemoryToConvos: false
41 | }
42 | console.log(`Added Botium Section in File "${packageJsonFile}".`)
43 | }
44 | packageJson.devDependencies = packageJson.devDependencies || {}
45 | if (!packageJson.devDependencies[argv.testRunner]) {
46 | packageJson.devDependencies[argv.testRunner] = 'latest'
47 | }
48 | if (!packageJson.devDependencies['botium-bindings']) {
49 | packageJson.devDependencies['botium-bindings'] = 'latest'
50 | }
51 | if (!packageJson.devDependencies['botium-connector-echo']) {
52 | packageJson.devDependencies['botium-connector-echo'] = 'latest'
53 | }
54 | packageJson.scripts = packageJson.scripts || {}
55 | if (!packageJson.scripts[argv.testRunner]) {
56 | if (argv.testRunner === 'jest') {
57 | packageJson.scripts[argv.testRunner] = `jest --env node ${argv.specdir}`
58 | } else {
59 | packageJson.scripts[argv.testRunner] = `${argv.testRunner} ${argv.specdir}`
60 | }
61 | } else {
62 | console.warn(`You already have an npm script called ${argv.testRunner}. In order to run botium tests, you'll need an npm script running "${argv.testRunner} ${argv.specdir}"`)
63 | }
64 | fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2))
65 |
66 | const botiumJsonFile = path.resolve(process.cwd(), 'botium.json')
67 | if (fs.existsSync(botiumJsonFile)) {
68 | console.log(`Botium Configuration File "${botiumJsonFile}" already present, skipping ...`)
69 | } else {
70 | fs.writeFileSync(botiumJsonFile, JSON.stringify({
71 | botium: {
72 | Capabilities: {
73 | PROJECTNAME: packageJson.name,
74 | CONTAINERMODE: 'echo'
75 | },
76 | Sources: { },
77 | Envs: { }
78 | }
79 | }, null, 2))
80 | console.log(`Botium Configuration File written to "${botiumJsonFile}".`)
81 | }
82 |
83 | const botiumSpecFile = path.resolve(botiumSpecDir, 'botium.spec.js')
84 | if (fs.existsSync(botiumSpecFile)) {
85 | console.log(`Botium Spec File "${botiumSpecFile}" already present, skipping ...`)
86 | } else {
87 | if (argv.testRunner === 'mocha') {
88 | fs.writeFileSync(botiumSpecFile,
89 | `const bb = require('botium-bindings')
90 | bb.helper.mocha().setupMochaTestSuite()
91 | `
92 | )
93 | } else if (argv.testRunner === 'jasmine') {
94 | fs.writeFileSync(botiumSpecFile,
95 | `const bb = require('botium-bindings')
96 | bb.helper.jasmine().setupJasmineTestSuite()
97 | `
98 | )
99 | } else if (argv.testRunner === 'jest') {
100 | fs.writeFileSync(botiumSpecFile,
101 | `const bb = require('botium-bindings')
102 | bb.helper.jest().setupJestTestSuite()
103 | `
104 | )
105 | }
106 | console.log(`Botium Spec File written to "${botiumSpecFile}".`)
107 | }
108 |
109 | const botiumEchoSample = path.resolve(botiumConvoDir, 'give_me_a_picture.convo.txt')
110 | if (fs.existsSync(botiumEchoSample)) {
111 | console.log(`Botium Convo File "${botiumEchoSample}" already present, skipping ...`)
112 | } else {
113 | fs.writeFileSync(botiumEchoSample,
114 | `give me picture
115 |
116 | #me
117 | Hello, Bot!
118 |
119 | #bot
120 | You said: Hello, Bot!
121 |
122 | #me
123 | give me a picture
124 |
125 | #bot
126 | Here is a picture
127 | MEDIA http://www.botium.at/img/logo.png
128 | `
129 | )
130 | console.log(`Botium Convo File written to "${botiumEchoSample}".`)
131 | }
132 | console.log(`Botium initialization nearly ready. You should now run "npm install" to complete, and "npm run ${argv.testRunner}" to verify.`)
133 | }
134 |
135 | module.exports = {
136 | command: 'init [test-runner]',
137 | describe: 'Setup Botium project for a specific test runner',
138 | builder: (yargs) => {
139 | yargs.positional('test-runner', {
140 | describe: 'Test runner',
141 | choices: testRunnerTypes,
142 | default: 'mocha'
143 | })
144 | yargs.option('specdir', {
145 | describe: 'Project directory to place the test specs',
146 | default: 'spec'
147 | })
148 | yargs.option('convodir', {
149 | describe: 'Project directory to place the convo files',
150 | default: path.join('spec', 'convo')
151 | })
152 | },
153 | handler
154 | }
155 |
--------------------------------------------------------------------------------
/src/helpers/jasmine.js:
--------------------------------------------------------------------------------
1 | /* global describe it beforeAll beforeEach afterAll afterEach fail */
2 |
3 | const BotiumBindings = require('../BotiumBindings')
4 |
5 | const defaultTimeout = process.env.BOTIUM_JASMINE_TIMEOUT || 60000
6 |
7 | const setupJasmineTestCases = ({ timeout = defaultTimeout, testcaseSelector, bb } = {}) => {
8 | bb = bb || new BotiumBindings()
9 |
10 | bb.setupTestSuite(
11 | (testcase, testcaseFunction) => {
12 | if (testcaseSelector && !testcaseSelector(testcase)) return false
13 |
14 | it(
15 | testcase.header.name,
16 | (done) => {
17 | testcaseFunction((err) => {
18 | if (err) {
19 | fail(err)
20 | }
21 | done()
22 | })
23 | },
24 | timeout)
25 | return true
26 | },
27 | null,
28 | (err) => fail(err)
29 | )
30 | }
31 |
32 | const setupJasmineTestSuite = ({ timeout = defaultTimeout, name, testcaseSelector, bb } = {}) => {
33 | bb = bb || new BotiumBindings()
34 | name = name || bb.getTestSuiteName()
35 |
36 | describe(name, () => {
37 | beforeAll((done) => {
38 | bb.beforeAll().then(() => done()).catch(done.fail)
39 | }, timeout)
40 |
41 | beforeEach((done) => {
42 | bb.beforeEach().then(() => done()).catch(done.fail)
43 | }, timeout)
44 |
45 | afterEach((done) => {
46 | bb.afterEach().then(() => done()).catch(done.fail)
47 | }, timeout)
48 |
49 | afterAll((done) => {
50 | bb.afterAll().then(() => done()).catch(done.fail)
51 | }, timeout)
52 |
53 | setupJasmineTestCases({ timeout, testcaseSelector, bb })
54 | })
55 | }
56 |
57 | module.exports = {
58 | setupJasmineTestCases,
59 | setupJasmineTestSuite
60 | }
61 |
--------------------------------------------------------------------------------
/src/helpers/jest.js:
--------------------------------------------------------------------------------
1 | /* global describe test it beforeAll beforeEach afterAll afterEach */
2 |
3 | const BotiumBindings = require('../BotiumBindings')
4 |
5 | const setupJestTestCases = ({ testcaseSelector, bb } = {}) => {
6 | bb = bb || new BotiumBindings()
7 |
8 | let testCount = 0
9 | bb.setupTestSuite(
10 | (testcase, testcaseFunction) => {
11 | if (testcaseSelector && !testcaseSelector(testcase)) return false
12 |
13 | testCount++
14 | test(testcase.header.name, testcaseFunction)
15 | return true
16 | }
17 | )
18 | if (testCount === 0) {
19 | it.skip('skip empty test suite', () => {})
20 | }
21 | }
22 |
23 | const setupJestTestSuite = ({ name, testcaseSelector, bb } = {}) => {
24 | bb = bb || new BotiumBindings()
25 | name = name || bb.getTestSuiteName()
26 |
27 | describe(name, () => {
28 | beforeAll((done) => {
29 | bb.beforeAll().then(() => done()).catch(done)
30 | })
31 |
32 | beforeEach((done) => {
33 | bb.beforeEach().then(() => done()).catch(done)
34 | })
35 |
36 | afterEach((done) => {
37 | bb.afterEach().then(() => done()).catch(done)
38 | })
39 |
40 | afterAll((done) => {
41 | bb.afterAll().then(() => done()).catch(done)
42 | })
43 |
44 | setupJestTestCases({ bb, testcaseSelector })
45 | })
46 | }
47 |
48 | module.exports = {
49 | setupJestTestCases,
50 | setupJestTestSuite
51 | }
52 |
--------------------------------------------------------------------------------
/src/helpers/mocha.js:
--------------------------------------------------------------------------------
1 | /* global describe it before beforeEach after afterEach */
2 |
3 | const BotiumBindings = require('../BotiumBindings')
4 |
5 | const defaultTimeout = process.env.BOTIUM_MOCHA_TIMEOUT || 60000
6 |
7 | const setupMochaTestCases = ({ timeout = defaultTimeout, testcaseSelector, bb } = {}) => {
8 | bb = bb || new BotiumBindings()
9 |
10 | bb.setupTestSuite(
11 | (testcase, testcaseFunction) => {
12 | if (testcaseSelector && !testcaseSelector(testcase)) return false
13 |
14 | it(testcase.header.name, testcaseFunction).timeout(timeout)
15 | return true
16 | }
17 | )
18 | }
19 |
20 | const setupMochaTestSuite = ({ timeout = defaultTimeout, name, testcaseSelector, bb } = {}) => {
21 | bb = bb || new BotiumBindings()
22 | name = name || bb.getTestSuiteName()
23 |
24 | describe(name, () => {
25 | before(function (done) {
26 | this.timeout(timeout)
27 | bb.beforeAll().then(() => done()).catch(done)
28 | })
29 | beforeEach(function (done) {
30 | this.timeout(timeout)
31 | bb.beforeEach().then(() => done()).catch(done)
32 | })
33 | afterEach(function (done) {
34 | this.timeout(timeout)
35 | bb.afterEach().then(() => done()).catch(done)
36 | })
37 | after(function (done) {
38 | this.timeout(timeout)
39 | bb.afterAll().then(() => done()).catch(done)
40 | })
41 |
42 | setupMochaTestCases({ timeout, testcaseSelector, bb })
43 | })
44 | }
45 |
46 | module.exports = {
47 | setupMochaTestCases,
48 | setupMochaTestSuite
49 | }
50 |
--------------------------------------------------------------------------------
/src/metrics.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const os = require('os')
3 |
4 | const botiumAnalyticsHost = process.env.BOTIUM_ANALYTICS_HOST || 'v1.license.botium.cyaraportal.us'
5 | const botiumAnalyticsPort = process.env.BOTIUM_ANALYTICS_PORT || 443
6 | const https = botiumAnalyticsPort === 443 ? require('https') : require('http')
7 | const execTimeout = 10000
8 |
9 | function logIfVerbose (toLog, stream) {
10 | if (process.env.BOTIUM_ANALYTICS_VERBOSE === 'true') {
11 | (stream || console.log)(toLog)
12 | }
13 | }
14 |
15 | async function reportUsage (metrics) {
16 | if (process.env.BOTIUM_ANALYTICS === 'false') return
17 |
18 | const packageJson = require(path.join(__dirname, '..', 'package.json'))
19 |
20 | const infoPayload = Object.assign({
21 | rawPlatform: os.platform(),
22 | rawArch: os.arch(),
23 | library: packageJson.name,
24 | version: packageJson.version
25 | }, metrics)
26 |
27 | const data = JSON.stringify(infoPayload)
28 | logIfVerbose(`Botium analytics payload: ${data}`)
29 |
30 | const reqOptions = {
31 | host: botiumAnalyticsHost,
32 | port: botiumAnalyticsPort,
33 | method: 'POST',
34 | path: '/metrics/usage/core',
35 | headers: {
36 | 'Content-Type': 'application/json',
37 | 'Content-Length': data.length
38 | },
39 | timeout: execTimeout
40 | }
41 | await new Promise((resolve, reject) => {
42 | const req = https.request(reqOptions, (res) => {
43 | logIfVerbose(`Response status: ${res.statusCode}`)
44 | resolve()
45 | })
46 |
47 | req.on('error', error => {
48 | logIfVerbose(error, console.error)
49 | resolve()
50 | })
51 |
52 | req.on('timeout', error => {
53 | logIfVerbose(error, console.error)
54 | resolve()
55 | })
56 |
57 | req.write(data)
58 | req.end()
59 | })
60 | }
61 |
62 | module.exports = {
63 | reportUsage: (metrics) => {
64 | reportUsage(metrics).catch(e => {
65 | logIfVerbose(`metrics error: ${e}`, console.error)
66 | })
67 | }
68 | }
69 |
--------------------------------------------------------------------------------