{"id":20712924,"url":"https://github.com/thesis/hubot-chat-testing","last_synced_at":"2025-07-08T19:41:28.518Z","repository":{"id":78438889,"uuid":"531950076","full_name":"thesis/hubot-chat-testing","owner":"thesis","description":"A fork of https://gitlab.com/hubot-scripts/hubot-chat-testing .","archived":false,"fork":false,"pushed_at":"2022-09-02T14:14:42.000Z","size":109,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-17T21:29:08.529Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thesis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-02T14:05:42.000Z","updated_at":"2022-09-02T14:06:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"9eb41b83-3d4b-4899-a70e-1def137c35cf","html_url":"https://github.com/thesis/hubot-chat-testing","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesis%2Fhubot-chat-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesis%2Fhubot-chat-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesis%2Fhubot-chat-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesis%2Fhubot-chat-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thesis","download_url":"https://codeload.github.com/thesis/hubot-chat-testing/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242988012,"owners_count":20217534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T02:22:33.062Z","updated_at":"2025-03-11T06:42:10.047Z","avatar_url":"https://github.com/thesis.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hubot-chat-testing\nNodeJS module to be used as a helper with automatic testing.\n\n## Why hubot-chat-testing?\nHubot chat testing module is a wrapper for the \n[hubot-test-helper](https://github.com/mtsmfm/hubot-test-helper) library\nand can be used to write easier to understand tests for Hubot.\n\nThe `hubot-test-helper` library provides great help with technical side of the tests - \nit manages the bot and the room creation and it allows for adding new messages to the bot. \nThe biggest problem - for me - is the readability for those tests. Let's use an example:\n\n```javascript\ncontext('testing good manners of the bot', function() {\n    beforeEach(function() {\n      return co(function*() {\n        yield this.room.user.say('user', 'hubot hi');\n        // maybe some promise with delaying the response...?\n        yield this.room.user.say('user2', 'hi');\n      }.bind(this));\n    });\n\n    it('should be polite and say hi when user is greeting', function() {\n      expect(this.room.messages[0]).to.be.eql(['user', 'hubot hi']);\n      expect(this.room.messages[1]).to.be.eql(['hubot', '@user hi']);\n      expect(this.room.messages[2]).to.be.eql(['user2', 'hi']);\n      expect(this.room.messages[3]).to.be.eql(['hubot', '@user2 hi']);\n    });\n});\n```\nThe user of this library has to remember that all the messages should be defined in the \n`beforeEach` section, where the `co` library is used altogether with the `yield` keyword. \nWhat is more important, when the bot's response takes some additional time, \nthe user also needs to include `Promise` with delay.\n\nThe Array type storing messages is also a little hard to expect more complex test suites.\n\nYou have to remember to include `hubot` and `@user` prefixes in some cases of messages.\n\nNext problem with readability is that the bot responses are defined in different section, `it`.\nThis way the chat history seems to be a little unsettled while normally it looks like conversation\nbetween user and bot, similar to \"user =\u003e bot =\u003e user =\u003e bot\" like so:\n\n```javascript\n    chat.when('the user says hi to the bot')\n    .user('user').messagesBot('hi')\n    .bot.repliesWith('hi')\n    .expect('the bot should say hi to the user')\n``` \n\nAnd this is exactly what I had in mind when writing tests for Hubot scripts. Why writing so much\ncopy-paste-like code, when in most of the cases you just want to achieve/test a simple flow of the\nconversation? \n\nThe `hubot-chat-testing` module will generate the `hubot-test-helper` scripts with remembering\nabout all the technical stuff - you just have to provide chat history.\n\n## Usage\n\n### Installing the module\n```bash\nnpm install hubot-chat-testing\n```\nthen all you have to do is to require the library and set-up the `hubot-test-helper` helper:\n```javascript\nconst HubotChatTesting = require('hubot-chat-testing');\nconst Helper = require('hubot-test-helper');\n\nconst chat = new HubotChatTesting('hubot', new Helper('../scripts/script.js'));\n```\n\n### Writing the tests\nAll you have to do in the first place is to create normal test suit - as you would do with the `hubot-test-helper` module.\nThen either in `describe` or `context` just place your chat assertions by using the module's API.\n\nTypical flow of the conversation:\n```javascript\n chat.when('testing good manners of the bot')\n    .user('user').messagesBot('hi')                // User: hubot hi\n    .bot.repliesWith('hi')                         // Hubot: @user hi\n    .user('user2').messagesBot('hi')               // User2: @hubot hi\n    .bot.repliesWith('hi')                         // Hubot: @user2 hi\n    .user('user').messagesRoom('hello everyone')   // User: hello everyone\n    .bot.repliesWith('hi')                         // Hubot: @user hi\n    .expect('the bot should be polite and say hi when user is greeting');\n```\n\nAs you can see, this library focuses on making the chat flow as easy as it would be in the real life. Each bot response\nshould be added as a reaction to the specific user's message - and each expectation means a new message in chat. \n\nThe `hubot-chat-test` module has simple to understand 'chains', which were inspired by libraries like `spec`, `mocha` etc.\n\n##### Checking whether the bot response matches regex\n\nIf you don't want to check the whole response of the bot, but instead you just need to \ncheck whether the response matches some regexp:\n```javascript\n chat.when('the user appears after years of absence')\n    .user('user').messagesRoom('hi father')\n    // Lets assume that bot normally says \"No, I am your father!\" to \"hi father\"\n    .bot.replyMatches(/(Luke|No), I am your father/)\n    .expect('the bot should tell the user the truth');\n```\n\n##### Checking whether the bot responses multiple time for one user message\n\nIf the bot feels very talkative, you can just use:\n```javascript\n chat.when('the user is greeting in the room')\n    .user('user').messagesRoom('hi')\n    .bot.repliesWith('Have I met you before? Let me think...')\n    .bot.repliesWith('Oh yes, now I remember! You\\'re that guy the admin told me to worry about!')\n    .expect('the bot should react to it with some chit-chat');\n```\n\n##### Multiple assertions for single bot response\n\nIf you want to perform multiple checks for single bot's response:\n```javascript\nchat.when('the user asks for a very complex answer')\n    .user('user').messagesBot('say dirty things to me')\n    .bot.replyIncludes('Lorem ipsum dolor sit amet,')\n        .and.itMatches(/mattis sit amet dolor$/i)\n        .and.itIncludes('Etiam aliquet sagittis')\n    .expect('the bot should react to it with some chit-chat');\n```\n\n##### Setting the delay for the bot response\n\nIf the bot needs time to compute an answer, you can increase the waiting time by using:\n```javascript\n// this delay will be used by default in all test scenarios\nconst chat = new HubotChatTesting('hubot', new Helper('../scripts/detailed-help.js'), {answerDelay: 50}); \n\n// this delay will be used in this specific test scenario\nchat.when('the user asks for a very complex answer', {answerDelay: 200}) \n    .user('user').messagesBot('a very intriguing message', 400) // only this request will wait 400 ms for an answer\n```\n\nThis functionality is useful when you are not mocking your bot's functionality and instead it calls some HTTP requests.\nMore information can be found [under the docs for hubot-test-helper](https://github.com/mtsmfm/hubot-test-helper#manual-delay).\n\n##### Setting content and adding assertions for the bot's brain\n \nIf you want to set the robot's brain before committing to the test case, just user below example:\n```javascript\n    chat.when('user is asking the bot to forget the value of the remembered variable')\n        .setBrain((brain =\u003e {\n            brain.set('hubot-sayings-name', 'value');\n        }))\n        .user('alice').messagesRoom('!forget name')\n        .bot.messagesRoom('forgotten')\n        .brain.not.contains('hubot-sayings-name')\n        .expect('the bot should forget it');\n```\n\n##### Adding your own expectations for the test\n\nIf you still need something more complex than this module's API, you can also define your own expectations that\nwill fire after the default ones:\n```javascript\nconst expect = require('chai').expect;\nchat.when('the user is asking for something very complex')\n    .user('user').messagesBot('cmon, do something')\n    .bot.repliesWith('*does*')\n    .additionalExpectations((test, logger) =\u003e {\n        logger.debug(`You can access the logger by using the optional parameter logger`);\n        expect(test.room.messages[1]).to.not.eql('simple')\n    })\n    .expect('the bot should do it')\n```\n\n##### Setting up the environment variables\n\nSometimes our bot will behave differently depending on the value of any environment variables.\nIf you would do it outside the beforeEach scope, it would set up the env variable with the same\nvalue for every test.\nIn order to make this easy, there is a way to set up the variables using the library's API:\n```javascript\n    chat.when('we have set up the environment variable')\n        .setEnvironmentVariables({\n            MY_VARIABLE: 'my-value'\n        })\n        .user('alice').messagesBot('encourage Rex')\n        .bot.replyIncludes('Rex')\n        .additionalExpectations(() =\u003e {\n            expect(process.env.MY_VARIABLE).to.eql('my-value');\n        })\n        .expect('the library should properly set up it');\n```\n\nThe library will revert the value after the testing is done, so it has no impact on other\ntests.\n\n##### Additional configuration for the hubot-test-helper\n\nIn case of requirement to set up the room other than with default values, you can do it with two different ways.\n```javascript\nconst roomOptions = {response: NewMockResponse};\n// The first way is to set the default options on all chat test cases\nconst chat = new HubotChatTesting('hubot', new Helper('../node_modules/hubot-sayings/src/hubot-sayings.js'), null, roomOptions);\n\nchat.when('user is asking the bot to remember the value')\n    .setRoomOptions(roomOptions) // The second way is to set the options only for this test case\n    .user('alice').messagesRoom('!remember name value')\n    .bot.messagesRoom(\"okay, i'll remember that\")\n    .brain.key('hubot-sayings-name').equals('value')\n    .expect('the bot should remember the values');\n```\n\n##### More examples\n\nFor more examples, please give the [tests](test) a try.\n\n## Contribution\nI am willing to greet any contributions that would make testing Hubot's scripts even more readable.\nIf you want to contribute, just fork the project and add some changes!\n\n## Errors and ideas to improve\nIf you will find any errors with this library or have great idea how to improve it (and dont want to do it on your own),\nplease feel free to open [a new ticket](https://gitlab.com/hubot-scripts/hubot-chat-testing/issues). \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesis%2Fhubot-chat-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthesis%2Fhubot-chat-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesis%2Fhubot-chat-testing/lists"}