{"id":15552263,"url":"https://github.com/bahmutov/chat.io","last_synced_at":"2025-09-29T00:33:18.773Z","repository":{"id":38423056,"uuid":"409226661","full_name":"bahmutov/chat.io","owner":"bahmutov","description":"Cypress.io testing for a chat application that requires auth","archived":false,"fork":false,"pushed_at":"2024-09-28T06:54:55.000Z","size":1628,"stargazers_count":12,"open_issues_count":13,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-03T14:14:05.219Z","etag":null,"topics":["cypress-example"],"latest_commit_sha":null,"homepage":"https://slides.com/bahmutov/e2e-for-chat","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/bahmutov.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":"2021-09-22T14:00:32.000Z","updated_at":"2024-01-05T17:31:17.000Z","dependencies_parsed_at":"2023-01-21T00:47:26.018Z","dependency_job_id":"844d7b82-1a84-4c5f-acb8-fd4619a5336f","html_url":"https://github.com/bahmutov/chat.io","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fchat.io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fchat.io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fchat.io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fchat.io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bahmutov","download_url":"https://codeload.github.com/bahmutov/chat.io/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234575242,"owners_count":18854926,"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":["cypress-example"],"created_at":"2024-10-02T14:14:09.074Z","updated_at":"2025-09-29T00:33:13.386Z","avatar_url":"https://github.com/bahmutov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chat.io [![renovate-app badge][renovate-badge]][renovate-app] ![cypress version](https://img.shields.io/badge/cypress-9.7.0-brightgreen) ![cypress-data-session version](https://img.shields.io/badge/cypress--data--session-2.0.0-brightgreen)\n\n[![ci status][ci image]][ci url] [![CircleCI](https://circleci.com/gh/bahmutov/chat.io/tree/main.svg?style=svg)](https://circleci.com/gh/bahmutov/chat.io/tree/main) [![chat.io](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/f1j79r/main\u0026style=flat\u0026logo=cypress)](https://dashboard.cypress.io/projects/f1j79r/runs)\n\n\u003e Cypress.io testing for a chat application that requires auth\n\n## Videos\n\n- [Use MongoDB From The Plugin File Or Call Task From DevTools Console](https://youtu.be/h-pXOjgZG24)\n- [Wait For jQuery slideDown Animation To Finish](https://youtu.be/vsH2SESJuik)\n- [Use Docker Compose To Run Application Locally And On GitHub Actions](https://youtu.be/QiaphZibZsE)\n- [Use cy.request Command To Create A User And Log in](https://youtu.be/EKq7RC_uNsA)\n- [Connect And Send Socket Messages From Cypress Test](https://youtu.be/Wk4l8p9JQNA)\n- [Use cy.session Command To Prepare Test Data But Only When Needed](https://youtu.be/1SOn8NbZF4o)\n- [Use cy.dataSession plugin to prepare the test data](https://youtu.be/As5yqkoZOx8)\n- [Use Data Alias Created Automatically By cypress-data-session](https://youtu.be/VQtjDGCuRzI)\n- [Create User Using cypress-data-session Command](https://youtu.be/P-sb5OHSNsM)\n- [Invalidate cy.session From cypress-data-session](https://youtu.be/SyDz6l_EFoc)\n- [Share Data Across Specs Using cypress-data-session Plugin](https://youtu.be/ws4TitQJ7fQ)\n- [Use cy.dataSession To Create A User And Log In](https://youtu.be/PTlcRBgFJaM)\n- [Nodemon And cypress-watch-and-reload Utilities](https://youtu.be/fy4qYGK690Q)\n- [Quickly Create A User And Log in Using Dependent Data Sessions](https://www.youtube.com/watch?v=0KTGc83wSoA)\n- [Run Cypress On CircleCI From Your Terminal](https://youtu.be/fBcoMmNBY5w) using [run-cy-on-ci](https://github.com/bahmutov/run-cy-on-ci) utility\n- [Stay Logged In During Tests By Preserving A Cookie](https://youtu.be/tXqX2SQurMc)\n- TODO: using `cy.task` to create a new room\n- TODO: using spec events to clear the rooms and the users\n\n## Blog posts\n\n- [Get Faster Feedback From Your Cypress Tests Running On GitHub Actions](https://glebbahmutov.com/blog/faster-ci-feedback/)\n- [Get Faster Feedback From Your Cypress Tests Running On CircleCI](https://glebbahmutov.com/blog/faster-ci-feedback-on-circleci/)\n- [Flexible Cypress Data Setup And Validation](https://glebbahmutov.com/blog/cypresss-data-session/)\n- [Dealing With 3rd Party Scripts In Cypress Tests](https://glebbahmutov.com/blog/3rd-party/)\n- [Faster User Object Creation](https://glebbahmutov.com/blog/faster-user-creation/)\n- [Email Cypress Test Report](https://glebbahmutov.com/blog/email-cypress-report/)\n\n## Presentations\n\n- [End-to-End Testing for a Real-time Chat Web Application](https://slides.com/bahmutov/e2e-for-chat)\n\n## Installation\n\n```shell\n$ npm install\n```\n\nYou will need a MongoDB somewhere and a Redis instance. I assume the MongoDB is running in the cloud and the Redis is running locally in a Docker container.\n\n## Run the app\n\n### Using docker-compose\n\n```shell\n$ docker-compose up\n```\n\nOr you can run Redis and MongoDB separately\n\n### Using separate services\n\nStart Redis\n\n```shell\n$ docker run -d -p 6379:6379 redis:alpine\n```\n\n```shell\n$ MONGODB=... SESSION_SECRET=... npm start\n```\n\nTip: use [as-a](https://github.com/bahmutov/as-a) to inject the above environment variables into a local / user profile file `.as-a.init`, something like this:\n\n```ini\n[chat.io]\nSESSION_SECRET=MySecretVariable1234\nMONGODB=mongodb://root:rootPass1234@localhost:27017/\n```\n\n```shell\n$ as-a chat.io npm start\n```\n\nOpen the [http://localhost:3000](http://localhost:3000) in your browser.\n\n![Chat between two users](./images/chat.png)\n\n## Run the tests\n\nBecause Cypress connects to the same MongoDB to clear the data in some tests, need to start it with the same environment variable\n\n```shell\n$ MONGODB=... npx cypress open\n```\n\nRead [Testing Mongo with Cypress](https://glebbahmutov.com/blog/testing-mongo-with-cypress/)\n\nTip: you can use [as-a](https://github.com/bahmutov/as-a) to start Cypress with environment variables to connect to the MongoDB locally\n\n```shell\n$ as-a chat.io npx cypress open\n```\n\n## Start the app and run the tests\n\nUsing [start-server-and-test](https://github.com/bahmutov/start-server-and-test) utility you can start the application and open Cypress (assuming the services have been started)\n\n```shell\n# assuming injecting ENV variables using \"as-a\"\n$ as-a chat.io npm run dev\n```\n\n## Watching mode\n\nThis mode speeds the local development\n\n### Watching the server\n\nYou can start the application server in watch mode. Any file change will automatically restart the server. Uses [nodemon](https://github.com/remy/nodemon)\n\n```shell\n$ npm run watch\n```\n\n### Watching the specs\n\nThe Cypress tests automatically re-run when the spec files change. They also re-run when any files in the `public` folder change thanks to the [cypress-watch-and-reload](https://github.com/bahmutov/cypress-watch-and-reload) plugin.\n\n## History\n\nAll props for this Chat app goes to the original repo [OmarElGabry/chat.io](https://github.com/OmarElGabry/chat.io). I have only cloned to show it being tested, added more features, added Cypress tests\n\n## Custom domain\n\nBy setting the \"hosts\" object in the `cypress.json` we can map custom domains back to the local machine and use them from Cypress tests. For example, the spec file [my-chat-domain.js](./cypress/integration/my-chat-domain.js) visits the `http://my-chat.io:3000` which is mapped back to the `127.0.0.1:3000` inside the [cypress.json](./cypress.json) file.\n\n## HTTPS\n\nTo create a local self-signed certificate on Mac I used the following commands (see [Cypress Hosts Option](https://glebbahmutov.com/blog/cypress-hosts-option/) and [bahmutov/cypress-local-https](https://github.com/bahmutov/cypress-local-https))\n\n```\n$ brew install mkcert\n$ mkcert -install\n$ mkdir .cert\n$ mkcert -key-file ./.cert/key.pem -cert-file ./.cert/cert.pem \"my-chat.io\"\n```\n\nTo start the server with HTTPS, use\n\n```\n$ HTTPS=true ... start command ...\n```\n\nIn this case, the base URL should point at `https://my-chat.io` with additional \"hosts\" mapping this custom domain back to `127.0.0.1`\n\n```json\n{\n  \"baseUrl\": \"https://my-chat.io:3000/\",\n  \"hosts\": {\n    \"my-chat.io\": \"127.0.0.1\"\n  }\n}\n```\n\nCurrently, the [plugin file](./cypress/plugins/index.js) changes the base URL and sets the \"hosts\" object automatically when you launch Cypress with `HTTPS=true` environment variable.\n\nFor example, I use the following commands to test HTTPS and the custom domain\n\n```\n$ HTTPS=true as-a . npm start\n# from another terminal open Cypress\n$ HTTPS=true as-a . npx cypress open\n# or using a single command via start-server-and-test\n$ HTTPS=true as-a . npm run dev\n```\n\n## Continuous Integration\n\nThe tests run automatically on pull requests, and the changed specs run first, read the blog post [Get Faster Feedback From Your Cypress Tests Running On GitHub Actions](https://glebbahmutov.com/blog/faster-ci-feedback/). The tests run on GitHub Actions, see the workflows in [.github/workflows](./.github/workflows) folder. Similarly, the E2E changed tests run first on CircleCI, and if they pass, then all tests run with [parallelization](https://on.cypress.io/parallelization), see [.circleci/config.yml](./.circleci/config.yml) file and read [Get Faster Feedback From Your Cypress Tests Running On CircleCI](https://glebbahmutov.com/blog/faster-ci-feedback-on-circleci/)\n\n## About me\n\n- [@bahmutov](https://twitter.com/bahmutov)\n- [glebbahmutov.com](https://glebbahmutov.com)\n- [blog](https://glebbahmutov.com/blog)\n- [videos](https://www.youtube.com/glebbahmutov)\n- [presentations](https://slides.com/bahmutov)\n- [cypress.tips](https://cypress.tips)\n\n[ci image]: https://github.com/bahmutov/chat.io/workflows/ci/badge.svg?branch=main\n[ci url]: https://github.com/bahmutov/chat.io/actions\n[renovate-badge]: https://img.shields.io/badge/renovate-app-blue.svg\n[renovate-app]: https://renovateapp.com/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Fchat.io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbahmutov%2Fchat.io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Fchat.io/lists"}