todaypp / cypress-socketio-chat

Example testing real-time Socket.io chat using Cypress.io

Home Page:https://slides.com/bahmutov/e2e-for-chat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cypress-socketio-chat

ci status badges status renovate-app badge cypress version

Example testing real-time Socket.io chat using Cypress.io

The original chat program copied from dkhd/node-group-chat as described in Build A Group-Chat App in 30 Lines Using Node.js blog post.

Chat test

Blog posts

Testing a Socket.io chat application can be done in several ways. Read the following blog posts to see the alternatives.

Title Description
Test a Socket.io Chat App using Cypress Simulates the second user by connecting to the chat server from the plugins file
Run Two Cypress Test Runners At The Same Time Launches two test runners, giving them separate specs to run
Sync Two Cypress Runners via Checkpoints Launches two test runners, which stay in sync by communicating via their own Socket.io server
Code Coverage For Chat App Instruments and measures the fullstack code coverage

Flip through the presentation slides E2E Testing For A Real-Time Chat Web Application

Specs

Name Description
first-spec Tests that the user can post a message and see it
random-name-spec.js Creates a random user name for the test
client-api-spec.js Invokes events as a 2nd user using app actions
socket-spec.js Mimics the 2nd user by connecting to the Socket.io server from the plugin file
socket-from-browser-spec.js Mimics the 2nd user by connecting to the Socket.io server from the spec file
mock-socket-spec.js The test forces the app to use a mock socket object instead of the real connection, see video
disconnect-spec.js Checks if the user disconnects correctly

Running 2 Cypress instances

This repo also shows how to run 2 Cypress instances at the same time to "really" chat with each other.

  • start the server with npm start
  • execute npm run chat:run which starts the two Cypress processes

Look at the package.json file to see the commands we use to run the first and second user specs - they are listed in cy-first-user.json and cy-second-user.json config files.

The test runners wait for each other using a common Socket.io server created in the chat.js script. This is a separate Socket.io server from the application.

Test communication

The first server logs in and reports that it is ready for the second test to start

// cypress/pair/first-user.js
/// <reference types="cypress" />

// this test behaves as the first user to join the chat
it('chats with the second user', () => {
  const name = 'First'
  const secondName = 'Second'

  cy.visit('/', {
    onBeforeLoad(win) {
      cy.stub(win, 'prompt').returns(name)
    },
  })

  // make sure the greeting message is shown
  cy.contains('#messages li i', `${name} join the chat..`).should('be.visible')
  cy.task('checkpoint', 'first user has joined')
})

The second test runner executes its own test. It first waits for the checkpoint before visiting the page

// cypress/pair/second-user.js
/// <reference types="cypress" />

// this test behaves as the second user to join the chat
it('chats with the first user', () => {
  cy.task('waitForCheckpoint', 'first user has joined')

  const name = 'Second'
  // we are chatting with the first user
  const firstName = 'First'
  cy.visit('/', {
    onBeforeLoad(win) {
      cy.stub(win, 'prompt').returns(name)
    },
  })
})

Code coverage

Added instrumenting front-end code using istanbul-lib-instrument module, see index.js file. Read the blog post Code Coverage For Chat App.

Fullstack code coverage

Note: I did not use Istanbul middleware because it seemed to not support ES6 syntax (the middleware module had no releases for a long time).

About

Example testing real-time Socket.io chat using Cypress.io

https://slides.com/bahmutov/e2e-for-chat


Languages

Language:JavaScript 93.5%Language:EJS 6.5%