UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

120 lines (108 loc) 3.79 kB
import _ from 'lodash'; import url from 'url'; const DEFAULT_WS_PATHNAME_PREFIX = '/ws'; /** * Adds websocket handler to express server instance. * It is expected this function is called in Express * server instance context. * * @param {Object} server - An instance of express HTTP server. * @param {string} handlerPathname - Web socket endpoint path starting with * a single slash character. It is recommended to always add * DEFAULT_WS_PATHNAME_PREFIX to all web socket pathnames. * @param {Object} handlerServer - WebSocket server instance. See * https://github.com/websockets/ws/pull/885 for more details * on how to configure the handler properly. */ async function addWebSocketHandler (handlerPathname, handlerServer) { // eslint-disable-line require-await let isUpgradeListenerAssigned = true; if (_.isUndefined(this.webSocketsMapping)) { this.webSocketsMapping = {}; isUpgradeListenerAssigned = false; } this.webSocketsMapping[handlerPathname] = handlerServer; if (isUpgradeListenerAssigned) { return; } // https://github.com/websockets/ws/pull/885 this.on('upgrade', (request, socket, head) => { const currentPathname = url.parse(request.url).pathname; for (const [pathname, wsServer] of _.toPairs(this.webSocketsMapping)) { if (currentPathname === pathname) { wsServer.handleUpgrade(request, socket, head, (ws) => { wsServer.emit('connection', ws, request); }); return; } } socket.destroy(); }); } /** * Returns web socket handlers registered for the given server * instance. * It is expected this function is called in Express * server instance context. * * @param {?string} keysFilter [null]- Only include pathnames with given * `keysFilter` value if set. All pairs will be included by default. * @returns {Object} pathnames to websocket server isntances mapping * matching the search criteria or an empty object otherwise. */ async function getWebSocketHandlers (keysFilter = null) { // eslint-disable-line require-await if (_.isEmpty(this.webSocketsMapping)) { return {}; } let result = {}; for (const [pathname, wsServer] of _.toPairs(this.webSocketsMapping)) { if (!_.isString(keysFilter) || pathname.includes(keysFilter)) { result[pathname] = wsServer; } } return result; } /** * Removes existing websocket handler from express server instance. * The call is ignored if the given `handlerPathname` handler * is not present in the handlers list. * It is expected this function is called in Express * server instance context. * * @param {string} handlerPathname - Websocket endpoint path. * @returns {boolean} true if the handlerPathname was found and deleted */ async function removeWebSocketHandler (handlerPathname) { // eslint-disable-line require-await if (!this.webSocketsMapping || !this.webSocketsMapping[handlerPathname]) { return false; } try { this.webSocketsMapping[handlerPathname].close(); return true; } catch (ign) { // ignore } finally { delete this.webSocketsMapping[handlerPathname]; } return false; } /** * Removes all existing websocket handler from express server instance. * It is expected this function is called in Express * server instance context. * * @returns {boolean} true if at least one handler has been deleted */ async function removeAllWebSocketHandlers () { if (_.isEmpty(this.webSocketsMapping)) { return false; } let result = false; for (const pathname of _.keys(this.webSocketsMapping)) { result = result || await this.removeWebSocketHandler(pathname); } return result; } export { addWebSocketHandler, removeWebSocketHandler, removeAllWebSocketHandlers, getWebSocketHandlers, DEFAULT_WS_PATHNAME_PREFIX, };