@empiricalrun/test-gen 0.16.13 → 0.17.1
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.
- package/CHANGELOG.md +16 -0
- package/README.md +10 -42
- package/dist/agent/browsing/utils.d.ts +1 -1
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +5 -5
- package/dist/agent/codegen/run.d.ts +2 -2
- package/dist/agent/codegen/run.d.ts.map +1 -1
- package/dist/agent/codegen/run.js +98 -107
- package/dist/bin/index.js +19 -26
- package/dist/bin/utils/index.d.ts +1 -2
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +2 -4
- package/dist/bin/utils/scenarios/index.d.ts +1 -1
- package/dist/bin/utils/scenarios/index.d.ts.map +1 -1
- package/dist/bin/utils/scenarios/index.js +11 -106
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/reporter/ci.d.ts +2 -2
- package/dist/reporter/ci.d.ts.map +1 -1
- package/dist/reporter/ci.js +4 -9
- package/dist/types/index.d.ts +2 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.17.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ac0256e: feat: remove support for update flag in test gen
|
|
8
|
+
|
|
9
|
+
## 0.17.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 914b207: fix: remove google sheet support in test gen
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 74eefc4: fix: remove comments of browser agent
|
|
18
|
+
|
|
3
19
|
## 0.16.13
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,61 +8,29 @@ Our agents that generate Playwright tests. There are 2 agents
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
npx @empiricalrun/test-gen
|
|
11
|
+
npx @empiricalrun/test-gen TEST_GEN_TOKEN
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
where `$args` can be one of the following
|
|
15
|
-
|
|
16
14
|
### Add new test
|
|
17
15
|
|
|
18
16
|
```sh
|
|
19
|
-
npx @empiricalrun/test-gen
|
|
17
|
+
npx @empiricalrun/test-gen TEST_GEN_TOKEN
|
|
20
18
|
```
|
|
21
19
|
|
|
22
20
|
- This will trigger browsing agent to write a new test for this scenario
|
|
23
|
-
- See [Base64 payload](#base64-payload)
|
|
24
|
-
|
|
25
|
-
```sh
|
|
26
|
-
npx @empiricalrun/test-gen delete.spec.ts
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
- This will trigger browsing agent to write a new test in this file
|
|
30
|
-
- **Note** that the file must have `createTest(...)` where the scenario is specified
|
|
31
|
-
|
|
32
|
-
#### Bulk add
|
|
33
|
-
|
|
34
|
-
```sh
|
|
35
|
-
npx @empiricalrun/test-gen scenarios.yml
|
|
36
|
-
|
|
37
|
-
# optional: filter for one scenario
|
|
38
|
-
npx @empiricalrun/test-gen scenarios.yml $scenario_name
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Using yml or google spreadsheet. **Note** that this only runs the code editing agent
|
|
42
|
-
|
|
43
|
-
```yaml ./tests/scenarios.yaml
|
|
44
|
-
dir: ./tests/ # [optional] directory where you want to create tests. Default - ./tests
|
|
45
|
-
scenarios: # list of scenarios
|
|
46
|
-
- name: user should be able to login successfully # name of the test case to be generated
|
|
47
|
-
steps: # steps for the test case
|
|
48
|
-
- cLick on "Login" button
|
|
49
|
-
- click on input "username"
|
|
50
|
-
- fill username as "foo@bar.com"
|
|
51
|
-
- fill password as "bar@123"
|
|
52
|
-
- click on "Login Button"
|
|
53
|
-
assert: "Login successful" text should be visible # assertion
|
|
54
|
-
```
|
|
21
|
+
- See [Test gen token: Base64 payload](#test-gen-token-base64-payload)
|
|
55
22
|
|
|
56
23
|
### Update existing test
|
|
57
24
|
|
|
58
25
|
```sh
|
|
59
|
-
npx @empiricalrun/test-gen
|
|
26
|
+
npx @empiricalrun/test-gen TEST_GEN_TOKEN
|
|
60
27
|
```
|
|
61
28
|
|
|
29
|
+
- If the test case is already present in the file, the test gen agent will update the existing test as per the steps provided in the payload
|
|
62
30
|
- This will trigger code editing agent to write a new test for this scenario
|
|
63
|
-
- See [Base64 payload](#base64-payload)
|
|
31
|
+
- See [Test gen token: Base64 payload](#test-gen-token-base64-payload)
|
|
64
32
|
|
|
65
|
-
### Base64 payload
|
|
33
|
+
### Test gen token: Base64 payload
|
|
66
34
|
|
|
67
35
|
Convert this object into a base64 payload - for new and update test.
|
|
68
36
|
|
|
@@ -72,10 +40,10 @@ const scenario = {
|
|
|
72
40
|
steps: [
|
|
73
41
|
"fill in the username as foobar@gmail.com",
|
|
74
42
|
"fill in the password as bazbaz",
|
|
75
|
-
"click on the login button"
|
|
43
|
+
"click on the login button",
|
|
76
44
|
],
|
|
77
45
|
assert: "",
|
|
78
|
-
group: "home"
|
|
46
|
+
group: "home",
|
|
79
47
|
};
|
|
80
|
-
btoa(JSON.stringify(scenario))
|
|
48
|
+
btoa(JSON.stringify(scenario));
|
|
81
49
|
```
|
|
@@ -2,7 +2,7 @@ import { Page } from "playwright";
|
|
|
2
2
|
import { PlaywrightTestConfig } from "playwright/test";
|
|
3
3
|
import { TestGenConfig } from "../../types";
|
|
4
4
|
export declare function isRegExp(obj: any): obj is RegExp;
|
|
5
|
-
export declare function prepareBrowsingAgentTask(steps: string[]
|
|
5
|
+
export declare function prepareBrowsingAgentTask(steps: string[]): string;
|
|
6
6
|
export declare function prepareFileForBrowsingAgent(genConfig: TestGenConfig): Promise<void>;
|
|
7
7
|
export declare function injectPwLocatorGenerator(page: Page): Promise<void>;
|
|
8
8
|
export declare function canRunBrowsingAgent(filePath: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AASvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AASvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAED,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,aAAa,iBAqCzE;AAiBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBASxD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,QA4BnD;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,GACtB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,8EASA"}
|
|
@@ -16,15 +16,15 @@ function isRegExp(obj) {
|
|
|
16
16
|
Object.prototype.toString.call(obj) === "[object RegExp]");
|
|
17
17
|
}
|
|
18
18
|
exports.isRegExp = isRegExp;
|
|
19
|
-
function prepareBrowsingAgentTask(steps
|
|
19
|
+
function prepareBrowsingAgentTask(steps) {
|
|
20
20
|
const sanitizedSteps = steps.map((step) => step.replace(/`/g, "\\`"));
|
|
21
|
-
const task = `${sanitizedSteps.join("\n")}\n
|
|
21
|
+
const task = `${sanitizedSteps.join("\n")}\n`;
|
|
22
22
|
return task;
|
|
23
23
|
}
|
|
24
24
|
exports.prepareBrowsingAgentTask = prepareBrowsingAgentTask;
|
|
25
25
|
async function prepareFileForBrowsingAgent(genConfig) {
|
|
26
|
-
const { specPath,
|
|
27
|
-
const { name, steps
|
|
26
|
+
const { specPath, testCase } = genConfig;
|
|
27
|
+
const { name, steps } = testCase;
|
|
28
28
|
const logger = new logger_1.CustomLogger();
|
|
29
29
|
if (!fs_extra_1.default.existsSync(specPath)) {
|
|
30
30
|
await fs_extra_1.default.createFile(specPath);
|
|
@@ -33,7 +33,7 @@ async function prepareFileForBrowsingAgent(genConfig) {
|
|
|
33
33
|
if (name && steps && steps.length) {
|
|
34
34
|
const existingContents = await fs_extra_1.default.readFile(specPath, "utf-8");
|
|
35
35
|
const testBlock = (0, web_1.getTypescriptTestBlock)(name, existingContents);
|
|
36
|
-
const mergedSteps = prepareBrowsingAgentTask(steps
|
|
36
|
+
const mergedSteps = prepareBrowsingAgentTask(steps);
|
|
37
37
|
let newContents = existingContents;
|
|
38
38
|
if (testBlock) {
|
|
39
39
|
logger.log("appending to existing test block");
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function generateTest(
|
|
1
|
+
import { TestCase, TestGenConfigOptions } from "../../types";
|
|
2
|
+
export declare function generateTest(testCase: TestCase, file: string, options: TestGenConfigOptions): Promise<TestCase[]>;
|
|
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":"AAmBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,YAAY,CAChC,
|
|
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,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CA8IrB"}
|
|
@@ -11,7 +11,7 @@ const context_1 = require("../../bin/utils/context");
|
|
|
11
11
|
const web_1 = require("../../bin/utils/platform/web");
|
|
12
12
|
const constants_1 = require("../../constants");
|
|
13
13
|
const session_1 = require("../../session");
|
|
14
|
-
async function generateTest(
|
|
14
|
+
async function generateTest(testCase, file, options) {
|
|
15
15
|
const logger = new logger_1.CustomLogger();
|
|
16
16
|
if (!fs_extra_1.default.existsSync(file)) {
|
|
17
17
|
logger.log(`Creating a new spec file: ${file}`);
|
|
@@ -19,42 +19,96 @@ async function generateTest(scenarios, file, isUpdate, options) {
|
|
|
19
19
|
}
|
|
20
20
|
const context = await (0, context_1.contextForGeneration)(file);
|
|
21
21
|
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
const generatedTestCases = [];
|
|
23
|
+
logger.logEmptyLine();
|
|
24
|
+
const trace = new llm_1.LLMTracing({
|
|
25
|
+
name: "generate-test",
|
|
26
|
+
sessionDetails: (0, session_1.getSessionDetails)(),
|
|
27
|
+
tags: [options.metadata.projectName, options.metadata.environment].filter((s) => !!s),
|
|
28
|
+
});
|
|
29
|
+
trace.event({
|
|
30
|
+
name: "collate-files-as-text",
|
|
31
|
+
output: {
|
|
32
|
+
codePrompt,
|
|
33
|
+
pomPrompt,
|
|
34
|
+
testFileContent,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
trace.update({ input: { testCase } });
|
|
38
|
+
const isUpdate = testFileContent.includes(`test("${testCase?.name}"`);
|
|
39
|
+
const promptSpan = trace.startSpan(isUpdate ? "update-scenario-prompt" : "add-scenario-prompt");
|
|
40
|
+
const promptName = isUpdate ? "update-scenario" : "add-scenario";
|
|
41
|
+
const instruction = await (0, llm_1.getPrompt)(promptName, {
|
|
42
|
+
testFiles: codePrompt,
|
|
43
|
+
pageFiles: pomPrompt,
|
|
44
|
+
scenarioName: testCase.name,
|
|
45
|
+
scenarioSteps: testCase.steps.join("\n"),
|
|
46
|
+
scenarioFile: file,
|
|
47
|
+
});
|
|
48
|
+
promptSpan.end({ output: { instruction } });
|
|
49
|
+
const firstShotMessage = await (0, llm_1.getLLMResult)({
|
|
50
|
+
messages: instruction,
|
|
51
|
+
trace,
|
|
52
|
+
model: options.model || constants_1.DEFAULT_MODEL,
|
|
53
|
+
provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
54
|
+
providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
55
|
+
modelParameters: {
|
|
56
|
+
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
57
|
+
...options.modelParameters,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
let response = firstShotMessage?.content || "";
|
|
61
|
+
logger.success("Test generated successfully!");
|
|
62
|
+
const readWriteFileSpan = trace.startSpan("write-to-file");
|
|
63
|
+
let contents = fs_extra_1.default.readFileSync(file, "utf-8");
|
|
64
|
+
const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(response);
|
|
65
|
+
let updatedContent = prependContent + contents + `\n\n${strippedContent}`;
|
|
66
|
+
if (isUpdate) {
|
|
67
|
+
const testBlock = (0, web_1.getTypescriptTestBlock)(testCase?.name, contents);
|
|
68
|
+
contents = contents.replace(testBlock, `\n\n${strippedContent}`);
|
|
69
|
+
updatedContent = prependContent + contents;
|
|
70
|
+
}
|
|
71
|
+
await fs_extra_1.default.writeFile(file, updatedContent, "utf-8");
|
|
72
|
+
readWriteFileSpan.end({ output: { updatedContent } });
|
|
73
|
+
logger.log("Linting generated code...");
|
|
74
|
+
trace.event({ name: "lint-file" });
|
|
75
|
+
await (0, web_1.lintErrors)(file);
|
|
76
|
+
const validateTypesSpan = trace.startSpan("detect-type-errors-in-file");
|
|
77
|
+
logger.log("Validating types...");
|
|
78
|
+
let errors = (0, web_1.validateTypescript)(file);
|
|
79
|
+
validateTypesSpan.end({ output: { errors } });
|
|
80
|
+
if (!errors.length) {
|
|
81
|
+
logger.success("Found no type issues!");
|
|
82
|
+
}
|
|
83
|
+
const maxIteration = 2;
|
|
84
|
+
let counter = 0;
|
|
85
|
+
while (errors.length > 0) {
|
|
86
|
+
const fileContent = fs_extra_1.default.readFileSync(file, "utf-8");
|
|
87
|
+
counter += 1;
|
|
88
|
+
if (counter > maxIteration) {
|
|
89
|
+
trace.event({ name: "code-fix-iteration-max-out" });
|
|
90
|
+
logger.error([
|
|
91
|
+
`Unable to fix typescript errors. Please review ${file} manually and fix the typescript errors.`,
|
|
92
|
+
`Run the test-gen command again, once errors are fixed.`,
|
|
93
|
+
`Trace: ${trace.url}`,
|
|
94
|
+
].join("\n"));
|
|
95
|
+
break;
|
|
45
96
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
97
|
+
trace.event({ name: "Found errors fixing" });
|
|
98
|
+
logger.warn("Found few errors while validating types:");
|
|
99
|
+
errors.forEach((e) => logger.warn(e));
|
|
100
|
+
logger.log("Trying to fix above errors...");
|
|
101
|
+
const promptSpan = trace.startSpan("fix-type-errors-prompt");
|
|
102
|
+
const instruction = await (0, llm_1.getPrompt)("fix-file-errors-ts", {
|
|
103
|
+
testFiles: codePrompt || "",
|
|
104
|
+
pageFiles: pomPrompt || "",
|
|
54
105
|
scenarioFile: file,
|
|
106
|
+
errors: errors,
|
|
107
|
+
fileContent: fileContent,
|
|
108
|
+
scenaioName: testCase.name,
|
|
55
109
|
});
|
|
56
110
|
promptSpan.end({ output: { instruction } });
|
|
57
|
-
const
|
|
111
|
+
const message = await (0, llm_1.getLLMResult)({
|
|
58
112
|
messages: instruction,
|
|
59
113
|
trace,
|
|
60
114
|
model: options.model || constants_1.DEFAULT_MODEL,
|
|
@@ -65,88 +119,25 @@ async function generateTest(scenarios, file, isUpdate, options) {
|
|
|
65
119
|
...options.modelParameters,
|
|
66
120
|
},
|
|
67
121
|
});
|
|
68
|
-
|
|
69
|
-
logger.success("Test generated successfully!");
|
|
122
|
+
response = message?.content || "";
|
|
70
123
|
const readWriteFileSpan = trace.startSpan("write-to-file");
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
let updatedContent = prependContent + contents + `\n\n${strippedContent}`;
|
|
74
|
-
if (isUpdate) {
|
|
75
|
-
const testBlock = (0, web_1.getTypescriptTestBlock)(scenario?.name, contents);
|
|
76
|
-
contents = contents.replace(testBlock, `\n\n${strippedContent}`);
|
|
77
|
-
updatedContent = prependContent + contents;
|
|
78
|
-
}
|
|
79
|
-
await fs_extra_1.default.writeFile(file, updatedContent, "utf-8");
|
|
80
|
-
readWriteFileSpan.end({ output: { updatedContent } });
|
|
81
|
-
logger.log("Linting generated code...");
|
|
124
|
+
await fs_extra_1.default.writeFile(file, response, "utf-8");
|
|
125
|
+
readWriteFileSpan.end({ output: { response } });
|
|
82
126
|
trace.event({ name: "lint-file" });
|
|
83
127
|
await (0, web_1.lintErrors)(file);
|
|
84
128
|
const validateTypesSpan = trace.startSpan("detect-type-errors-in-file");
|
|
85
|
-
|
|
86
|
-
let errors = (0, web_1.validateTypescript)(file);
|
|
129
|
+
errors = (0, web_1.validateTypescript)(file);
|
|
87
130
|
validateTypesSpan.end({ output: { errors } });
|
|
88
131
|
if (!errors.length) {
|
|
89
132
|
logger.success("Found no type issues!");
|
|
90
133
|
}
|
|
91
|
-
const maxIteration = 2;
|
|
92
|
-
let counter = 0;
|
|
93
|
-
while (errors.length > 0) {
|
|
94
|
-
const fileContent = fs_extra_1.default.readFileSync(file, "utf-8");
|
|
95
|
-
counter += 1;
|
|
96
|
-
if (counter > maxIteration) {
|
|
97
|
-
trace.event({ name: "code-fix-iteration-max-out" });
|
|
98
|
-
logger.error([
|
|
99
|
-
`Unable to fix typescript errors. Please review ${file} manually and fix the typescript errors.`,
|
|
100
|
-
`Run the test-gen command again, once errors are fixed.`,
|
|
101
|
-
`Trace: ${trace.url}`,
|
|
102
|
-
].join("\n"));
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
trace.event({ name: "Found errors fixing" });
|
|
106
|
-
logger.warn("Found few errors while validating types:");
|
|
107
|
-
errors.forEach((e) => logger.warn(e));
|
|
108
|
-
logger.log("Trying to fix above errors...");
|
|
109
|
-
const promptSpan = trace.startSpan("fix-type-errors-prompt");
|
|
110
|
-
const instruction = await (0, llm_1.getPrompt)("fix-file-errors-ts", {
|
|
111
|
-
testFiles: codePrompt || "",
|
|
112
|
-
pageFiles: pomPrompt || "",
|
|
113
|
-
scenarioFile: file,
|
|
114
|
-
errors: errors,
|
|
115
|
-
fileContent: fileContent,
|
|
116
|
-
scenaioName: scenario.name,
|
|
117
|
-
});
|
|
118
|
-
promptSpan.end({ output: { instruction } });
|
|
119
|
-
const message = await (0, llm_1.getLLMResult)({
|
|
120
|
-
messages: instruction,
|
|
121
|
-
trace,
|
|
122
|
-
model: options.model || constants_1.DEFAULT_MODEL,
|
|
123
|
-
provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
124
|
-
providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
125
|
-
modelParameters: {
|
|
126
|
-
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
127
|
-
...options.modelParameters,
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
response = message?.content || "";
|
|
131
|
-
const readWriteFileSpan = trace.startSpan("write-to-file");
|
|
132
|
-
await fs_extra_1.default.writeFile(file, response, "utf-8");
|
|
133
|
-
readWriteFileSpan.end({ output: { response } });
|
|
134
|
-
trace.event({ name: "lint-file" });
|
|
135
|
-
await (0, web_1.lintErrors)(file);
|
|
136
|
-
const validateTypesSpan = trace.startSpan("detect-type-errors-in-file");
|
|
137
|
-
errors = (0, web_1.validateTypescript)(file);
|
|
138
|
-
validateTypesSpan.end({ output: { errors } });
|
|
139
|
-
if (!errors.length) {
|
|
140
|
-
logger.success("Found no type issues!");
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
trace.event({ name: "format-file" });
|
|
144
|
-
await (0, web_1.formatCode)(file);
|
|
145
|
-
logger.success("File formatted successfully!");
|
|
146
|
-
logger.log(`Trace: ${trace.url}`);
|
|
147
|
-
generatedScenarios.push(scenario);
|
|
148
|
-
trace.update({ input: { scenario }, output: { response } });
|
|
149
134
|
}
|
|
150
|
-
|
|
135
|
+
trace.event({ name: "format-file" });
|
|
136
|
+
await (0, web_1.formatCode)(file);
|
|
137
|
+
logger.success("File formatted successfully!");
|
|
138
|
+
logger.log(`Trace: ${trace.url}`);
|
|
139
|
+
generatedTestCases.push(testCase);
|
|
140
|
+
trace.update({ input: { testCase }, output: { response } });
|
|
141
|
+
return generatedTestCases;
|
|
151
142
|
}
|
|
152
143
|
exports.generateTest = generateTest;
|
package/dist/bin/index.js
CHANGED
|
@@ -19,40 +19,33 @@ dotenv_1.default.config({
|
|
|
19
19
|
process.on("exit", async () => await (0, llm_1.flushAllTraces)());
|
|
20
20
|
process.on("SIGINT", async () => await (0, llm_1.flushAllTraces)());
|
|
21
21
|
process.on("SIGTERM", async () => await (0, llm_1.flushAllTraces)());
|
|
22
|
-
async function runAgent(sourceFile,
|
|
22
|
+
async function runAgent(sourceFile, testGenConfig) {
|
|
23
23
|
const logger = new logger_1.CustomLogger();
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
logger.success("Generating test using coding agent");
|
|
40
|
-
const gen = await (0, run_2.generateTest)(scenarios, specPath, isUpdate, testGenConfig.options);
|
|
41
|
-
generatedTestScenarios.push(...gen);
|
|
42
|
-
}
|
|
24
|
+
const { specPath, testCase } = testGenConfig;
|
|
25
|
+
if (testGenConfig.options?.agent !== "code") {
|
|
26
|
+
// this assumes we have only one scenario in test config
|
|
27
|
+
logger.success("Generating test using browsing agent");
|
|
28
|
+
await (0, utils_1.prepareFileForBrowsingAgent)(testGenConfig);
|
|
29
|
+
await (0, run_1.generateTestsUsingBrowsingAgent)(specPath);
|
|
30
|
+
await (0, reporter_1.reportTestGenVideos)({
|
|
31
|
+
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
logger.success("Generating test using coding agent");
|
|
36
|
+
await (0, run_2.generateTest)(testCase, specPath, testGenConfig.options);
|
|
43
37
|
}
|
|
44
|
-
return generatedTestScenarios;
|
|
45
38
|
}
|
|
46
39
|
(async function main() {
|
|
47
40
|
const logger = new logger_1.CustomLogger({ useReporter: false });
|
|
48
41
|
if (process.argv.length < 3) {
|
|
49
|
-
logger.error("Please provide path to scenarios using command:", "npx @empiricalrun/test-gen <
|
|
42
|
+
logger.error("Please provide path to scenarios using command:", "npx @empiricalrun/test-gen <TEST_GEN_TOKEN>");
|
|
50
43
|
process.exit(1);
|
|
51
44
|
}
|
|
52
|
-
const { sourceFile,
|
|
53
|
-
(0, reporter_1.setReporterConfig)(
|
|
54
|
-
|
|
45
|
+
const { sourceFile, testGenConfig } = await (0, utils_2.parseCliArgs)();
|
|
46
|
+
(0, reporter_1.setReporterConfig)(testGenConfig?.options?.metadata);
|
|
47
|
+
await runAgent(sourceFile, testGenConfig);
|
|
55
48
|
// TODO: move these reporters to a better lifecycle
|
|
56
|
-
await (0, ci_1.reportOnCI)(
|
|
49
|
+
await (0, ci_1.reportOnCI)(testGenConfig.testCase);
|
|
57
50
|
process.exit(0);
|
|
58
51
|
})();
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { TestGenConfig } from "../../types";
|
|
2
2
|
export declare function parseCliArgs(scenarioOrScenariosPath?: string): Promise<{
|
|
3
3
|
sourceFile: string;
|
|
4
|
-
|
|
5
|
-
isUpdate: boolean;
|
|
4
|
+
testGenConfig: TestGenConfig;
|
|
6
5
|
}>;
|
|
7
6
|
export declare function getTestConfigCliArg(): string;
|
|
8
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,wBAAsB,YAAY,CAChC,uBAAuB,GAAE,MAA8B
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,wBAAsB,YAAY,CAChC,uBAAuB,GAAE,MAA8B;;;GASxD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
package/dist/bin/utils/index.js
CHANGED
|
@@ -3,12 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getTestConfigCliArg = exports.parseCliArgs = void 0;
|
|
4
4
|
const scenarios_1 = require("./scenarios");
|
|
5
5
|
async function parseCliArgs(scenarioOrScenariosPath = getTestConfigCliArg()) {
|
|
6
|
-
const
|
|
7
|
-
const testGenConfigs = await (0, scenarios_1.loadTestConfigs)(scenarioOrScenariosPath);
|
|
6
|
+
const testGenConfig = await (0, scenarios_1.loadTestConfigs)(scenarioOrScenariosPath);
|
|
8
7
|
return {
|
|
9
8
|
sourceFile: scenarioOrScenariosPath,
|
|
10
|
-
|
|
11
|
-
isUpdate,
|
|
9
|
+
testGenConfig,
|
|
12
10
|
};
|
|
13
11
|
}
|
|
14
12
|
exports.parseCliArgs = parseCliArgs;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TestGenConfig } from "../../../types";
|
|
2
|
-
declare function loadTestConfigs(scenariosPath: string): Promise<TestGenConfig
|
|
2
|
+
declare function loadTestConfigs(scenariosPath: string): Promise<TestGenConfig>;
|
|
3
3
|
export { loadTestConfigs };
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAwB,MAAM,gBAAgB,CAAC;AAUrE,iBAAe,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAY5E;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,112 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.loadTestConfigs = void 0;
|
|
7
|
-
const google_auth_library_1 = require("google-auth-library");
|
|
8
|
-
const slugify_1 = __importDefault(require("slugify"));
|
|
9
|
-
function isValidJSON(str) {
|
|
10
|
-
try {
|
|
11
|
-
JSON.parse(str);
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
catch (e) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Method to update / add scenarios to the repo.
|
|
20
|
-
* @param path
|
|
21
|
-
* @returns updated paths of scenarios
|
|
22
|
-
*/
|
|
23
|
-
async function loadScenariosFromGsheet(path) {
|
|
24
|
-
const { GoogleSpreadsheet } = await import("google-spreadsheet");
|
|
25
|
-
const url = new URL(path);
|
|
26
|
-
const docId = url.pathname.split("/")[3];
|
|
27
|
-
const searchParams = new URLSearchParams(url.hash.split("#")[1]);
|
|
28
|
-
const sheetId = Number(searchParams.get("gid")) || 0;
|
|
29
|
-
// TODO: use oauth 2
|
|
30
|
-
const serviceAccountAuth = new google_auth_library_1.JWT({
|
|
31
|
-
email: process.env.GOOGLE_SERVICE_EMAIL,
|
|
32
|
-
key: Buffer.from(process.env.GOOGLE_SERVICE_EMAIL_PRIVATE_KEY, "base64").toString(),
|
|
33
|
-
scopes: ["https://www.googleapis.com/auth/spreadsheets"],
|
|
34
|
-
});
|
|
35
|
-
const doc = new GoogleSpreadsheet(docId, serviceAccountAuth);
|
|
36
|
-
await doc.loadInfo();
|
|
37
|
-
const sheet = doc.sheetsById[sheetId];
|
|
38
|
-
const rows = await sheet.getRows();
|
|
39
|
-
const map = new Map();
|
|
40
|
-
rows.forEach((r) => {
|
|
41
|
-
// TODO: fix for case insensitive
|
|
42
|
-
const category = r.get("Category");
|
|
43
|
-
const name = r.get("Scenario");
|
|
44
|
-
const steps = r
|
|
45
|
-
.get("Steps")
|
|
46
|
-
.split("\n")
|
|
47
|
-
.map((s) => s.trim())
|
|
48
|
-
.filter((s) => !!s.length);
|
|
49
|
-
const assert = r.get("Assert");
|
|
50
|
-
const specPath = category
|
|
51
|
-
? `./tests/${category}.spec.ts`
|
|
52
|
-
: `./tests/${(0, slugify_1.default)(name)}.spec.ts`;
|
|
53
|
-
const scenario = {
|
|
54
|
-
steps,
|
|
55
|
-
name,
|
|
56
|
-
assert,
|
|
57
|
-
};
|
|
58
|
-
if (!map.get(specPath)) {
|
|
59
|
-
map.set(specPath, [scenario]);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const scenarios = map.get(specPath);
|
|
63
|
-
scenarios.push(scenario);
|
|
64
|
-
map.set(specPath, scenarios);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
const results = [];
|
|
68
|
-
for (const [specPath, scenarios] of map.entries()) {
|
|
69
|
-
results.push({
|
|
70
|
-
specPath,
|
|
71
|
-
scenarios,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
return results;
|
|
75
|
-
}
|
|
76
4
|
async function loadTestConfigs(scenariosPath) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
},
|
|
89
|
-
];
|
|
90
|
-
// api flow
|
|
91
|
-
}
|
|
92
|
-
else if (isValidJSON(atob(scenariosPath))) {
|
|
93
|
-
const str = atob(scenariosPath);
|
|
94
|
-
const config = JSON.parse(str);
|
|
95
|
-
const specPath = `./tests/${config.group || "index"}.spec.ts`;
|
|
96
|
-
return [
|
|
97
|
-
{
|
|
98
|
-
specPath,
|
|
99
|
-
scenarios: [
|
|
100
|
-
{
|
|
101
|
-
name: config.name,
|
|
102
|
-
steps: config.steps.filter((s) => !!s),
|
|
103
|
-
assert: config.assert,
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
options: config.options,
|
|
107
|
-
},
|
|
108
|
-
];
|
|
109
|
-
}
|
|
110
|
-
throw Error("Invalid path for test scenarios");
|
|
5
|
+
const str = atob(scenariosPath);
|
|
6
|
+
const config = JSON.parse(str);
|
|
7
|
+
const specPath = `./tests/${config.group || "index"}.spec.ts`;
|
|
8
|
+
return {
|
|
9
|
+
specPath,
|
|
10
|
+
testCase: {
|
|
11
|
+
name: config.name,
|
|
12
|
+
steps: config.steps.filter((s) => !!s),
|
|
13
|
+
},
|
|
14
|
+
options: config.options,
|
|
15
|
+
};
|
|
111
16
|
}
|
|
112
17
|
exports.loadTestConfigs = loadTestConfigs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"AAMA,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,IAAI,CAAa;gBACb,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAGtC,WAAW,CAAC,QAAQ,EAAE,MAAM;IAGtB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAkC1C;AAED,wBAAsB,gBAAgB,kBAAK"}
|
package/dist/file/server.js
CHANGED
|
@@ -8,7 +8,6 @@ const express_1 = __importDefault(require("express"));
|
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const web_1 = require("../bin/utils/platform/web");
|
|
11
|
-
const string_1 = require("../utils/string");
|
|
12
11
|
class FileService {
|
|
13
12
|
filePath = "";
|
|
14
13
|
port = 0;
|
|
@@ -21,17 +20,16 @@ class FileService {
|
|
|
21
20
|
async startFileService() {
|
|
22
21
|
const app = (0, express_1.default)();
|
|
23
22
|
app.use(express_1.default.json());
|
|
24
|
-
app.post("/test", (req, res) => {
|
|
25
|
-
const { generatedCode
|
|
23
|
+
app.post("/test", async (req, res) => {
|
|
24
|
+
const { generatedCode } = req.body;
|
|
26
25
|
try {
|
|
27
26
|
const testFilePath = path_1.default.resolve(process.cwd(), this.filePath);
|
|
28
27
|
if (testFilePath) {
|
|
29
28
|
const testFile = fs_1.default.readFileSync(testFilePath, "utf-8");
|
|
30
|
-
const
|
|
31
|
-
const updatedTestFile = testFile.replace(/await createTest\([\s\S]*?\);\n/, jsComments + "\n" + generatedCode);
|
|
29
|
+
const updatedTestFile = testFile.replace(/await createTest\([\s\S]*?\);\n/, "\n" + generatedCode);
|
|
32
30
|
const importStatement = `import { test, expect } from "@playwright/test";`;
|
|
33
31
|
fs_1.default.writeFileSync(testFilePath, importStatement + "\n" + updatedTestFile, "utf-8");
|
|
34
|
-
(0, web_1.lintErrors)(testFilePath);
|
|
32
|
+
await (0, web_1.lintErrors)(testFilePath);
|
|
35
33
|
return res.send({ success: true });
|
|
36
34
|
}
|
|
37
35
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -15,8 +15,7 @@ process.on("SIGTERM", async () => await (0, llm_1.flushAllTraces)());
|
|
|
15
15
|
async function createTest(task, page, test) {
|
|
16
16
|
const port = process.env.APP_PORT || 3030;
|
|
17
17
|
const testConfigArg = process.env.TEST_GEN_TOKEN;
|
|
18
|
-
const {
|
|
19
|
-
const [testGenConfig] = testGenConfigs;
|
|
18
|
+
const { testGenConfig } = await (0, utils_1.parseCliArgs)(testConfigArg);
|
|
20
19
|
(0, reporter_1.setReporterConfig)(testGenConfig.options?.metadata);
|
|
21
20
|
const fileService = new client_1.default(Number(port));
|
|
22
21
|
test.setTimeout(900000);
|
package/dist/reporter/ci.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function reportOnCI(
|
|
1
|
+
import { TestCase } from "../types";
|
|
2
|
+
export declare function reportOnCI(testCase: TestCase): Promise<TestCase>;
|
|
3
3
|
//# sourceMappingURL=ci.d.ts.map
|
|
@@ -1 +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,
|
|
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,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOtE"}
|
package/dist/reporter/ci.js
CHANGED
|
@@ -25,17 +25,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.reportOnCI = void 0;
|
|
27
27
|
const core = __importStar(require("@actions/core"));
|
|
28
|
-
async function reportOnCI(
|
|
28
|
+
async function reportOnCI(testCase) {
|
|
29
29
|
if ("true") {
|
|
30
|
-
const
|
|
31
|
-
const scenariosOutput = scenarios
|
|
32
|
-
.map((s) => {
|
|
33
|
-
return `**Scenario:** ${s.name} \n\n**Steps:**\n - ${s.steps.join("\n - ")}`;
|
|
34
|
-
})
|
|
35
|
-
.join("\n ----- \n");
|
|
30
|
+
const scenariosOutput = `**Scenario:** ${testCase.name} \n\n**Steps:**\n - ${testCase.steps.join("\n - ")}`;
|
|
36
31
|
core.setOutput("summary", scenariosOutput);
|
|
37
|
-
core.setOutput("test_names",
|
|
32
|
+
core.setOutput("test_names", testCase.name);
|
|
38
33
|
}
|
|
39
|
-
return
|
|
34
|
+
return testCase;
|
|
40
35
|
}
|
|
41
36
|
exports.reportOnCI = reportOnCI;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -20,13 +20,12 @@ export type TestGenConfigOptions = {
|
|
|
20
20
|
};
|
|
21
21
|
export type TestGenConfig = {
|
|
22
22
|
specPath: string;
|
|
23
|
-
|
|
23
|
+
testCase: TestCase;
|
|
24
24
|
options?: TestGenConfigOptions;
|
|
25
25
|
};
|
|
26
|
-
export type
|
|
26
|
+
export type TestCase = {
|
|
27
27
|
name: string;
|
|
28
28
|
steps: string[];
|
|
29
|
-
assert: string;
|
|
30
29
|
};
|
|
31
30
|
export type PlaywrightActionGenerator = (page: Page) => Action;
|
|
32
31
|
export type ActionSchema = OpenAI.Chat.Completions.ChatCompletionTool;
|
|
@@ -1 +1 @@
|
|
|
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;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,
|
|
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;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,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"}
|