@empiricalrun/test-gen 0.16.2 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/agent/browsing/index.d.ts +5 -2
  3. package/dist/agent/browsing/index.d.ts.map +1 -1
  4. package/dist/agent/browsing/index.js +7 -4
  5. package/dist/agent/browsing/run.d.ts.map +1 -1
  6. package/dist/agent/browsing/run.js +12 -9
  7. package/dist/agent/codegen/run.d.ts +2 -2
  8. package/dist/agent/codegen/run.d.ts.map +1 -1
  9. package/dist/agent/codegen/run.js +14 -7
  10. package/dist/bin/index.js +7 -3
  11. package/dist/bin/logger/index.js +1 -1
  12. package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
  13. package/dist/bin/utils/platform/web/index.js +11 -1
  14. package/dist/constants/index.d.ts +6 -0
  15. package/dist/constants/index.d.ts.map +1 -0
  16. package/dist/constants/index.js +13 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -2
  19. package/dist/{bin/reporter → reporter}/ci.d.ts +1 -1
  20. package/dist/reporter/ci.d.ts.map +1 -0
  21. package/dist/reporter/index.d.ts +17 -0
  22. package/dist/reporter/index.d.ts.map +1 -0
  23. package/dist/reporter/index.js +62 -0
  24. package/dist/types/index.d.ts +4 -2
  25. package/dist/types/index.d.ts.map +1 -1
  26. package/dist/uploader/index.d.ts +14 -0
  27. package/dist/uploader/index.d.ts.map +1 -0
  28. package/dist/uploader/index.js +52 -0
  29. package/dist/uploader/r2.d.ts +10 -0
  30. package/dist/uploader/r2.d.ts.map +1 -0
  31. package/dist/uploader/r2.js +124 -0
  32. package/dist/utils/exec.d.ts.map +1 -1
  33. package/dist/utils/exec.js +14 -3
  34. package/package.json +7 -2
  35. package/dist/bin/reporter/ci.d.ts.map +0 -1
  36. package/dist/bin/reporter/index.d.ts +0 -4
  37. package/dist/bin/reporter/index.d.ts.map +0 -1
  38. package/dist/bin/reporter/index.js +0 -23
  39. /package/dist/{bin/reporter → reporter}/ci.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.16.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 4c32cf9: feat: add support for uploading test video of browsing agent generated tests
8
+
9
+ ## 0.16.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 8243b11: fix: add logs for errors while running playwright
14
+
3
15
  ## 0.16.2
4
16
 
5
17
  ### Patch Changes
@@ -1,7 +1,10 @@
1
1
  import { Page } from "playwright";
2
- export declare function browsingAgent(task: string, page: Page, options?: {
2
+ import { TestGenConfigOptions } from "../../types";
3
+ type BrowsingAgentOptions = Partial<TestGenConfigOptions> & {
3
4
  htmlSanitize?: {
4
5
  disallowedStrings?: string[];
5
6
  };
6
- }): Promise<string>;
7
+ };
8
+ export declare function browsingAgent(task: string, page: Page, options: BrowsingAgentOptions): Promise<string>;
9
+ export {};
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQlC,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IACP,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACE,mBAyFP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAInD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,mBA4F9B"}
@@ -4,10 +4,11 @@ exports.browsingAgent = void 0;
4
4
  const llm_1 = require("@empiricalrun/llm");
5
5
  const actions_1 = require("../../actions");
6
6
  const logger_1 = require("../../bin/logger");
7
+ const constants_1 = require("../../constants");
7
8
  const session_1 = require("../../session");
8
9
  const html_1 = require("../../utils/html");
9
10
  const utils_1 = require("./utils");
10
- async function browsingAgent(task, page, options = {}) {
11
+ async function browsingAgent(task, page, options) {
11
12
  const logger = new logger_1.CustomLogger();
12
13
  const trace = new llm_1.LLMTracing({
13
14
  name: "browsing-agent",
@@ -43,10 +44,12 @@ async function browsingAgent(task, page, options = {}) {
43
44
  messages,
44
45
  tools,
45
46
  trace,
46
- model: "gpt-4o",
47
- provider: "openai",
47
+ model: options.model || constants_1.DEFAULT_MODEL,
48
+ provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
49
+ providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
48
50
  modelParameters: {
49
- temperature: 0.5,
51
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
52
+ ...options.modelParameters,
50
53
  tool_choice: "required",
51
54
  },
52
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAaA,wBAAsB,+BAA+B,CAAC,YAAY,EAAE,MAAM,iBA0BzE"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAaA,wBAAsB,+BAA+B,CAAC,YAAY,EAAE,MAAM,iBA4BzE"}
@@ -26,15 +26,18 @@ async function generateTestsUsingBrowsingAgent(testFilePath) {
26
26
  if (!process.env.CI) {
27
27
  command = command.concat(` --headed`);
28
28
  }
29
- const exitCode = await (0, exec_1.cmd)(command.split(" "), {
30
- env: {
31
- APP_PORT: port.toString(),
32
- PW_TEST_HTML_REPORT_OPEN: "never",
33
- TEST_GEN_TOKEN: (0, utils_1.getTestConfigCliArg)(),
34
- },
35
- });
36
- if (exitCode != 0) {
37
- process.exit(exitCode);
29
+ try {
30
+ await (0, exec_1.cmd)(command.split(" "), {
31
+ env: {
32
+ APP_PORT: port.toString(),
33
+ PW_TEST_HTML_REPORT_OPEN: "never",
34
+ TEST_GEN_TOKEN: (0, utils_1.getTestConfigCliArg)(),
35
+ },
36
+ });
37
+ }
38
+ catch (e) {
39
+ logger.error(e);
40
+ process.exit(1);
38
41
  }
39
42
  await (0, web_1.removeTestOnly)(testFilePath);
40
43
  }
@@ -1,3 +1,3 @@
1
- import { Scenario } from "../../types";
2
- export declare function generateTest(scenarios: Scenario[], file: string, isUpdate: boolean): Promise<Scenario[]>;
1
+ import { Scenario, TestGenConfigOptions } from "../../types";
2
+ export declare function generateTest(scenarios: Scenario[], file: string, isUpdate: boolean, options: TestGenConfigOptions): Promise<Scenario[]>;
3
3
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,wBAAsB,YAAY,CAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,CA6IrB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,YAAY,CAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAqJrB"}
@@ -9,8 +9,9 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const logger_1 = require("../../bin/logger");
10
10
  const context_1 = require("../../bin/utils/context");
11
11
  const web_1 = require("../../bin/utils/platform/web");
12
+ const constants_1 = require("../../constants");
12
13
  const session_1 = require("../../session");
13
- async function generateTest(scenarios, file, isUpdate) {
14
+ async function generateTest(scenarios, file, isUpdate, options) {
14
15
  const logger = new logger_1.CustomLogger();
15
16
  if (!fs_extra_1.default.existsSync(file)) {
16
17
  logger.log(`Creating a new spec file: ${file}`);
@@ -55,10 +56,12 @@ async function generateTest(scenarios, file, isUpdate) {
55
56
  const firstShotMessage = await (0, llm_1.getLLMResult)({
56
57
  messages: instruction,
57
58
  trace,
58
- model: "gpt-4o",
59
- provider: "openai",
59
+ model: options.model || constants_1.DEFAULT_MODEL,
60
+ provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
61
+ providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
60
62
  modelParameters: {
61
- temperature: 0.5,
63
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
64
+ ...options.modelParameters,
62
65
  },
63
66
  });
64
67
  let response = firstShotMessage?.content || "";
@@ -115,9 +118,13 @@ async function generateTest(scenarios, file, isUpdate) {
115
118
  const message = await (0, llm_1.getLLMResult)({
116
119
  messages: instruction,
117
120
  trace,
118
- model: "gpt-4o",
119
- provider: "openai",
120
- modelParameters: { temperature: 0.5 },
121
+ model: options.model || constants_1.DEFAULT_MODEL,
122
+ provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
123
+ providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
124
+ modelParameters: {
125
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
126
+ ...options.modelParameters,
127
+ },
121
128
  });
122
129
  response = message?.content || "";
123
130
  const readWriteFileSpan = trace.startSpan("write-to-file");
package/dist/bin/index.js CHANGED
@@ -9,9 +9,9 @@ const dotenv_1 = __importDefault(require("dotenv"));
9
9
  const run_1 = require("../agent/browsing/run");
10
10
  const utils_1 = require("../agent/browsing/utils");
11
11
  const run_2 = require("../agent/codegen/run");
12
+ const reporter_1 = require("../reporter");
13
+ const ci_1 = require("../reporter/ci");
12
14
  const logger_1 = require("./logger");
13
- const reporter_1 = require("./reporter");
14
- const ci_1 = require("./reporter/ci");
15
15
  const utils_2 = require("./utils");
16
16
  dotenv_1.default.config({
17
17
  path: [".env.local", ".env"],
@@ -30,11 +30,14 @@ async function runAgent(sourceFile, isUpdate, testGenConfigs) {
30
30
  logger.success("Generating test using browsing agent");
31
31
  await (0, utils_1.prepareFileForBrowsingAgent)(testGenConfig);
32
32
  await (0, run_1.generateTestsUsingBrowsingAgent)(specPath);
33
+ await (0, reporter_1.reportTestGenVideos)({
34
+ projectRepoName: testGenConfig.options.metadata.projectRepoName,
35
+ });
33
36
  generatedTestScenarios.push(...testGenConfig.scenarios);
34
37
  }
35
38
  else {
36
39
  logger.success("Generating test using coding agent");
37
- const gen = await (0, run_2.generateTest)(scenarios, specPath, isUpdate);
40
+ const gen = await (0, run_2.generateTest)(scenarios, specPath, isUpdate, testGenConfig.options);
38
41
  generatedTestScenarios.push(...gen);
39
42
  }
40
43
  }
@@ -49,6 +52,7 @@ async function runAgent(sourceFile, isUpdate, testGenConfigs) {
49
52
  const { sourceFile, testGenConfigs, isUpdate } = await (0, utils_2.parseCliArgs)();
50
53
  (0, reporter_1.setReporterConfig)(testGenConfigs[0]?.options?.metadata);
51
54
  const generated = await runAgent(sourceFile, isUpdate, testGenConfigs);
55
+ // TODO: move these reporters to a better lifecycle
52
56
  await (0, ci_1.reportOnCI)(generated);
53
57
  process.exit(0);
54
58
  })();
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomLogger = void 0;
4
4
  const reporter_1 = require("@empiricalrun/reporter");
5
5
  const picocolors_1 = require("picocolors");
6
- const reporter_2 = require("../reporter");
6
+ const reporter_2 = require("../../reporter");
7
7
  class CustomLogger {
8
8
  useReporter = false;
9
9
  constructor({ useReporter = true } = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAKA,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAwC7D;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,qBAM3D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAOhD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAIpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAKA,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiD7D;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,qBAM3D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAOhD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAIpD"}
@@ -56,7 +56,17 @@ function validateTypescript(filePath) {
56
56
  const semanticDiagnostics = program.getSemanticDiagnostics(sourceFile);
57
57
  if (semanticDiagnostics.length > 0) {
58
58
  semanticDiagnostics.forEach((diagnostic) => {
59
- errors.push(diagnostic.messageText.toString());
59
+ if (typeof diagnostic.messageText === "string") {
60
+ errors.push(diagnostic.messageText);
61
+ }
62
+ else {
63
+ let messageChain = diagnostic.messageText;
64
+ errors.push(messageChain.messageText);
65
+ while (messageChain?.next) {
66
+ messageChain = messageChain.next[0];
67
+ errors.push(messageChain?.messageText);
68
+ }
69
+ }
60
70
  });
61
71
  }
62
72
  return errors;
@@ -0,0 +1,6 @@
1
+ import { LLMModel, LLMProvider, ModelParameters } from "@empiricalrun/llm";
2
+ export declare const MODEL_API_KEYS: Record<LLMProvider, string>;
3
+ export declare const DEFAULT_MODEL_PROVIDER: LLMProvider;
4
+ export declare const DEFAULT_MODEL: LLMModel;
5
+ export declare const DEFAULT_MODEL_PARAMETERS: ModelParameters;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE3E,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAItD,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAAsB,CAAC;AAE5D,eAAO,MAAM,aAAa,EAAE,QAAmB,CAAC;AAEhD,eAAO,MAAM,wBAAwB,EAAE,eAEtC,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MODEL_PARAMETERS = exports.DEFAULT_MODEL = exports.DEFAULT_MODEL_PROVIDER = exports.MODEL_API_KEYS = void 0;
4
+ exports.MODEL_API_KEYS = {
5
+ google: process.env.GOOGLE_API_KEY || "",
6
+ anthropic: process.env.ANTHROPIC_API_KEY || "",
7
+ openai: process.env.OPENAI_API_KEY || "",
8
+ };
9
+ exports.DEFAULT_MODEL_PROVIDER = "openai";
10
+ exports.DEFAULT_MODEL = "gpt-4o";
11
+ exports.DEFAULT_MODEL_PARAMETERS = {
12
+ temperature: 0.5,
13
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,iBAiBnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,iBAkBnE"}
package/dist/index.js CHANGED
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createTest = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
8
  const browsing_1 = require("./agent/browsing");
9
- const reporter_1 = require("./bin/reporter");
10
9
  const utils_1 = require("./bin/utils");
11
10
  const client_1 = __importDefault(require("./file/client"));
11
+ const reporter_1 = require("./reporter");
12
12
  process.on("exit", async () => await (0, llm_1.flushAllTraces)());
13
13
  process.on("SIGINT", async () => await (0, llm_1.flushAllTraces)());
14
14
  process.on("SIGTERM", async () => await (0, llm_1.flushAllTraces)());
@@ -17,13 +17,14 @@ async function createTest(task, page, test) {
17
17
  const testConfigArg = process.env.TEST_GEN_TOKEN;
18
18
  const { testGenConfigs } = await (0, utils_1.parseCliArgs)(testConfigArg);
19
19
  const [testGenConfig] = testGenConfigs;
20
- (0, reporter_1.setReporterConfig)(testGenConfig?.options?.metadata);
20
+ (0, reporter_1.setReporterConfig)(testGenConfig.options?.metadata);
21
21
  const fileService = new client_1.default(Number(port));
22
22
  test.setTimeout(900000);
23
23
  const code = await (0, browsing_1.browsingAgent)(task, page, {
24
24
  htmlSanitize: {
25
25
  disallowedStrings: ["v-data-table__td v-data-table-column--align-start"],
26
26
  },
27
+ ...testGenConfig.options,
27
28
  });
28
29
  await fileService.updateTest({
29
30
  task,
@@ -1,3 +1,3 @@
1
- import { Scenario } from "../../types";
1
+ import { Scenario } from "../types";
2
2
  export declare function reportOnCI(scenarios: Scenario[]): Promise<Scenario[]>;
3
3
  //# sourceMappingURL=ci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../src/reporter/ci.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAsB,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,uBAerD"}
@@ -0,0 +1,17 @@
1
+ import { Reporter } from "@empiricalrun/reporter";
2
+ export declare function getReporter(): Reporter | undefined;
3
+ /**
4
+ * function will upload videos and json summary of test results to r2 and report them to reporter.
5
+ * method won't throw error if it fails to report
6
+ * @param {{
7
+ * projectRepoName: string;
8
+ * }} {
9
+ * projectRepoName
10
+ * }
11
+ * @returns Promise<void> returns void
12
+ */
13
+ export declare function reportTestGenVideos({ projectRepoName, }: {
14
+ projectRepoName: string;
15
+ }): Promise<void>;
16
+ export declare function setReporterConfig(config: any): void;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAW5E,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,eAAe,GAChB,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;CACzB,iBA4BA;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAGnD"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setReporterConfig = exports.reportTestGenVideos = exports.getReporter = void 0;
4
+ const reporter_1 = require("@empiricalrun/reporter");
5
+ const logger_1 = require("../bin/logger");
6
+ const uploader_1 = require("../uploader");
7
+ let reporterInstance = undefined;
8
+ let reporterConfig = undefined;
9
+ function getReporter() {
10
+ // if no config is set, return undefined
11
+ if (!reporterConfig) {
12
+ console.warn("initialising reporter without any config");
13
+ }
14
+ // initialise once config is set
15
+ if (!reporterInstance && reporterConfig) {
16
+ reporterInstance = new reporter_1.Reporter(reporterConfig);
17
+ }
18
+ return reporterInstance;
19
+ }
20
+ exports.getReporter = getReporter;
21
+ /**
22
+ * function will upload videos and json summary of test results to r2 and report them to reporter.
23
+ * method won't throw error if it fails to report
24
+ * @param {{
25
+ * projectRepoName: string;
26
+ * }} {
27
+ * projectRepoName
28
+ * }
29
+ * @returns Promise<void> returns void
30
+ */
31
+ async function reportTestGenVideos({ projectRepoName, }) {
32
+ const logger = new logger_1.CustomLogger();
33
+ try {
34
+ if (!(0, uploader_1.checkIfResultsUploadAllowed)()) {
35
+ logger.log("Skipped uploading generated test video");
36
+ }
37
+ const { videoUrls } = await (0, uploader_1.uploadTestResultsUsingPrjtRepo)({
38
+ projectRepoName,
39
+ });
40
+ const reporter = getReporter();
41
+ const reporterMessage = `
42
+
43
+ Here are the videos of the generated test:
44
+
45
+ ${videoUrls
46
+ .map((url) => `
47
+ <video src="${url}" autoplay="true" muted="true" controls loop playsinline></video>`)
48
+ .join("\n")}
49
+ `;
50
+ await reporter?.report(new reporter_1.ProcessLogMessageBuilder({ message: reporterMessage }));
51
+ }
52
+ catch (err) {
53
+ logger.error("Failed to report test results");
54
+ console.error(err);
55
+ }
56
+ }
57
+ exports.reportTestGenVideos = reportTestGenVideos;
58
+ function setReporterConfig(config) {
59
+ console.info("initialised reporter config");
60
+ reporterConfig = config;
61
+ }
62
+ exports.setReporterConfig = setReporterConfig;
@@ -1,3 +1,4 @@
1
+ import { LLMModel, LLMProvider, ModelParameters } from "@empiricalrun/llm";
1
2
  import OpenAI from "openai";
2
3
  import { Page } from "playwright";
3
4
  export type FileContent = {
@@ -6,9 +7,10 @@ export type FileContent = {
6
7
  };
7
8
  export type TestGenConfigOptions = {
8
9
  agent: "code" | "browser";
9
- model: string;
10
+ model: LLMModel;
11
+ modelProvider: LLMProvider;
12
+ modelParameters?: ModelParameters;
10
13
  metadata: {
11
- apiToken: string;
12
14
  testSessionId: number;
13
15
  testCaseName: string;
14
16
  projectRepoName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * function to upload test results to r2 using the project repo name
3
+ * this only uploads json summary of test results
4
+ * @param { projectName: string } projectRepoName - name of the project repo
5
+ * @returns urls of videos and summary json
6
+ */
7
+ export declare function uploadTestResultsUsingPrjtRepo({ projectRepoName, }: {
8
+ projectRepoName: string;
9
+ }): Promise<{
10
+ videoUrls: string[];
11
+ summaryUrl: string;
12
+ }>;
13
+ export declare function checkIfResultsUploadAllowed(): string | undefined;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uploader/index.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH,wBAAsB,8BAA8B,CAAC,EACnD,eAAe,GAChB,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAyBD;AAED,wBAAgB,2BAA2B,uBAQ1C"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.checkIfResultsUploadAllowed = exports.uploadTestResultsUsingPrjtRepo = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const r2_1 = require("./r2");
9
+ // json summary of test results
10
+ const TEST_RESULTS_DIR = "test-results";
11
+ const UPLOAD_BUCKET = "test-report";
12
+ const UPLOAD_DOMAIN = "https://reports.empirical.run"; // domain based on bucket mentioned above
13
+ function getFullUploadPath(filePath, uploadDir) {
14
+ const relativeFilePath = filePath.replace(path_1.default.join(process.cwd(), TEST_RESULTS_DIR), "");
15
+ return `${UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
16
+ }
17
+ /**
18
+ * function to upload test results to r2 using the project repo name
19
+ * this only uploads json summary of test results
20
+ * @param { projectName: string } projectRepoName - name of the project repo
21
+ * @returns urls of videos and summary json
22
+ */
23
+ async function uploadTestResultsUsingPrjtRepo({ projectRepoName, }) {
24
+ const uploadUniqueId = crypto.randomUUID();
25
+ // project repo name is the github repo name
26
+ // the folder names in r2 are the github repo name without the `-tests` suffix
27
+ const uploadDir = `test-generation/${projectRepoName.replace("-tests", "")}/${uploadUniqueId}`;
28
+ const files = await (0, r2_1.uploadDirectory)({
29
+ sourceDir: path_1.default.join(process.cwd(), TEST_RESULTS_DIR),
30
+ destinationDir: uploadDir,
31
+ uploadBucket: UPLOAD_BUCKET,
32
+ });
33
+ const fileNames = Object.keys(files);
34
+ // TODO: parse the json summary and then detect video attachments
35
+ // current assumption
36
+ // - test gen will only run on a single spec file
37
+ // - the video files will be of format <spec-file-name>.webm
38
+ const videoFiles = fileNames.filter((fileName) => fileName.endsWith(".webm"));
39
+ return {
40
+ videoUrls: videoFiles.map((fileName) => getFullUploadPath(fileName, uploadDir)),
41
+ summaryUrl: getFullUploadPath("/test-results/summary.json", uploadDir),
42
+ };
43
+ }
44
+ exports.uploadTestResultsUsingPrjtRepo = uploadTestResultsUsingPrjtRepo;
45
+ function checkIfResultsUploadAllowed() {
46
+ // TODO: check for valid R2 credentials
47
+ // check for project repo name, and r2 creds
48
+ return (process.env.R2_ACCOUNT_ID &&
49
+ process.env.R2_ACCESS_KEY_ID &&
50
+ process.env.R2_SECRET_ACCESS_KEY);
51
+ }
52
+ exports.checkIfResultsUploadAllowed = checkIfResultsUploadAllowed;
@@ -0,0 +1,10 @@
1
+ interface FileMap {
2
+ [file: string]: string;
3
+ }
4
+ export declare function uploadDirectory({ sourceDir, destinationDir, uploadBucket, }: {
5
+ sourceDir: string;
6
+ destinationDir: string;
7
+ uploadBucket: string;
8
+ }): Promise<FileMap>;
9
+ export {};
10
+ //# sourceMappingURL=r2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../src/uploader/r2.ts"],"names":[],"mappings":"AAqBA,UAAU,OAAO;IACf,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAgGD,wBAAsB,eAAe,CAAC,EACpC,SAAS,EACT,cAAc,EACd,YAAY,GACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnB"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.uploadDirectory = void 0;
30
+ const client_s3_1 = require("@aws-sdk/client-s3");
31
+ const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
32
+ const fs = __importStar(require("fs"));
33
+ const md5_1 = __importDefault(require("md5"));
34
+ const path_1 = __importDefault(require("path"));
35
+ const getFileList = (dir) => {
36
+ let files = [];
37
+ const items = fs.readdirSync(dir, {
38
+ withFileTypes: true,
39
+ });
40
+ for (const item of items) {
41
+ const isDir = item.isDirectory();
42
+ const absolutePath = `${dir}/${item.name}`;
43
+ if (isDir) {
44
+ files = [...files, ...getFileList(absolutePath)];
45
+ }
46
+ else {
47
+ files.push(absolutePath);
48
+ }
49
+ }
50
+ return files;
51
+ };
52
+ const run = async (config) => {
53
+ const map = new Map();
54
+ const urls = {};
55
+ const S3 = new client_s3_1.S3Client({
56
+ region: "auto",
57
+ endpoint: `https://${config.accountId}.r2.cloudflarestorage.com`,
58
+ credentials: {
59
+ accessKeyId: config.accessKeyId,
60
+ secretAccessKey: config.secretAccessKey,
61
+ },
62
+ });
63
+ const files = getFileList(config.sourceDir);
64
+ const mime = (await import("mime")).default;
65
+ await Promise.all(files.map(async (file) => {
66
+ console.log(file);
67
+ const fileStream = fs.readFileSync(file);
68
+ console.log(config.sourceDir);
69
+ console.log(config.destinationDir);
70
+ //const fileName = file.replace(/^.*[\\\/]/, "");
71
+ const fileName = file.replace(config.sourceDir, "");
72
+ const fileKey = path_1.default.join(config.destinationDir !== "" ? config.destinationDir : config.sourceDir, fileName);
73
+ if (fileKey.includes(".gitkeep"))
74
+ return;
75
+ console.log(fileKey);
76
+ const mimeType = mime.getType(file);
77
+ const uploadParams = {
78
+ Bucket: config.bucket,
79
+ Key: fileKey,
80
+ Body: fileStream,
81
+ ContentLength: fs.statSync(file).size,
82
+ ContentType: mimeType ?? "application/octet-stream",
83
+ };
84
+ const cmd = new client_s3_1.PutObjectCommand(uploadParams);
85
+ const digest = (0, md5_1.default)(fileStream);
86
+ cmd.middlewareStack.add((next) => async (args) => {
87
+ args.request.headers["if-none-match"] = `"${digest}"`;
88
+ return await next(args);
89
+ }, {
90
+ step: "build",
91
+ name: "addETag",
92
+ });
93
+ try {
94
+ const data = await S3.send(cmd);
95
+ console.log(`R2 Success - ${file}`);
96
+ map.set(file, data);
97
+ const fileUrl = await (0, s3_request_presigner_1.getSignedUrl)(S3, cmd);
98
+ urls[file] = fileUrl;
99
+ }
100
+ catch (err) {
101
+ const error = err;
102
+ if (error["$metadata"]) {
103
+ if (error.$metadata.httpStatusCode !== 412)
104
+ // If-None-Match
105
+ throw error;
106
+ }
107
+ }
108
+ return;
109
+ }));
110
+ return urls;
111
+ };
112
+ async function uploadDirectory({ sourceDir, destinationDir, uploadBucket, }) {
113
+ let config = {
114
+ accountId: process.env.R2_ACCOUNT_ID,
115
+ accessKeyId: process.env.R2_ACCESS_KEY_ID,
116
+ secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
117
+ bucket: uploadBucket,
118
+ sourceDir,
119
+ destinationDir,
120
+ };
121
+ const uploadedFiles = await run(config);
122
+ return uploadedFiles;
123
+ }
124
+ exports.uploadDirectory = uploadDirectory;
@@ -1 +1 @@
1
- {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAGA,wBAAgB,GAAG,CACjB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAejB"}
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAGA,wBAAgB,GAAG,CACjB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
@@ -7,18 +7,29 @@ exports.cmd = void 0;
7
7
  const child_process_1 = require("child_process");
8
8
  const process_1 = __importDefault(require("process"));
9
9
  function cmd(command, options) {
10
- return new Promise((resolveFunc) => {
10
+ let lastLog = "";
11
+ return new Promise((resolveFunc, rejectFunc) => {
11
12
  let p = (0, child_process_1.spawn)(command[0], command.slice(1), {
12
13
  env: { ...process_1.default.env, ...options.env },
13
14
  });
14
15
  p.stdout.on("data", (x) => {
15
- process_1.default.stdout.write(x.toString());
16
+ const log = x.toString();
17
+ process_1.default.stdout.write(log);
18
+ lastLog = log;
16
19
  });
17
20
  p.stderr.on("data", (x) => {
21
+ const log = x.toString();
18
22
  process_1.default.stderr.write(x.toString());
23
+ lastLog = log;
19
24
  });
20
25
  p.on("exit", (code) => {
21
- resolveFunc(code);
26
+ if (code != 0) {
27
+ // assuming last log is the error message before exiting
28
+ rejectFunc(lastLog);
29
+ }
30
+ else {
31
+ resolveFunc(code);
32
+ }
22
33
  });
23
34
  });
24
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.16.2",
3
+ "version": "0.16.4",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -15,6 +15,8 @@
15
15
  },
16
16
  "author": "Empirical Team <hey@empirical.run>",
17
17
  "dependencies": {
18
+ "@aws-sdk/client-s3": "^3.614.0",
19
+ "@aws-sdk/s3-request-presigner": "^3.614.0",
18
20
  "@types/sanitize-html": "^2.11.0",
19
21
  "commander": "^12.1.0",
20
22
  "detect-port": "^1.6.1",
@@ -25,6 +27,8 @@
25
27
  "google-auth-library": "^9.10.0",
26
28
  "google-spreadsheet": "^4.1.2",
27
29
  "ignore": "^5.3.1",
30
+ "md5": "^2.3.0",
31
+ "mime": "^4.0.4",
28
32
  "minimatch": "^10.0.1",
29
33
  "openai": "^4.47.2",
30
34
  "picocolors": "^1.0.1",
@@ -40,7 +44,8 @@
40
44
  "devDependencies": {
41
45
  "@types/detect-port": "^1.3.5",
42
46
  "@types/express": "^4.17.21",
43
- "@types/fs-extra": "^11.0.4"
47
+ "@types/fs-extra": "^11.0.4",
48
+ "@types/md5": "^2.3.5"
44
49
  },
45
50
  "scripts": {
46
51
  "dev": "tsc --build --watch",
@@ -1 +0,0 @@
1
- {"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../../src/bin/reporter/ci.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,wBAAsB,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,uBAerD"}
@@ -1,4 +0,0 @@
1
- import { Reporter } from "@empiricalrun/reporter";
2
- export declare function getReporter(): Reporter | undefined;
3
- export declare function setReporterConfig(config: any): void;
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/reporter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIlD,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAGnD"}
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setReporterConfig = exports.getReporter = void 0;
4
- const reporter_1 = require("@empiricalrun/reporter");
5
- let reporterInstance = undefined;
6
- let reporterConfig = undefined;
7
- function getReporter() {
8
- // if no config is set, return undefined
9
- if (!reporterConfig) {
10
- console.warn("initialising reporter without any config");
11
- }
12
- // initialise once config is set
13
- if (!reporterInstance && reporterConfig) {
14
- reporterInstance = new reporter_1.Reporter(reporterConfig);
15
- }
16
- return reporterInstance;
17
- }
18
- exports.getReporter = getReporter;
19
- function setReporterConfig(config) {
20
- console.info("initialised reporter config");
21
- reporterConfig = config;
22
- }
23
- exports.setReporterConfig = setReporterConfig;
File without changes