diff --git a/src/cli.ts b/src/cli.ts index c451950..1e8b77d 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -181,8 +181,8 @@ export const buildCmd = (): CompletableCommand => { .helpGroup("execute") .requiredOption("-u, --url ", "Url the tests should run against") .option( - "-c, --test-case-id [uuid]", - "Id of the test case you want to run, if not provided will run all test cases in the test target", + "-p, --test-case-path [string]", + "Path of the test case you want to run, if not provided will run all test cases in the test target", ) .option( "-e, --environment-id [uuid]", @@ -420,7 +420,7 @@ export const buildCmd = (): CompletableCommand => { ) .addOption( new Option( - "-d, --dependency-path ", + "-d, --dependency-path [path]", "The path of to test case you want to use as dependency", ), ) diff --git a/src/debugtopus/index.ts b/src/debugtopus/index.ts index 29ffe8a..05ad042 100644 --- a/src/debugtopus/index.ts +++ b/src/debugtopus/index.ts @@ -12,7 +12,10 @@ import ora from "ora"; import { Open } from "unzipper"; import { OCTOMIND_FOLDER_NAME } from "../constants"; -import { findOctomindFolder } from "../helpers"; +import { + findOctomindFolder, + getAbsoluteFilePathInOctomindRoot, +} from "../helpers"; import { getEnvironments, getPlaywrightCode, @@ -21,7 +24,7 @@ import { } from "../tools"; import { client, handleError } from "../tools/client"; import { SyncTestCase } from "../tools/sync/types"; -import { readTestCasesFromDir } from "../tools/sync/yaml"; +import { loadTestCase, readTestCasesFromDir } from "../tools/sync/yaml"; import { getRelevantTestCases } from "../tools/yamlMutations/getRelevantTestCases"; import { ensureChromiumIsInstalled } from "./installation"; @@ -180,19 +183,39 @@ const runTests = async ({ } }; -const getFilteredTestCaseWithDependencies = ( - testCases: SyncTestCase[], - filterTestCaseId: string, -): SyncTestCase[] => { - const filteredTestCase = testCases.find( - (testCase) => testCase.id === filterTestCaseId, - ); +const getFilteredTestCaseWithDependencies = async ({ + testCases, + filterTestCasePath, + octomindRoot, +}: { + testCases: SyncTestCase[]; + filterTestCasePath: string; + octomindRoot: string; +}): Promise<{ + relevantTestCases: SyncTestCase[]; + filterTestCaseId: string; +}> => { + const absoluteTestCaseFilePath = await getAbsoluteFilePathInOctomindRoot({ + octomindRoot, + filePath: filterTestCasePath, + }); + if (!absoluteTestCaseFilePath) { + throw new Error( + `Could not find ${filterTestCasePath} in folder ${octomindRoot}`, + ); + } + + const filteredTestCase = loadTestCase(absoluteTestCaseFilePath); if (!filteredTestCase) { - throw new Error(`Could not find test case with id ${filterTestCaseId}`); + throw new Error(`Could not find test case with id ${filterTestCasePath}`); } const testCasesById = Object.fromEntries(testCases.map((tc) => [tc.id, tc])); - return getRelevantTestCases(testCasesById, filteredTestCase); + const relevantTestCases = getRelevantTestCases( + testCasesById, + filteredTestCase, + ); + return { relevantTestCases, filterTestCaseId: filteredTestCase.id }; }; export const runDebugtopus = async (options: DebugtopusOptions) => { @@ -284,7 +307,7 @@ export const runDebugtopus = async (options: DebugtopusOptions) => { }; export const executeLocalTestCases = async ( - options: DebugtopusOptions, + options: Omit & { testCasePath?: string }, ): Promise => { const octomindRoot = await findOctomindFolder(); if (!octomindRoot) { @@ -296,11 +319,15 @@ export const executeLocalTestCases = async ( const throbber = ora("Generating code").start(); let testCases = readTestCasesFromDir(octomindRoot); - if (options.testCaseId) { - testCases = getFilteredTestCaseWithDependencies( + let filterTestCaseId: string | undefined = undefined; + if (options.testCasePath) { + const filtered = await getFilteredTestCaseWithDependencies({ testCases, - options.testCaseId, - ); + filterTestCasePath: options.testCasePath, + octomindRoot, + }); + testCases = filtered.relevantTestCases; + filterTestCaseId = filtered.filterTestCaseId; } const body = { @@ -308,7 +335,7 @@ export const executeLocalTestCases = async ( testTargetId: options.testTargetId, executionUrl: options.url, environmentId: options.environmentId, - filterTestCaseIds: options.testCaseId ? [options.testCaseId] : undefined, + filterTestCaseIds: filterTestCaseId ? [filterTestCaseId] : undefined, }; const { error, response } = await client.POST( "/apiKey/beta/test-targets/{testTargetId}/code", diff --git a/tests/debugtopus/index.spec.ts b/tests/debugtopus/index.spec.ts index 4fba22e..17cc1fd 100644 --- a/tests/debugtopus/index.spec.ts +++ b/tests/debugtopus/index.spec.ts @@ -14,10 +14,14 @@ import { readZipFromResponseBody, } from "../../src/debugtopus/index"; import { ensureChromiumIsInstalled } from "../../src/debugtopus/installation"; -import { findOctomindFolder } from "../../src/helpers"; +import { + findOctomindFolder, + getAbsoluteFilePathInOctomindRoot, +} from "../../src/helpers"; import { client } from "../../src/tools/client"; import { getPlaywrightConfig } from "../../src/tools/playwright"; -import { readTestCasesFromDir } from "../../src/tools/sync/yaml"; +import { loadTestCase, readTestCasesFromDir } from "../../src/tools/sync/yaml"; +import { getRelevantTestCases } from "../../src/tools/yamlMutations/getRelevantTestCases"; import { createMockSyncTestCase } from "../mocks"; vi.mock("fs/promises"); @@ -28,6 +32,7 @@ vi.mock("../../src/tools/sync/yaml"); vi.mock("../../src/tools/playwright"); vi.mock("../../src/debugtopus/installation"); vi.mock("../../src/helpers"); +vi.mock("../../src/tools/yamlMutations/getRelevantTestCases"); vi.mock("child_process"); vi.mock("node:stream/promises"); vi.mock("util", () => ({ @@ -46,6 +51,11 @@ const mockedReadTestCasesFromDir = vi.mocked(readTestCasesFromDir); const mockedGetPlaywrightConfig = vi.mocked(getPlaywrightConfig); const mockedEnsureChromiumIsInstalled = vi.mocked(ensureChromiumIsInstalled); +const mockedGetAbsoluteFilePathInOctomindRoot = vi.mocked( + getAbsoluteFilePathInOctomindRoot, +); +const mockedLoadTestCase = vi.mocked(loadTestCase); +const mockedGetRelevantTestCases = vi.mocked(getRelevantTestCases); describe("debugtopus", () => { describe("readZipFromResponseBody", () => { @@ -282,20 +292,35 @@ describe("debugtopus", () => { ); }); - it("should filter test cases by testCaseId when provided", async () => { - setupExecutionMocks(); - mockedReadTestCasesFromDir.mockReturnValue([ + it("should filter test cases by testCaseName when provided", async () => { + const targetTestCase = createMockSyncTestCase({ id: "target-id" }); + const allTestCases = [ createMockSyncTestCase({ id: "other-1" }), - createMockSyncTestCase({ id: "target-id" }), + targetTestCase, createMockSyncTestCase({ id: "other-2" }), - ]); + ]; + + setupExecutionMocks(); + mockedReadTestCasesFromDir.mockReturnValue(allTestCases); + mockedGetAbsoluteFilePathInOctomindRoot.mockResolvedValue( + `${OCTOMIND_ROOT}/target-test.yaml`, + ); + mockedLoadTestCase.mockReturnValue(targetTestCase); + mockedGetRelevantTestCases.mockReturnValue([targetTestCase]); await executeLocalTestCases({ testTargetId: "test-target-id", url: "https://example.com", - testCaseId: "target-id", + testCasePath: "target-test.yaml", }); + expect(mockedGetAbsoluteFilePathInOctomindRoot).toHaveBeenCalledWith({ + octomindRoot: OCTOMIND_ROOT, + filePath: "target-test.yaml", + }); + expect(mockedLoadTestCase).toHaveBeenCalledWith( + `${OCTOMIND_ROOT}/target-test.yaml`, + ); expect(mockedClient.POST).toHaveBeenCalledWith( "/apiKey/beta/test-targets/{testTargetId}/code", expect.objectContaining({ @@ -307,19 +332,22 @@ describe("debugtopus", () => { ); }); - it("should throw an error if testCaseId does not match any test case", async () => { + it("should throw an error if testCaseName file is not found", async () => { vi.mocked(findOctomindFolder).mockResolvedValue(OCTOMIND_ROOT); mockedReadTestCasesFromDir.mockReturnValue([ createMockSyncTestCase({ id: "test-case-1" }), ]); + mockedGetAbsoluteFilePathInOctomindRoot.mockResolvedValue(null); await expect( executeLocalTestCases({ testTargetId: "test-target-id", url: "https://example.com", - testCaseId: "non-existent-id", + testCasePath: "non-existent.yaml", }), - ).rejects.toThrow("Could not find test case with id non-existent-id"); + ).rejects.toThrow( + `Could not find non-existent.yaml in folder ${OCTOMIND_ROOT}`, + ); }); }); });