Skip to content
This repository was archived by the owner on Jul 14, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ src/version.ts
node_modules/
.idea
octomind.config.json
octomind-cli-debug/
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const jestConfig: jest.Config = {
testMatch: ["**/tests/**/*.spec.ts"],
testPathIgnorePatterns: ["dist", "node_modules"],
testTimeout: 20_000,
watchPathIgnorePatterns: ["temp"],
watchPathIgnorePatterns: ["octomind-cli-debug"],
prettierPath: null, //https://github.com/jestjs/jest/issues/14305 -> jest 30 will support it
};

Expand Down
46 changes: 25 additions & 21 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const buildCmd = (): Command => {
program
.name("octomind-cli")
.description(
`Octomind CLI tool. Version: ${version}. see https://octomind.dev/docs/api-reference/`
`Octomind CLI tool. Version: ${version}. see https://octomind.dev/docs/api-reference/`,
)
.version(version);

Expand All @@ -55,7 +55,7 @@ export const buildCmd = (): Command => {
if (existingConfig.apiKey && !options.force) {
console.log("⚠️ Configuration already exists.");
const overwrite = await promptUser(
"Do you want to overwrite it? (y/N): "
"Do you want to overwrite it? (y/N): ",
);

if (
Expand All @@ -70,7 +70,7 @@ export const buildCmd = (): Command => {
let apiKey;
if (!options.apiKey) {
apiKey = await promptUser(
"Enter your API key. Go to https://octomind.dev/docs/run-tests/execution-curl#create-an-api-key to learn how to generate one: "
"Enter your API key. Go to https://octomind.dev/docs/run-tests/execution-curl#create-an-api-key to learn how to generate one: ",
);
if (!apiKey) {
console.log("❌ API key is required.");
Expand All @@ -80,7 +80,7 @@ export const buildCmd = (): Command => {
let testTargetId;
if (!options.testTargetId) {
testTargetId = await promptUser(
"Enter test target id (optional, press Enter to skip): "
"Enter test target id (optional, press Enter to skip): ",
);
}

Expand All @@ -96,35 +96,39 @@ export const buildCmd = (): Command => {
} catch (error) {
console.error(
"❌ Error during initialization:",
(error as Error).message
(error as Error).message,
);
process.exit(1);
}
}
},
);

createCommandWithCommonOptions("debug")
.description("run test cases against local build")
.requiredOption("-u, --url <url>", "url the tests should run against")
.option(
"-i, --id <uuid>",
"id of the test case you want to run, if not provided will run all test cases in the test target"
"id of the test case you want to run, if not provided will run all test cases in the test target",
)
.option(
"-e, --environmentId <uuid>",
"id of the environment you want to run against, if not provided will run all test cases against the default environment"
"id of the environment you want to run against, if not provided will run all test cases against the default environment",
)
.option(
"-a, --testTargetId <uuid>",
"id of the test target of the test case"
"id of the test target of the test case",
)
.option(
"--headless",
"if we should run headless without the UI of playwright and the browser"
"if we should run headless without the UI of playwright and the browser",
)
.option(
"--persist",
"if we should write playwright config and files to current directory, you can then run 'npx playwright test' to run them again",
)
.action(async (options, command) => {
const resolvedTestTargetId = await resolveTestTargetId(
options.testTargetId
options.testTargetId,
);
command.setOptionValue("testTargetId", resolvedTestTargetId);
void runDebugtopus(options);
Expand All @@ -140,7 +144,7 @@ export const buildCmd = (): Command => {
.option(
"-v, --variables-to-overwrite <variables>",
"JSON object of variables to overwrite",
toJSON
toJSON,
)
.action(async (options) => {
const testTargetId = await resolveTestTargetId(options.testTargetId);
Expand Down Expand Up @@ -184,7 +188,7 @@ export const buildCmd = (): Command => {
.option("-t, --test-target-id <id>", "Test target ID")
.action(async (options, command) => {
const resolvedTestTargetId = await resolveTestTargetId(
options.testTargetId
options.testTargetId,
);
command.setOptionValue("testTargetId", resolvedTestTargetId);
void listEnvironments(options);
Expand All @@ -199,7 +203,7 @@ export const buildCmd = (): Command => {
.option("--test-account-password <password>", "Test account password")
.option(
"--test-account-otp-initializer-key <key>",
"Test account OTP initializer key"
"Test account OTP initializer key",
)
.option("--basic-auth-username <username>", "Basic auth username")
.option("--basic-auth-password <password>", "Basic auth password")
Expand All @@ -208,7 +212,7 @@ export const buildCmd = (): Command => {
createEnvironment({
...options,
testTargetId: await resolveTestTargetId(options.testTargetId),
})
}),
);

createCommandWithCommonOptions("update-environment")
Expand All @@ -221,7 +225,7 @@ export const buildCmd = (): Command => {
.option("--test-account-password <password>", "Test account password")
.option(
"--test-account-otp-initializer-key <key>",
"Test account OTP initializer key"
"Test account OTP initializer key",
)
.option("--basic-auth-username <username>", "Basic auth username")
.option("--basic-auth-password <password>", "Basic auth password")
Expand All @@ -230,7 +234,7 @@ export const buildCmd = (): Command => {
updateEnvironment({
...options,
testTargetId: await resolveTestTargetId(options.testTargetId),
})
}),
);

createCommandWithCommonOptions("delete-environment")
Expand All @@ -244,7 +248,7 @@ export const buildCmd = (): Command => {
.option("-t, --test-target-id <id>", "Test target ID")
.action(async (options, command) => {
const resolvedTestTargetId = await resolveTestTargetId(
options.testTargetId
options.testTargetId,
);
command.setOptionValue("testTargetId", resolvedTestTargetId);
void getNotifications(options);
Expand All @@ -256,7 +260,7 @@ export const buildCmd = (): Command => {
.option("-t, --test-target-id <id>", "Test target ID")
.action(async (options, command) => {
const resolvedTestTargetId = await resolveTestTargetId(
options.testTargetId
options.testTargetId,
);
command.setOptionValue("testTargetId", resolvedTestTargetId);
void getTestCase(options);
Expand All @@ -273,12 +277,12 @@ export const buildCmd = (): Command => {
.option(
"--assigned-tag-ids <ids>",
"Comma-separated list of tag IDs",
splitter
splitter,
)
.option("--folder-id <id>", "Folder ID")
.action(async (options, command) => {
const resolvedTestTargetId = await resolveTestTargetId(
options.testTargetId
options.testTargetId,
);
command.setOptionValue("testTargetId", resolvedTestTargetId);
void createDiscovery(options);
Expand Down
7 changes: 5 additions & 2 deletions src/debugtopus/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type DebugtopusOptions = {
url: string;
environmentId?: string;
headless?: boolean;
persist?: boolean;
};

const getPackageRootLevel = (appDir: string): string => {
Expand Down Expand Up @@ -72,7 +73,7 @@ const prepareDirectories = async (
packageRootDir = getPackageRootLevel(appDir);
}

const tempDir = path.join(packageRootDir, "temp");
const tempDir = path.join(packageRootDir, "octomind-cli-debug");

if (existsSync(tempDir)) {
await fs.rm(tempDir, { force: true, recursive: true });
Expand Down Expand Up @@ -208,7 +209,9 @@ export const runDebugtopus = async (options: DebugtopusOptions) => {
throw new Error("no environment found");
}

const dirs = await prepareDirectories();
const dirs = await prepareDirectories(
options.persist ? process.cwd() : undefined,
);

const config = await getPlaywrightConfig({
testTargetId: options.testTargetId,
Expand Down