donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
156 lines • 6.72 kB
JavaScript
"use strict";
///////////////////////////////////////////////////////////
// BEGIN: Special Playwright environment variable setup. //
///////////////////////////////////////////////////////////
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Main = exports.PlaywrightUtils = void 0;
exports.startDonobuServer = startDonobuServer;
// Set environment variables necessary to initialize Playwright browsers
// reliably using the Donobu-installed browsers. This must be done before
// referencing any Playwright code so that that code captures the correct
// environment state. This is obviously a gross hack but the Playwright SDK has
// no clean way to work around this.
process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY = '1';
const MiscUtils_1 = require("./utils/MiscUtils");
const path_1 = __importDefault(require("path"));
const envVars_1 = require("./envVars");
if (process.env[envVars_1.ENV_VAR_NAMES.USE_PACKAGED_PLAYWRIGHT_BROWSERS]) {
process.env.PLAYWRIGHT_BROWSERS_PATH = path_1.default.join(MiscUtils_1.MiscUtils.baseWorkingDirectory(), '.playwright');
}
/////////////////////////////////////////////////////////
// END: Special Playwright environment variable setup. //
/////////////////////////////////////////////////////////
///////////////////////////////////
// BEGIN: Process handler setup. //
///////////////////////////////////
const Logger_1 = require("./utils/Logger");
const JsonUtils_1 = require("./utils/JsonUtils");
process.on('unhandledRejection', async (reason, promise) => {
const errorDetails = JSON.stringify(JsonUtils_1.JsonUtils.objectToJson({
reason: reason instanceof Error
? {
message: reason.message,
name: reason.name,
stack: reason.stack,
}
: reason,
promise: promise,
}), null, 2);
Logger_1.appLogger.error(`Unhandled Promise Rejection: ${errorDetails}`);
process.exit(1);
});
process.on('uncaughtException', async (error) => {
const errorDetails = JSON.stringify(JsonUtils_1.JsonUtils.objectToJson({
message: error.message,
name: error.name,
stack: error.stack,
}), null, 2);
Logger_1.appLogger.error(`Uncaught Exception: ${errorDetails}`);
process.exit(1);
});
['SIGTERM', 'SIGINT', 'SIGHUP'].forEach((signal) => {
process.on(signal, async () => {
Logger_1.appLogger.info(`Received ${signal}, shutting down...`);
process.exit(0);
});
});
/////////////////////////////////
// END: Process handler setup. //
/////////////////////////////////
const AdminApiController_1 = require("./managers/AdminApiController");
const commander_1 = require("commander");
const PlaywrightUtils_1 = require("./utils/PlaywrightUtils");
const DonobuDeploymentEnvironment_1 = require("./models/DonobuDeploymentEnvironment");
const DEFAULT_PORT = 31000;
var PlaywrightUtils_2 = require("./utils/PlaywrightUtils");
Object.defineProperty(exports, "PlaywrightUtils", { enumerable: true, get: function () { return PlaywrightUtils_2.PlaywrightUtils; } });
__exportStar(require("./playwrightTestExtensions"), exports);
__exportStar(require("./utils/MiscUtils"), exports);
__exportStar(require("./utils/Logger"), exports);
function divineDeploymentEnvironment() {
const donobuDeploymentEnvironmentStr = process.env[envVars_1.ENV_VAR_NAMES.DONOBU_DEPLOYMENT_ENVIRONMENT];
if (donobuDeploymentEnvironmentStr) {
return DonobuDeploymentEnvironment_1.DonobuDeploymentEnvironment[donobuDeploymentEnvironmentStr];
}
return DonobuDeploymentEnvironment_1.DonobuDeploymentEnvironment.LOCAL;
}
/**
* Starts a Donobu API server at the given port. The server assumes that the
* Playwright browsers have been installed.
*/
async function startDonobuServer(port = DEFAULT_PORT) {
try {
const adminController = await AdminApiController_1.AdminApiController.create(divineDeploymentEnvironment());
adminController.start(port);
Logger_1.appLogger.info(`Donobu API server available on http://localhost:${port}`);
process.on('SIGINT', async () => {
adminController.stop();
process.exit(0);
});
// Keep the process running
await new Promise(() => { });
}
catch (e) {
Logger_1.appLogger.error('Exception while running server', e);
process.exit(1);
}
}
/**
* This is the main entrypoint of the program. If you are looking for real
* business logic then see the DonobuFlow class.
*/
class Main {
/**
* Starts the program, ensures that the Playwright browsers are installed and
* starts the API server.
*/
static async main(args) {
const program = new commander_1.Command();
program
.option('--port <number>', `The port to run the API on. Defaults to ${DEFAULT_PORT}.`)
.option('--only-install-browsers-and-quit', 'Only install the Playwright browsers and quit.')
.parse(args);
const options = program.opts();
if (options.onlyInstallBrowsersAndQuit) {
await PlaywrightUtils_1.PlaywrightUtils.ensurePlaywrightInstallation();
process.exit(0);
}
const port = this.parsePort(options.port);
await PlaywrightUtils_1.PlaywrightUtils.ensurePlaywrightInstallation();
await startDonobuServer(port);
}
static parsePort(port) {
const parsedPort = port ? parseInt(port, 10) : DEFAULT_PORT;
if (isNaN(parsedPort)) {
Logger_1.appLogger.info(`Invalid port: ${port}`);
process.exit(1);
}
return parsedPort;
}
}
exports.Main = Main;
// If this file is being run directly
if (require.main === module) {
Main.main(process.argv).catch((e) => {
Logger_1.appLogger.error('Unhandled error in main', e);
process.exit(1);
});
}
//# sourceMappingURL=main.js.map