cro-development-tool
Version:
A tool to quickly developer CRO tests with your favorite editor, using live reload, with SCSS and ES6 support
165 lines (131 loc) • 4.2 kB
text/typescript
/**
* Om onze testen nog sneller te developen een klein servertje wat een socket start
* Als je de chrome plugin installeert, krijg je live injectie / reload van je CRO test code.
*
* @author Jonas van Ineveld
*/
// server
import { fetchEntryPoints, rootDir, currentConfig, getInfoFromPath, createTestId, getFile, getTestPath } from './helpers.js';
import path from 'path';
import { createServer } from "http";
import { Server, Socket } from "socket.io";
export class liveReload {
activeTests = []
urls = []
url_info = []
requestTestFiles = null
subscribers = {}
server: Server
constructor(requestTestFiles) {
this.requestTestFiles = requestTestFiles;
const httpServer = createServer();
this.server = new Server(httpServer, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
this.server.on("connection", (socket: Socket) => this.newConnection(socket));
httpServer.listen(6589);
}
createSocketHandlers(socket){
socket.on('hello', () => {
socket.emit('hello')
});
socket.on('get_projects_tree', () => {
socket.emit('projects_tree', fetchEntryPoints())
});
socket.on('get_test_info', async data => {
let testPath = data.testPath,
info = await getInfoFromPath(path.join(rootDir, currentConfig.rootDir, testPath));
setTimeout(() => socket.emit('got_test_info', { info }), 400);
})
socket.on('subscribe_to_test', ({ test }) => {
this.addSubscriber(test, socket.id)
})
socket.on('fetch_prod_css_content', ({test}) => {
let cssFile = path.join(getTestPath(test), 'generated','prod', 'output.css')
socket.emit('css_file_contents', getFile(cssFile));
})
socket.on('fetch_prod_js_content', ({test}) => {
let jsFile = path.join(getTestPath(test), 'generated','prod', 'output.js')
socket.emit('js_file_contents', getFile(jsFile));
})
socket.on('disconnect', socket => {
this.removeSubscriber(socket.id)
})
}
addSubscriber(test, socketId){
let testId = createTestId(test)
if(! this.subscribers[testId]){
this.subscribers[testId] = []
}
this.subscribers[testId].push(socketId)
this.sendInitialUpdate(socketId, test)
}
removeSubscriber(socketId){
let activeTests = Object.keys(this.subscribers);
for(let testId of activeTests){
this.subscribers[testId] = this.subscribers[testId].filter(subSocketId => subSocketId!==socketId)
}
}
disconnectHandler(index){
this.activeTests = this.activeTests.splice(index,1)
}
activateTest(test, socket){
let newLenth = this.activeTests.push({ ...test, id: socket.id });
socket.on('disconnect', () => {
this.disconnectHandler(newLenth-1)
});
this.sendInitialUpdate(socket.id, test)
}
toggleTest(testToActivate){
// console.log('cooowl', testToActivate)
}
testIsActive(testInfo){
// console.log('checking if test is active', testInfo)
let testId = createTestId(testInfo)
if(this.subscribers[testId]){
// console.log('found subscribers', this.subscribers)
return this.subscribers[testId].length ? this.subscribers[testId] : false
}
// console.log('no subscribers', testId)
return false;
}
newConnection(socket){
try {
let request_url = socket.request._query.path
this.createSocketHandlers(socket);
if(request_url==='devtools'){
let points = fetchEntryPoints();
socket.emit('projects_tree', points);
}
} catch (error) {
console.error(error);
}
}
async sendInitialUpdate(socket_id, test) {
let data = await this.requestTestFiles(test)
this.server.to(socket_id).emit('initial_resources', { ...data, customer: test.customer, test: test.test, variation: test.variation });
}
sendCSSUpdate(css, testInfo){
const activeTests = this.testIsActive(testInfo);
if(!activeTests){
return;
}
for(let activeTest of activeTests){
// console.log('updating client', activeTest.id)
this.server.to(activeTest).emit('css_updated', { css, test: testInfo });
}
}
sendJSUpdate(js, testInfo){
const activeTests = this.testIsActive(testInfo);
if(!activeTests){
return;
}
// console.log('sending js updates', testInfo)
for(let activeTest of activeTests){
this.server.to(activeTest).emit('js_updated', js);
}
}
}