diff --git a/app/client/cypress/scripts/cypress-local-setup.js b/app/client/cypress/scripts/cypress-local-setup.js index 72c6a47370..e8424e0834 100644 --- a/app/client/cypress/scripts/cypress-local-setup.js +++ b/app/client/cypress/scripts/cypress-local-setup.js @@ -1,13 +1,12 @@ -const { execSync } = require("child_process"); +const { exec, execSync } = require("child_process"); const { existsSync, readFileSync, writeFileSync } = require("fs"); const path = require("path"); const prompt = require("prompt-sync")(); -// Function to check if a Docker container is running function isContainerRunning(containerName) { try { const output = execSync( - `docker ps --format '{{.Names}}' | grep -w "${containerName}"`, + `docker ps --filter "name=^/${containerName}$" --format '{{.Names}}'`, ); return output.length > 0; } catch (error) { @@ -15,6 +14,98 @@ function isContainerRunning(containerName) { } } +// Helper function to execute commands and return a Promise +async function execCommand(command, options) { + return new Promise((resolve, reject) => { + exec(command, options, (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve({ stdout, stderr }); + } + }); + }); +} + +function checkDockerCompose() { + try { + execSync("docker-compose --version", { stdio: "ignore" }); + return true; + } catch (error) { + console.error( + "ERROR: docker-compose is not installed. Please install Docker Compose.", + ); + process.exit(1); + } +} + +async function runLocalServer() { + try { + let user_input = prompt( + `Do you wish to continue without setting up the local server with docker? (yes/no): `, + ); + user_input = (user_input || "").trim().toLowerCase(); + + if (user_input === "yes" || user_input === "y") { + console.log( + "INFO", + "Continuing without setting up local backend docker based server.", + ); + } else { + // Adjust the path to point to the correct directory + const dockerDir = path.join(__dirname, "../../../../deploy/docker"); + + if (!existsSync(dockerDir)) { + console.error(`ERROR: Directory ${dockerDir} does not exist.`); + process.exit(1); // Exit if the directory is missing + } + + await checkDockerCompose(); // Ensure Docker Compose is available + + console.log("INFO: Starting local server using Docker Compose..."); + execSync(`cd ${dockerDir} && pwd && docker-compose up -d`, { + stdio: "inherit", + }); + + // Wait for the services to be fully up and running + let servicesRunning = false; + const maxRetries = 30; + const retryInterval = 7000; // 7 seconds + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const { stdout } = await execCommand("docker-compose ps", { + cwd: dockerDir, + }); + if (stdout.includes("Up")) { + servicesRunning = true; + break; + } + } catch (error) { + console.error("ERROR: Error checking service status:", error.message); + process.exit(1); // Exit if checking service status fails + } + console.log( + `INFO: Waiting for services to be fully up and running... (attempt ${attempt}/${maxRetries})`, + ); + await new Promise((resolve) => setTimeout(resolve, retryInterval)); + } + if (servicesRunning) { + console.log("INFO: Local server is up and running."); + return true; + } else { + console.error( + "ERROR: Services did not become available within the expected time.", + ); + process.exit(1); // Exit if services are not up + } + } + } catch (error) { + console.error("ERROR: Error starting local server:", error.message); + process.exit(1); // Exit if starting local server fails + } +} + function ensureTEDIsRunning() { // Check if TED is running. If not, then ask user if they wish to pull and run the TED container const isTedRunning = isContainerRunning("ted"); @@ -147,7 +238,7 @@ async function setupCypress() { // Get the baseUrl from cypress.config.ts file let repoRoot = path.join(__dirname, "..", ".."); let baseUrl = getBaseUrl(repoRoot); - + await runLocalServer(); await checkIfAppsmithIsRunning(baseUrl); // Install Cypress using yarn install on the app/client repository