@empiricalrun/test-gen 0.43.1 → 0.43.3
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 +17 -0
- package/dist/actions/skill.d.ts.map +1 -1
- package/dist/actions/skill.js +1 -0
- package/dist/agent/browsing/run.d.ts +3 -16
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +9 -10
- 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 +3 -3
- package/dist/agent/master/action-tool-calls.d.ts.map +1 -1
- package/dist/agent/master/action-tool-calls.js +2 -1
- package/dist/agent/master/browser-tests/index.spec.js +1 -1
- package/dist/agent/master/next-action.d.ts.map +1 -1
- package/dist/agent/master/next-action.js +5 -2
- package/dist/agent/master/run.d.ts.map +1 -1
- package/dist/agent/master/run.js +5 -0
- package/dist/agent/planner/run.d.ts +1 -1
- package/dist/agent/planner/run.d.ts.map +1 -1
- package/dist/agent/planner/run.js +91 -28
- package/dist/bin/index.js +33 -16
- package/dist/bin/utils/index.d.ts +7 -5
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +10 -26
- package/dist/bin/utils/platform/web/index.d.ts +1 -1
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +2 -2
- package/dist/bin/utils/scenarios/index.d.ts +3 -0
- package/dist/bin/utils/scenarios/index.d.ts.map +1 -1
- package/dist/bin/utils/scenarios/index.js +33 -1
- package/dist/browser-injected-scripts/annotate-elements.spec.js +22 -0
- package/dist/browser-injected-scripts/annotate-elements.spec.ts +32 -0
- package/dist/file/client.d.ts +1 -0
- package/dist/file/client.d.ts.map +1 -1
- package/dist/file/client.js +16 -0
- package/dist/file/server.d.ts +4 -2
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +8 -4
- package/dist/human-in-the-loop/cli.d.ts +2 -0
- package/dist/human-in-the-loop/cli.d.ts.map +1 -0
- package/dist/human-in-the-loop/cli.js +24 -0
- package/dist/human-in-the-loop/index.d.ts +10 -0
- package/dist/human-in-the-loop/index.d.ts.map +1 -0
- package/dist/human-in-the-loop/index.js +24 -0
- package/dist/human-in-the-loop/ipc.d.ts +4 -0
- package/dist/human-in-the-loop/ipc.d.ts.map +1 -0
- package/dist/human-in-the-loop/ipc.js +48 -0
- package/dist/initSentry.js +1 -1
- package/dist/prompts/lib/ts-transformer.d.ts.map +1 -1
- package/dist/prompts/lib/ts-transformer.js +3 -1
- package/dist/reporter/index.d.ts +1 -0
- package/dist/reporter/index.d.ts.map +1 -1
- package/dist/reporter/index.js +13 -7
- package/dist/uploader/index.d.ts +4 -3
- package/dist/uploader/index.d.ts.map +1 -1
- package/dist/uploader/index.js +14 -14
- package/dist/utils/pw-test.d.ts +1 -1
- package/dist/utils/pw-test.d.ts.map +1 -1
- package/dist/utils/pw-test.js +5 -4
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,aAAa,EAEd,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,aAAa,EAEd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAetC,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GACjC,MAAM,CAgBR;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GACjC,aAAa,CAYf;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAmBnE"}
|
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadTestConfigs = void 0;
|
|
3
|
+
exports.loadTestConfigs = exports.buildTestConfigFromOptions = exports.buildTokenFromOptions = void 0;
|
|
4
|
+
function buildTokenFromOptions(options) {
|
|
5
|
+
const genConfig = buildTestConfigFromOptions(options);
|
|
6
|
+
const requestConfig = {
|
|
7
|
+
specPath: genConfig.specPath,
|
|
8
|
+
id: genConfig.testCase.id,
|
|
9
|
+
name: genConfig.testCase.name,
|
|
10
|
+
steps: genConfig.testCase.steps,
|
|
11
|
+
filePath: genConfig.testCase.filePath,
|
|
12
|
+
suites: genConfig.testCase.suites,
|
|
13
|
+
ai_gist: genConfig.testCase.ai_gist,
|
|
14
|
+
build: genConfig.build,
|
|
15
|
+
options: genConfig.options,
|
|
16
|
+
environment: genConfig.environment,
|
|
17
|
+
testErrorDiagnosis: genConfig.testErrorDiagnosis,
|
|
18
|
+
};
|
|
19
|
+
return btoa(encodeURIComponent(JSON.stringify(requestConfig)));
|
|
20
|
+
}
|
|
21
|
+
exports.buildTokenFromOptions = buildTokenFromOptions;
|
|
22
|
+
function buildTestConfigFromOptions(options) {
|
|
23
|
+
return {
|
|
24
|
+
specPath: `./tests/${options.file}`,
|
|
25
|
+
testCase: {
|
|
26
|
+
id: 0,
|
|
27
|
+
name: options.name,
|
|
28
|
+
steps: [options.prompt],
|
|
29
|
+
filePath: options.file,
|
|
30
|
+
// TODO: Support suites in this flow
|
|
31
|
+
suites: [],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
exports.buildTestConfigFromOptions = buildTestConfigFromOptions;
|
|
4
36
|
function loadTestConfigs(testGenToken) {
|
|
5
37
|
const str = decodeURIComponent(atob(testGenToken));
|
|
6
38
|
const config = JSON.parse(str);
|
|
@@ -183,3 +183,25 @@ const action_tool_calls_1 = require("../agent/master/action-tool-calls");
|
|
|
183
183
|
test_1.test.expect(annotations.length).toBe(1);
|
|
184
184
|
test_1.test.expect(annotations[0]?.tagName).toBe("DIV");
|
|
185
185
|
});
|
|
186
|
+
test_1.test.fail("should not annotate children that don't have onClick handler", async ({ page }) => {
|
|
187
|
+
await page.setContent(`<div class="button-outer" onclick="alert('clicked')">
|
|
188
|
+
<div class="button-inner">Click me</div>
|
|
189
|
+
</div>`);
|
|
190
|
+
await page.addScriptTag({
|
|
191
|
+
path: path_1.default.resolve(__dirname, "./annotate-elements.js"),
|
|
192
|
+
});
|
|
193
|
+
const annotations = await page.evaluate(() => {
|
|
194
|
+
// eslint-disable-next-line no-undef
|
|
195
|
+
const { annotations } = annotateElementsWithPreference();
|
|
196
|
+
return Object.entries(annotations).map(([hint, config]) => ({
|
|
197
|
+
hint,
|
|
198
|
+
innerText: config.node.innerText?.toLowerCase().trim(),
|
|
199
|
+
tagName: config.node.tagName,
|
|
200
|
+
testId: config.node.getAttribute("data-testid"),
|
|
201
|
+
className: config.node.className,
|
|
202
|
+
}));
|
|
203
|
+
});
|
|
204
|
+
console.log(annotations);
|
|
205
|
+
test_1.test.expect(annotations.length).toBe(1);
|
|
206
|
+
test_1.test.expect(annotations[0].className).toBe("button-outer");
|
|
207
|
+
});
|
|
@@ -299,3 +299,35 @@ test("should only annotate given text on quizziz page", async ({ page }) => {
|
|
|
299
299
|
test.expect(annotations.length).toBe(1);
|
|
300
300
|
test.expect(annotations[0]?.tagName).toBe("DIV");
|
|
301
301
|
});
|
|
302
|
+
|
|
303
|
+
test.fail(
|
|
304
|
+
"should not annotate children that don't have onClick handler",
|
|
305
|
+
async ({ page }) => {
|
|
306
|
+
await page.setContent(
|
|
307
|
+
`<div class="button-outer" onclick="alert('clicked')">
|
|
308
|
+
<div class="button-inner">Click me</div>
|
|
309
|
+
</div>`,
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
await page.addScriptTag({
|
|
313
|
+
path: path.resolve(__dirname, "./annotate-elements.js"),
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const annotations = await page.evaluate(() => {
|
|
317
|
+
// eslint-disable-next-line no-undef
|
|
318
|
+
const { annotations } = annotateElementsWithPreference();
|
|
319
|
+
|
|
320
|
+
return Object.entries(annotations).map(([hint, config]) => ({
|
|
321
|
+
hint,
|
|
322
|
+
innerText: config.node.innerText?.toLowerCase().trim(),
|
|
323
|
+
tagName: config.node.tagName,
|
|
324
|
+
testId: config.node.getAttribute("data-testid"),
|
|
325
|
+
className: config.node.className,
|
|
326
|
+
}));
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
console.log(annotations);
|
|
330
|
+
test.expect(annotations.length).toBe(1);
|
|
331
|
+
test.expect(annotations[0].className).toBe("button-outer");
|
|
332
|
+
},
|
|
333
|
+
);
|
package/dist/file/client.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/file/client.ts"],"names":[],"mappings":"AAAA,cAAM,eAAe;IACnB,OAAO,EAAE,MAAM,CAAC;gBACJ,IAAI,EAAE,MAAM;IAIlB,UAAU,CAAC,EACf,aAAa,EACb,IAAI,EACJ,WAAW,GACZ,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/file/client.ts"],"names":[],"mappings":"AAAA,cAAM,eAAe;IACnB,OAAO,EAAE,MAAM,CAAC;gBACJ,IAAI,EAAE,MAAM;IAIlB,UAAU,CAAC,EACf,aAAa,EACb,IAAI,EACJ,WAAW,GACZ,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB;IAgBK,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;CAgBnC;AAED,eAAe,eAAe,CAAC"}
|
package/dist/file/client.js
CHANGED
|
@@ -20,5 +20,21 @@ class TestFileService {
|
|
|
20
20
|
console.log("Generated and updated test successfully");
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
async post(path, body) {
|
|
24
|
+
const resp = await fetch(`${this.baseUrl}${path}`, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify(body),
|
|
30
|
+
});
|
|
31
|
+
if (!resp.ok) {
|
|
32
|
+
throw new Error(`API failed with status ${resp.statusText}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const data = await resp.json();
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
23
39
|
}
|
|
24
40
|
exports.default = TestFileService;
|
package/dist/file/server.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export declare class FileService {
|
|
2
|
-
private filePath;
|
|
3
2
|
private port;
|
|
4
|
-
|
|
3
|
+
private filePath;
|
|
4
|
+
private repoDir;
|
|
5
|
+
constructor({ port, repoDir }: {
|
|
5
6
|
port: number;
|
|
7
|
+
repoDir: string;
|
|
6
8
|
});
|
|
7
9
|
setFilePath(filePath: string): void;
|
|
8
10
|
startFileService(): Promise<number>;
|
|
@@ -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":"AAWA,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAc;gBAEjB,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAKhE,WAAW,CAAC,QAAQ,EAAE,MAAM;IAItB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAyC1C;AAED,wBAAsB,gBAAgB,kBAAK"}
|
package/dist/file/server.js
CHANGED
|
@@ -8,11 +8,14 @@ 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 ipc_1 = require("../human-in-the-loop/ipc");
|
|
11
12
|
class FileService {
|
|
12
|
-
filePath = "";
|
|
13
13
|
port = 0;
|
|
14
|
-
|
|
14
|
+
filePath = "";
|
|
15
|
+
repoDir = "";
|
|
16
|
+
constructor({ port, repoDir }) {
|
|
15
17
|
this.port = port;
|
|
18
|
+
this.repoDir = repoDir;
|
|
16
19
|
}
|
|
17
20
|
setFilePath(filePath) {
|
|
18
21
|
this.filePath = filePath;
|
|
@@ -20,14 +23,15 @@ class FileService {
|
|
|
20
23
|
async startFileService() {
|
|
21
24
|
const app = (0, express_1.default)();
|
|
22
25
|
app.use(express_1.default.json());
|
|
26
|
+
(0, ipc_1.humanLoopRoute)(app);
|
|
23
27
|
app.post("/test", async (req, res) => {
|
|
24
28
|
const { generatedCode, importPaths } = req.body;
|
|
25
29
|
try {
|
|
26
|
-
const testFilePath = path_1.default.resolve(
|
|
30
|
+
const testFilePath = path_1.default.resolve(this.repoDir, this.filePath);
|
|
27
31
|
if (testFilePath) {
|
|
28
32
|
const testFile = fs_1.default.readFileSync(testFilePath, "utf-8");
|
|
29
33
|
const newContents = (0, web_1.replaceCreateTestWithNewCode)(testFilePath, testFile, generatedCode);
|
|
30
|
-
const importStatements = await (0, web_1.importAllExportsStmtFromFilePaths)(importPaths, this.filePath);
|
|
34
|
+
const importStatements = await (0, web_1.importAllExportsStmtFromFilePaths)(this.repoDir, importPaths, this.filePath);
|
|
31
35
|
fs_1.default.writeFileSync(testFilePath, `${importStatements.join("\n")}\n${newContents}`, "utf-8");
|
|
32
36
|
await (0, web_1.lintErrors)(testFilePath);
|
|
33
37
|
return res.send({ success: true });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/human-in-the-loop/cli.ts"],"names":[],"mappings":"AAEA,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
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.getFeedbackUsingCli = void 0;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
async function getFeedbackUsingCli(message) {
|
|
9
|
+
const answers = await inquirer_1.default.prompt([
|
|
10
|
+
{
|
|
11
|
+
type: "input",
|
|
12
|
+
name: "feedback",
|
|
13
|
+
message: message || "Does this plan look good?",
|
|
14
|
+
validate: (input) => {
|
|
15
|
+
if (input.trim().length === 0) {
|
|
16
|
+
return "Feedback cannot be empty";
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
]);
|
|
22
|
+
return answers.feedback;
|
|
23
|
+
}
|
|
24
|
+
exports.getFeedbackUsingCli = getFeedbackUsingCli;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/human-in-the-loop/index.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IAER,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,KAAK,CAAA;KAAE;IAChD,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;CAOnD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HumanLoop = void 0;
|
|
4
|
+
const cli_1 = require("./cli");
|
|
5
|
+
const ipc_1 = require("./ipc");
|
|
6
|
+
// TODO: how to make this more conversational
|
|
7
|
+
// do we need a layer to understand the feedback ?
|
|
8
|
+
// we need a layer to put the feedback in the context again
|
|
9
|
+
// and then we need to generate final output which the user can review
|
|
10
|
+
class HumanLoop {
|
|
11
|
+
options;
|
|
12
|
+
// TODO: have a better name for this
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async getFeedback({ message }) {
|
|
17
|
+
// this needs to have a provider based on environment
|
|
18
|
+
if (this.options.method === "ipc") {
|
|
19
|
+
return await (0, ipc_1.getFeedbackUsingIPC)(message);
|
|
20
|
+
}
|
|
21
|
+
return await (0, cli_1.getFeedbackUsingCli)(message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.HumanLoop = HumanLoop;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../../src/human-in-the-loop/ipc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKvC,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,QAwB1C;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa1E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
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.getFeedbackUsingIPC = exports.humanLoopRoute = void 0;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const client_1 = __importDefault(require("../file/client"));
|
|
9
|
+
function humanLoopRoute(app) {
|
|
10
|
+
app.post("/converse", async (req, res) => {
|
|
11
|
+
const { message } = req.body;
|
|
12
|
+
try {
|
|
13
|
+
const answers = await inquirer_1.default.prompt([
|
|
14
|
+
{
|
|
15
|
+
type: "input",
|
|
16
|
+
name: "feedback",
|
|
17
|
+
message: message || "Does this plan look good?",
|
|
18
|
+
validate: (input) => {
|
|
19
|
+
if (input.trim().length === 0) {
|
|
20
|
+
return "Feedback cannot be empty";
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
return res.send({
|
|
27
|
+
...answers,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error(e);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
exports.humanLoopRoute = humanLoopRoute;
|
|
36
|
+
async function getFeedbackUsingIPC(message) {
|
|
37
|
+
const port = process.env.APP_PORT || 3030;
|
|
38
|
+
const fileService = new client_1.default(Number(port));
|
|
39
|
+
try {
|
|
40
|
+
const resp = await fileService.post("/converse", { message });
|
|
41
|
+
return resp.feedback;
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
console.error("[getFeedbackUsingIPC] Error while fetching feedback using IPC", e);
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.getFeedbackUsingIPC = getFeedbackUsingIPC;
|
package/dist/initSentry.js
CHANGED
|
@@ -25,7 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
const Sentry = __importStar(require("@sentry/node"));
|
|
27
27
|
Sentry.init({
|
|
28
|
-
enabled: process.env.NODE_ENV
|
|
28
|
+
enabled: process.env.NODE_ENV === "production",
|
|
29
29
|
dsn: "https://87e61b11ede1431d7156bcd26da997cc@o4506822020235264.ingest.us.sentry.io/4508806031015936",
|
|
30
30
|
tracesSampleRate: 1.0,
|
|
31
31
|
serverName: "test-gen",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts-transformer.d.ts","sourceRoot":"","sources":["../../../src/prompts/lib/ts-transformer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,iBAAS,2BAA2B,IAAI,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"ts-transformer.d.ts","sourceRoot":"","sources":["../../../src/prompts/lib/ts-transformer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,iBAAS,2BAA2B,IAAI,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,CAsG3E;AAED,eAAe,2BAA2B,CAAC"}
|
|
@@ -32,7 +32,9 @@ function createHandlebarsTransformer() {
|
|
|
32
32
|
const importToVarMap = new Map();
|
|
33
33
|
const visitor = (node) => {
|
|
34
34
|
// Handle references to the imported identifiers
|
|
35
|
-
if (ts.isIdentifier(node) &&
|
|
35
|
+
if (ts.isIdentifier(node) &&
|
|
36
|
+
importToVarMap.has(node.text) &&
|
|
37
|
+
!ts.isPropertyAccessExpression(node.parent)) {
|
|
36
38
|
return ts.factory.createIdentifier(importToVarMap.get(node.text));
|
|
37
39
|
}
|
|
38
40
|
return ts.visitEachChild(node, visitor, context);
|
package/dist/reporter/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare function getReporter(): Reporter | undefined;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function setReporterConfig(config: ReporterConfigType): void;
|
|
19
19
|
export declare class TestGenUpdatesReporter {
|
|
20
|
+
private repoDir;
|
|
20
21
|
constructor();
|
|
21
22
|
sendGenTrace(trace: string): Promise<void>;
|
|
22
23
|
reportGenAssets({ projectRepoName, testName, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAa5E,KAAK,kBAAkB,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAa5E,KAAK,kBAAkB,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,OAAO,CAAS;;IAKlB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,eAAe,CAAC,EACpB,eAAe,EACf,QAAQ,GACT,EAAE;QACD,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAiDK,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C9C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWxD"}
|
package/dist/reporter/index.js
CHANGED
|
@@ -40,7 +40,10 @@ function setReporterConfig(config) {
|
|
|
40
40
|
}
|
|
41
41
|
exports.setReporterConfig = setReporterConfig;
|
|
42
42
|
class TestGenUpdatesReporter {
|
|
43
|
-
|
|
43
|
+
repoDir;
|
|
44
|
+
constructor() {
|
|
45
|
+
this.repoDir = process.cwd();
|
|
46
|
+
}
|
|
44
47
|
async sendGenTrace(trace) {
|
|
45
48
|
console.log("trace", trace);
|
|
46
49
|
// upload trace to r2 and report it to reporter
|
|
@@ -56,6 +59,7 @@ class TestGenUpdatesReporter {
|
|
|
56
59
|
const { videoUrls, traceFiles } = await (0, uploader_1.uploadTestResultsUsingPrjRepo)({
|
|
57
60
|
projectRepoName,
|
|
58
61
|
testName,
|
|
62
|
+
repoDir: this.repoDir,
|
|
59
63
|
});
|
|
60
64
|
const reporter = getReporter();
|
|
61
65
|
const message = {
|
|
@@ -101,24 +105,26 @@ class TestGenUpdatesReporter {
|
|
|
101
105
|
}
|
|
102
106
|
try {
|
|
103
107
|
// upload current screenshot to r2 and report it to reporter
|
|
104
|
-
if (!fs_extra_1.default.existsSync(path_1.default.join(
|
|
105
|
-
await fs_extra_1.default.mkdir(
|
|
108
|
+
if (!fs_extra_1.default.existsSync(path_1.default.join(this.repoDir, "gen-assets"))) {
|
|
109
|
+
await fs_extra_1.default.mkdir(this.repoDir, "gen-assets");
|
|
106
110
|
}
|
|
107
|
-
await fs_extra_1.default.writeFile(path_1.default.join(
|
|
111
|
+
await fs_extra_1.default.writeFile(path_1.default.join(this.repoDir, "gen-assets", `current-view-${Date.now()}.png`), buffer);
|
|
108
112
|
const uploadDir = (0, uploader_1.getUploadPathForRun)(reporterConfig?.projectRepoName);
|
|
109
113
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
110
|
-
sourceDir: path_1.default.join(
|
|
114
|
+
sourceDir: path_1.default.join(this.repoDir, "gen-assets"),
|
|
111
115
|
destinationDir: uploadDir,
|
|
112
116
|
uploadBucket: uploader_1.UPLOAD_BUCKET,
|
|
113
117
|
});
|
|
114
118
|
const filePath = Object.keys(files)[0];
|
|
115
|
-
const relativeFilePath = filePath.replace(path_1.default.join(
|
|
119
|
+
const relativeFilePath = filePath.replace(path_1.default.join(this.repoDir, "gen-assets"), "");
|
|
116
120
|
const url = `${uploader_1.UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
|
|
117
121
|
await getReporter()?.report(new reporter_1.ProcessLogMessageBuilder({
|
|
118
122
|
type: "current-snapshot",
|
|
119
123
|
message: JSON.stringify({ type: "current-view", url }),
|
|
120
124
|
}));
|
|
121
|
-
await fs_extra_1.default.rmdir((
|
|
125
|
+
await fs_extra_1.default.rmdir(path_1.default.join(this.repoDir, "gen-assets"), {
|
|
126
|
+
recursive: true,
|
|
127
|
+
});
|
|
122
128
|
}
|
|
123
129
|
catch (e) {
|
|
124
130
|
console.warn("Failed to upload current view screenshot", e);
|
package/dist/uploader/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const UPLOAD_BUCKET = "test-report";
|
|
2
2
|
export declare const UPLOAD_DOMAIN = "https://reports.empirical.run";
|
|
3
|
-
export declare function getFullUploadPath(filePath: string, uploadDir: string): string;
|
|
4
|
-
export declare function getRelativeUploadPath(filePath: string): string;
|
|
3
|
+
export declare function getFullUploadPath(repoDir: string, filePath: string, uploadDir: string): string;
|
|
4
|
+
export declare function getRelativeUploadPath(filePath: string, repoDir: string): string;
|
|
5
5
|
/**
|
|
6
6
|
* Function to upload test results to R2 using the project repo name and test name.
|
|
7
7
|
* This function uploads both the JSON summary of test results and associated video files.
|
|
@@ -12,9 +12,10 @@ export declare function getRelativeUploadPath(filePath: string): string;
|
|
|
12
12
|
* @returns {string[]} returns.videoUrls - URLs of the uploaded video files.
|
|
13
13
|
* @returns {string} returns.summaryUrl - URL of the uploaded summary JSON file.
|
|
14
14
|
*/
|
|
15
|
-
export declare function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }: {
|
|
15
|
+
export declare function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, repoDir, }: {
|
|
16
16
|
projectRepoName: string;
|
|
17
17
|
testName: string;
|
|
18
|
+
repoDir: string;
|
|
18
19
|
}): Promise<{
|
|
19
20
|
videoUrls: string[];
|
|
20
21
|
summaryUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uploader/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAG7D,wBAAgB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uploader/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAG7D,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,UAKlB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAEtE;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,eAAe,EACf,QAAQ,EACR,OAAO,GACR,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC,CAgED;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,UAM1D;AAED,wBAAgB,2BAA2B,uBAQ1C"}
|
package/dist/uploader/index.js
CHANGED
|
@@ -16,14 +16,14 @@ const PLAYWRIGHT_REPORT_DATA = "playwright-report/data";
|
|
|
16
16
|
exports.UPLOAD_BUCKET = "test-report";
|
|
17
17
|
exports.UPLOAD_DOMAIN = "https://reports.empirical.run"; // domain based on bucket mentioned above
|
|
18
18
|
const uploadId = crypto.randomUUID();
|
|
19
|
-
function getFullUploadPath(filePath, uploadDir) {
|
|
19
|
+
function getFullUploadPath(repoDir, filePath, uploadDir) {
|
|
20
20
|
// remove the source dir from the file path - only keep the relative path
|
|
21
|
-
const relativeFilePath = getRelativeUploadPath(filePath);
|
|
21
|
+
const relativeFilePath = getRelativeUploadPath(filePath, repoDir);
|
|
22
22
|
return `${exports.UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
|
|
23
23
|
}
|
|
24
24
|
exports.getFullUploadPath = getFullUploadPath;
|
|
25
|
-
function getRelativeUploadPath(filePath) {
|
|
26
|
-
return filePath.replace(path_1.default.join(
|
|
25
|
+
function getRelativeUploadPath(filePath, repoDir) {
|
|
26
|
+
return filePath.replace(path_1.default.join(repoDir, PLAYWRIGHT_REPORT_DATA), "");
|
|
27
27
|
}
|
|
28
28
|
exports.getRelativeUploadPath = getRelativeUploadPath;
|
|
29
29
|
/**
|
|
@@ -36,25 +36,25 @@ exports.getRelativeUploadPath = getRelativeUploadPath;
|
|
|
36
36
|
* @returns {string[]} returns.videoUrls - URLs of the uploaded video files.
|
|
37
37
|
* @returns {string} returns.summaryUrl - URL of the uploaded summary JSON file.
|
|
38
38
|
*/
|
|
39
|
-
async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
39
|
+
async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, repoDir, }) {
|
|
40
40
|
const uploadDir = getUploadPathForRun(projectRepoName);
|
|
41
|
-
console.log("Current directory for assets upload",
|
|
41
|
+
console.log("Current directory for assets upload", repoDir);
|
|
42
42
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
43
|
-
sourceDir: path_1.default.join(
|
|
43
|
+
sourceDir: path_1.default.join(repoDir, PLAYWRIGHT_REPORT_DATA),
|
|
44
44
|
destinationDir: uploadDir,
|
|
45
45
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
46
46
|
});
|
|
47
47
|
// upload summary.json
|
|
48
48
|
await (0, r2_uploader_1.uploadDirectory)({
|
|
49
|
-
sourceDir: path_1.default.join(
|
|
50
|
-
fileList: [path_1.default.join(
|
|
49
|
+
sourceDir: path_1.default.join(repoDir, "playwright-report"),
|
|
50
|
+
fileList: [path_1.default.join(repoDir, "playwright-report", "summary.json")],
|
|
51
51
|
destinationDir: uploadDir,
|
|
52
52
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
53
53
|
});
|
|
54
54
|
// fileNames are relative upload paths
|
|
55
55
|
const fileNames = Object.keys(files);
|
|
56
|
-
console.log("Uploaded files", fileNames.map((f) => getFullUploadPath(f, uploadDir)));
|
|
57
|
-
const defaultLocation = path_1.default.join(
|
|
56
|
+
console.log("Uploaded files", fileNames.map((f) => getFullUploadPath(repoDir, f, uploadDir)));
|
|
57
|
+
const defaultLocation = path_1.default.join(repoDir, "playwright-report", "summary.json");
|
|
58
58
|
const results = (0, reporter_1.parseJsonReport)(defaultLocation);
|
|
59
59
|
const flatTestsList = (0, reporter_1.getFlattenedTestList)(results.suites);
|
|
60
60
|
const testAttachmentPaths = [];
|
|
@@ -65,7 +65,7 @@ async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
|
65
65
|
// results array is basically made by retries
|
|
66
66
|
for (const attachments of test.tests[0].results[0].attachments) {
|
|
67
67
|
if (attachments.path) {
|
|
68
|
-
testAttachmentPaths.push(getRelativeUploadPath(attachments.path));
|
|
68
|
+
testAttachmentPaths.push(getRelativeUploadPath(attachments.path, repoDir));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -78,11 +78,11 @@ async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
|
78
78
|
console.log("traceFiles", traceFiles);
|
|
79
79
|
return {
|
|
80
80
|
videoUrls: videoFiles
|
|
81
|
-
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
81
|
+
.map((fileName) => getFullUploadPath(repoDir, fileName, uploadDir))
|
|
82
82
|
.filter((url) => !!url),
|
|
83
83
|
summaryUrl: `${exports.UPLOAD_DOMAIN}/${uploadDir}/summary.json`,
|
|
84
84
|
traceFiles: traceFiles
|
|
85
|
-
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
85
|
+
.map((fileName) => getFullUploadPath(repoDir, fileName, uploadDir))
|
|
86
86
|
.filter((url) => !!url),
|
|
87
87
|
};
|
|
88
88
|
}
|
package/dist/utils/pw-test.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,
|
|
1
|
+
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CAKd;AAED,wBAAsB,QAAQ,kBAS7B"}
|
package/dist/utils/pw-test.js
CHANGED
|
@@ -5,17 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.skipTest = exports.getTestFixtureModuleFromRepo = void 0;
|
|
7
7
|
const api_1 = __importDefault(require("tsx/cjs/api"));
|
|
8
|
-
async function getTestFixtureModuleFromRepo() {
|
|
9
|
-
const [lastDir] =
|
|
10
|
-
const dir = `${
|
|
8
|
+
async function getTestFixtureModuleFromRepo(repoDir) {
|
|
9
|
+
const [lastDir] = repoDir.split("/").reverse();
|
|
10
|
+
const dir = `${repoDir}/${lastDir}`;
|
|
11
11
|
const { test } = await api_1.default.require(`./tests/fixtures.ts`, dir);
|
|
12
12
|
return test;
|
|
13
13
|
}
|
|
14
14
|
exports.getTestFixtureModuleFromRepo = getTestFixtureModuleFromRepo;
|
|
15
15
|
async function skipTest() {
|
|
16
16
|
let test;
|
|
17
|
+
let repoDir = process.cwd();
|
|
17
18
|
try {
|
|
18
|
-
test = await getTestFixtureModuleFromRepo();
|
|
19
|
+
test = await getTestFixtureModuleFromRepo(repoDir);
|
|
19
20
|
}
|
|
20
21
|
catch (e) {
|
|
21
22
|
console.error("Error while importing fixture module to extract test:", e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"google-auth-library": "^9.10.0",
|
|
59
59
|
"google-spreadsheet": "^4.1.2",
|
|
60
60
|
"ignore": "^5.3.1",
|
|
61
|
+
"inquirer": "^12.4.2",
|
|
61
62
|
"lodash.isequal": "^4.5.0",
|
|
62
63
|
"md5": "^2.3.0",
|
|
63
64
|
"mime": "^4.0.4",
|