refactor(code-executor): migrate user scripts to single context argument
- replace (page, context, helpers) signature with async (context) => {}
- add ScriptContext interface exposing page, browser, env, getEnv,
getCredential, getStepOutput, runSnippet, dumpDom, log/warn/error
- rename getEnvUrl to getEnv throughout service and docs
- fix step ordering: normalizeStepOrder and run step rows are now 1-based
- migrate existing DB rows (scenario_steps, scenario_run_steps) +1
- update all tests and stored snippet/step code in DB to new API
This commit is contained in:
@@ -136,35 +136,35 @@ describe("BrowserController", () => {
|
||||
expect(res.body).toEqual({ result: 42 });
|
||||
});
|
||||
|
||||
it("exposes environment via helpers.env in a named session", async () => {
|
||||
it("exposes environment via context.env in a named session", async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
sessionName: "no-such-session",
|
||||
code: "return helpers.env.BASE_URL;",
|
||||
code: "return context.env.BASE_URL;",
|
||||
environment: { BASE_URL: "https://env.example.com" },
|
||||
})
|
||||
.expect(201);
|
||||
expect(res.body).toEqual({ result: "https://env.example.com" });
|
||||
});
|
||||
|
||||
it("exposes environment via helpers.env in a sessionless exec", async () => {
|
||||
it("exposes environment via context.env in a sessionless exec", async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
code: "return helpers.env.KEY;",
|
||||
code: "return context.env.KEY;",
|
||||
environment: { KEY: "value123" },
|
||||
})
|
||||
.expect(201);
|
||||
expect(res.body).toEqual({ result: "value123" });
|
||||
});
|
||||
|
||||
it("exposes credentials via helpers.getCredential in a named session", async () => {
|
||||
it("exposes credentials via context.getCredential in a named session", async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
sessionName: "no-such-session",
|
||||
code: "return helpers.getCredential('admin');",
|
||||
code: "return context.getCredential('admin');",
|
||||
credentials: { admin: { username: "user1", password: "pass1" } },
|
||||
})
|
||||
.expect(201);
|
||||
@@ -173,11 +173,11 @@ describe("BrowserController", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("exposes credentials via helpers.getCredential in a sessionless exec", async () => {
|
||||
it("exposes credentials via context.getCredential in a sessionless exec", async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
code: "return helpers.getCredential('svc');",
|
||||
code: "return context.getCredential('svc');",
|
||||
credentials: { svc: { token: "abc" } },
|
||||
})
|
||||
.expect(201);
|
||||
@@ -188,7 +188,7 @@ describe("BrowserController", () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
code: "return helpers.getCredential('missing');",
|
||||
code: "return context.getCredential('missing');",
|
||||
credentials: {},
|
||||
})
|
||||
.expect(500);
|
||||
@@ -199,7 +199,7 @@ describe("BrowserController", () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post("/exec")
|
||||
.send({
|
||||
code: "return Object.keys(helpers.env).length === 0 ? 'empty' : 'not-empty';",
|
||||
code: "return Object.keys(context.env).length === 0 ? 'empty' : 'not-empty';",
|
||||
})
|
||||
.expect(201);
|
||||
expect(res.body).toEqual({ result: "empty" });
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Integration tests for ScenarioRunStepEntity.output column and the
|
||||
* helpers.getStepOutput() API available inside exec step scripts.
|
||||
* context.getStepOutput() API available inside exec step scripts.
|
||||
*
|
||||
* Strategy:
|
||||
* - Seed a session row so the scheduler can create a browser context.
|
||||
@@ -17,7 +17,7 @@ import { ScenarioService } from "../src/scenario/scenario.service";
|
||||
import { ScenarioSchedulerService } from "../src/scenario/scenario-scheduler.service";
|
||||
import { EnvironmentEntity } from "../src/environment/environment.entity";
|
||||
|
||||
describe("ScenarioRunStepEntity.output + helpers.getStepOutput", () => {
|
||||
describe("ScenarioRunStepEntity.output + context.getStepOutput", () => {
|
||||
let app: INestApplication;
|
||||
let dataSource: DataSource;
|
||||
let scenarioService: ScenarioService;
|
||||
@@ -135,15 +135,15 @@ describe("ScenarioRunStepEntity.output + helpers.getStepOutput", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── helpers.getStepOutput ──────────────────────────────────────────────────
|
||||
// ── context.getStepOutput ──────────────────────────────────────────────────
|
||||
|
||||
describe("helpers.getStepOutput()", () => {
|
||||
describe("context.getStepOutput()", () => {
|
||||
it("returns output of a previous step by absolute order", async () => {
|
||||
await seedSession();
|
||||
const scId = await createScenario("getStepOutput-absolute");
|
||||
await createStep(scId, 0, "return 99;");
|
||||
// Step 1 reads step 0's output via absolute index 0
|
||||
await createStep(scId, 1, "return await helpers.getStepOutput(0);");
|
||||
// Step 1 reads step 1's output via absolute index 1 (1-based)
|
||||
await createStep(scId, 1, "return await context.getStepOutput(1);");
|
||||
|
||||
const runId = await runScenario(scId);
|
||||
const rows = await dataSource.query(
|
||||
@@ -159,7 +159,7 @@ describe("ScenarioRunStepEntity.output + helpers.getStepOutput", () => {
|
||||
const scId = await createScenario("getStepOutput-relative");
|
||||
await createStep(scId, 0, 'return "step-zero";');
|
||||
// Step 1 uses relative index -1 to reference step 0
|
||||
await createStep(scId, 1, "return await helpers.getStepOutput(-1);");
|
||||
await createStep(scId, 1, "return await context.getStepOutput(-1);");
|
||||
|
||||
const runId = await runScenario(scId);
|
||||
const rows = await dataSource.query(
|
||||
@@ -173,7 +173,7 @@ describe("ScenarioRunStepEntity.output + helpers.getStepOutput", () => {
|
||||
await seedSession();
|
||||
const scId = await createScenario("getStepOutput-missing");
|
||||
// Step 0 tries to read step order 99 which does not exist
|
||||
await createStep(scId, 0, "return await helpers.getStepOutput(99);");
|
||||
await createStep(scId, 0, "return await context.getStepOutput(99);");
|
||||
|
||||
const runId = await runScenario(scId);
|
||||
const row = await dataSource.query(
|
||||
@@ -190,12 +190,12 @@ describe("ScenarioRunStepEntity.output + helpers.getStepOutput", () => {
|
||||
await createStep(
|
||||
scId,
|
||||
1,
|
||||
"const prev = await helpers.getStepOutput(-1); return [...prev, 3];",
|
||||
"const prev = await context.getStepOutput(-1); return [...prev, 3];",
|
||||
);
|
||||
await createStep(
|
||||
scId,
|
||||
2,
|
||||
"const prev = await helpers.getStepOutput(-1); return [...prev, 4];",
|
||||
"const prev = await context.getStepOutput(-1); return [...prev, 4];",
|
||||
);
|
||||
|
||||
const runId = await runScenario(scId);
|
||||
|
||||
@@ -216,7 +216,7 @@ describe("ScenarioController", () => {
|
||||
.expect(201);
|
||||
|
||||
expect(res.body.id).toBeDefined();
|
||||
expect(res.body.order).toBe(0);
|
||||
expect(res.body.order).toBe(1);
|
||||
});
|
||||
|
||||
it("creates a step without execCode", async () => {
|
||||
@@ -274,7 +274,7 @@ describe("ScenarioController", () => {
|
||||
.expect(200);
|
||||
|
||||
const orders = res.body.steps.map((s: { order: number }) => s.order);
|
||||
expect(orders).toEqual([0, 1, 2]);
|
||||
expect(orders).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -573,7 +573,7 @@ describe("ScenarioController", () => {
|
||||
expect(res.body.name).toBe("imported scenario");
|
||||
expect(res.body.steps).toHaveLength(3);
|
||||
expect(res.body.steps.map((s: { order: number }) => s.order)).toEqual([
|
||||
0, 1, 2,
|
||||
1, 2, 3,
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -689,7 +689,7 @@ describe("ScenarioController", () => {
|
||||
.expect(200);
|
||||
|
||||
const orders = res.body.stepRuns.map((s: { order: number }) => s.order);
|
||||
expect(orders).toEqual([0, 1, 2]);
|
||||
expect(orders).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it("returns 404 for unknown run", async () => {
|
||||
|
||||
Reference in New Issue
Block a user