Merge pull request #11 from amhsirak/develop
feat: record & workflow routes
This commit is contained in:
9
server/src/routes/index.ts
Normal file
9
server/src/routes/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { router as record } from './record';
|
||||||
|
import { router as workflow } from './workflow';
|
||||||
|
import { router as storage } from './storage';
|
||||||
|
|
||||||
|
export {
|
||||||
|
record,
|
||||||
|
workflow,
|
||||||
|
storage,
|
||||||
|
};
|
||||||
113
server/src/routes/record.ts
Normal file
113
server/src/routes/record.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* RESTful API endpoints handling remote browser recording sessions.
|
||||||
|
*/
|
||||||
|
import { Router } from 'express';
|
||||||
|
|
||||||
|
import {
|
||||||
|
initializeRemoteBrowserForRecording,
|
||||||
|
destroyRemoteBrowser,
|
||||||
|
getActiveBrowserId,
|
||||||
|
interpretWholeWorkflow,
|
||||||
|
stopRunningInterpretation,
|
||||||
|
getRemoteBrowserCurrentUrl, getRemoteBrowserCurrentTabs,
|
||||||
|
} from '../browser-management/controller'
|
||||||
|
import { chromium } from "playwright";
|
||||||
|
import logger from "../logger";
|
||||||
|
|
||||||
|
export const router = Router();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs information about remote browser recording session.
|
||||||
|
*/
|
||||||
|
router.all('/', (req, res, next) => {
|
||||||
|
logger.log('debug', `The record API was invoked: ${req.url}`)
|
||||||
|
next() // pass control to the next handler
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for starting the remote browser recording session.
|
||||||
|
* returns session's id
|
||||||
|
*/
|
||||||
|
router.get('/start', (req, res) => {
|
||||||
|
const id = initializeRemoteBrowserForRecording({
|
||||||
|
browser: chromium,
|
||||||
|
launchOptions: {
|
||||||
|
headless: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res.send(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST endpoint for starting the remote browser recording session accepting browser launch options.
|
||||||
|
* returns session's id
|
||||||
|
*/
|
||||||
|
router.post('/start', (req, res) => {
|
||||||
|
const id = initializeRemoteBrowserForRecording({
|
||||||
|
browser: chromium,
|
||||||
|
launchOptions: req.body,
|
||||||
|
});
|
||||||
|
return res.send(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for terminating the remote browser recording session.
|
||||||
|
* returns whether the termination was successful
|
||||||
|
*/
|
||||||
|
router.get('/stop/:browserId', async (req, res) => {
|
||||||
|
const success = await destroyRemoteBrowser(req.params.browserId);
|
||||||
|
return res.send(success);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for getting the id of the active remote browser.
|
||||||
|
*/
|
||||||
|
router.get('/active', (req, res) => {
|
||||||
|
const id = getActiveBrowserId();
|
||||||
|
return res.send(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for getting the current url of the active remote browser.
|
||||||
|
*/
|
||||||
|
router.get('/active/url', (req, res) => {
|
||||||
|
const id = getActiveBrowserId();
|
||||||
|
if (id) {
|
||||||
|
const url = getRemoteBrowserCurrentUrl(id);
|
||||||
|
return res.send(url);
|
||||||
|
}
|
||||||
|
return res.send(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for getting the current tabs of the active remote browser.
|
||||||
|
*/
|
||||||
|
router.get('/active/tabs', (req, res) => {
|
||||||
|
const id = getActiveBrowserId();
|
||||||
|
if (id) {
|
||||||
|
const hosts = getRemoteBrowserCurrentTabs(id);
|
||||||
|
return res.send(hosts);
|
||||||
|
}
|
||||||
|
return res.send([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for starting an interpretation of the currently generated workflow.
|
||||||
|
*/
|
||||||
|
router.get('/interpret', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await interpretWholeWorkflow();
|
||||||
|
return res.send('interpretation done');
|
||||||
|
} catch (e) {
|
||||||
|
return res.send('interpretation done');
|
||||||
|
return res.status(400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for stopping an ongoing interpretation of the currently generated workflow.
|
||||||
|
*/
|
||||||
|
router.get('/interpret/stop', async (req, res) => {
|
||||||
|
await stopRunningInterpretation();
|
||||||
|
return res.send('interpretation stopped');
|
||||||
|
});
|
||||||
123
server/src/routes/workflow.ts
Normal file
123
server/src/routes/workflow.ts
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* RESTful API endpoints handling currently generated workflow management.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Router } from 'express';
|
||||||
|
import logger from "../logger";
|
||||||
|
import { browserPool } from "../server";
|
||||||
|
import { readFile } from "../workflow-management/storage";
|
||||||
|
|
||||||
|
export const router = Router();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs information about workflow API.
|
||||||
|
*/
|
||||||
|
router.all('/', (req, res, next) => {
|
||||||
|
logger.log('debug', `The workflow API was invoked: ${req.url}`)
|
||||||
|
next() // pass control to the next handler
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint for a recording linked to a remote browser instance.
|
||||||
|
* returns session's id
|
||||||
|
*/
|
||||||
|
router.get('/:browserId', (req, res) => {
|
||||||
|
const activeBrowser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||||
|
let workflowFile = null;
|
||||||
|
if (activeBrowser && activeBrowser.generator) {
|
||||||
|
workflowFile = activeBrowser.generator.getWorkflowFile();
|
||||||
|
}
|
||||||
|
return res.send(workflowFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get endpoint returning the parameter array of the recording associated with the browserId browser instance.
|
||||||
|
*/
|
||||||
|
router.get('/params/:browserId', (req, res) => {
|
||||||
|
const activeBrowser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||||
|
let params = null;
|
||||||
|
if (activeBrowser && activeBrowser.generator) {
|
||||||
|
params = activeBrowser.generator.getParams();
|
||||||
|
}
|
||||||
|
return res.send(params);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE endpoint for deleting a pair from the generated workflow.
|
||||||
|
*/
|
||||||
|
router.delete('/pair/:index', (req, res) => {
|
||||||
|
const id = browserPool.getActiveBrowserId();
|
||||||
|
if (id) {
|
||||||
|
const browser = browserPool.getRemoteBrowser(id);
|
||||||
|
if (browser) {
|
||||||
|
browser.generator?.removePairFromWorkflow(parseInt(req.params.index));
|
||||||
|
const workflowFile = browser.generator?.getWorkflowFile();
|
||||||
|
return res.send(workflowFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.send(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST endpoint for adding a pair to the generated workflow.
|
||||||
|
*/
|
||||||
|
router.post('/pair/:index', (req, res) => {
|
||||||
|
const id = browserPool.getActiveBrowserId();
|
||||||
|
if (id) {
|
||||||
|
const browser = browserPool.getRemoteBrowser(id);
|
||||||
|
logger.log('debug', `Adding pair to workflow`);
|
||||||
|
if (browser) {
|
||||||
|
logger.log('debug', `Adding pair to workflow: ${JSON.stringify(req.body)}`);
|
||||||
|
if (req.body.pair) {
|
||||||
|
browser.generator?.addPairToWorkflow(parseInt(req.params.index), req.body.pair);
|
||||||
|
const workflowFile = browser.generator?.getWorkflowFile();
|
||||||
|
return res.send(workflowFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.send(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT endpoint for updating a pair in the generated workflow.
|
||||||
|
*/
|
||||||
|
router.put('/pair/:index', (req, res) => {
|
||||||
|
const id = browserPool.getActiveBrowserId();
|
||||||
|
if (id) {
|
||||||
|
const browser = browserPool.getRemoteBrowser(id);
|
||||||
|
logger.log('debug', `Updating pair in workflow`);
|
||||||
|
if (browser) {
|
||||||
|
logger.log('debug', `New value: ${JSON.stringify(req.body)}`);
|
||||||
|
if (req.body.pair) {
|
||||||
|
browser.generator?.updatePairInWorkflow(parseInt(req.params.index), req.body.pair);
|
||||||
|
const workflowFile = browser.generator?.getWorkflowFile();
|
||||||
|
return res.send(workflowFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.send(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT endpoint for updating the currently generated workflow file from the one in the storage.
|
||||||
|
*/
|
||||||
|
router.put('/:browserId/:fileName', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const browser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||||
|
logger.log('debug', `Updating workflow file`);
|
||||||
|
if (browser && browser.generator) {
|
||||||
|
const recording = await readFile(`./../storage/recordings/${req.params.fileName}.waw.json`)
|
||||||
|
const parsedRecording = JSON.parse(recording);
|
||||||
|
if (parsedRecording.recording) {
|
||||||
|
browser.generator?.updateWorkflowFile(parsedRecording.recording, parsedRecording.recording_meta);
|
||||||
|
const workflowFile = browser.generator?.getWorkflowFile();
|
||||||
|
return res.send(workflowFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.send(null);
|
||||||
|
} catch (e) {
|
||||||
|
const { message } = e as Error;
|
||||||
|
logger.log('info', `Error while reading a recording with name: ${req.params.fileName}.waw.json`);
|
||||||
|
return res.send(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user