Something went wrong. Try again.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495import { describe, expect, it } from "vitest";import { parseScript } from "../../runner/parser";import { printScript } from "../../runner/printer";import { expandIncludes } from "../../runner/include";
const ok = (text: string) => { const r = parseScript(text); if (!r.ok) throw new Error(JSON.stringify(r.errors)); return r.script;};const errors = (text: string, options = {}) => { const r = parseScript(text, options); return r.ok ? [] : r.errors;};const GIFT = `test "gift" needs session test-qian needs session test-buster start http://127.0.0.1:4780/gift.html step "qian makes a gift" click text:"Create gift" step "buster claims it" goto http://127.0.0.1:4780/claim.html on:test-buster click text:"Claim" on:test-buster step "qian sees it claimed" verify text:"Claimed" on:test-qian`;
describe("several sessions in one script (P5-6)", () => { it("the first needs session is the default profile, the others are extra", () => { const s = ok(GIFT); expect(s.needsSession).toBe("test-qian"); expect(s.needsLine).toBe(2); expect(s.alsoNeeds).toEqual([{ name: "test-buster", line: 3 }]); }); it("a command may say which profile does it, with on:NAME; without it, the default does", () => { const s = ok(GIFT); const commands = s.steps.flatMap((st) => st.commands); expect(commands.map((c) => [c.verb, (c as { on?: string }).on])).toEqual([["click", undefined], ["goto", "test-buster"], ["click", "test-buster"], ["verify", "test-qian"]]); }); it("a script with one needs session has no extra and its commands have no on", () => { const s = ok(`test "x"\n needs session a\n step "s"\n click text:"Go"\n`); expect(s.alsoNeeds).toBeUndefined(); }); it("the same profile twice is an error on the second line", () => { const e = errors(`test "x"\n needs session a\n needs session a\n step "s"\n click text:"Go"\n`); expect(e).toMatchObject([{ code: "E010", line: 3 }]); expect(e[0]!.message).toContain("twice"); }); it("on: naming a profile the script does not declare is an error that says how to declare it", () => { const e = errors(`test "x"\n needs session a\n step "s"\n click text:"Go" on:b\n`); expect(e).toMatchObject([{ code: "E003", line: 4 }]); expect(e[0]!.message).toBe('on:b names a profile this script does not declare: add "needs session b" at the top (declared: a)'); }); it("on: in a script that declares no profile at all says so", () => { const e = errors(`test "x"\n step "s"\n click text:"Go" on:b\n`); expect(e[0]!.message).toBe('on:b names a profile this script does not declare: add "needs session b" at the top (declared: none)'); }); it("on: needs a plain profile name", () => { for (const bad of ['on:"a b"', "on:-x", "on:a/b"]) { const e = errors(`test "x"\n needs session a\n step "s"\n click text:"Go" ${bad}\n`); expect(e[0]?.code, bad).toBe("E003"); } }); it("on: goes with any command and with other modifiers, in any order", () => { const s = ok(`test "x"\n needs session a\n needs session b\n step "s"\n verify text:"Hi" on:b timeout:2s within:"Box"\n sleep 5ms on:b\n capture total css:"#t" as:total on:a\n`); const [v, sl, cap] = s.steps[0]!.commands as Array<{ on?: string; verb: string }>; expect([v!.on, sl!.on, cap!.on]).toEqual(["b", "b", "a"]); }); it("printing and parsing again gives the same script, extra sessions and on: included", () => { const first = ok(GIFT); const second = ok(printScript(first)); expect(second.alsoNeeds?.map((n) => n.name)).toEqual(["test-buster"]); expect(second.steps.flatMap((st) => st.commands).map((c) => (c as { on?: string }).on)).toEqual([undefined, "test-buster", "test-buster", "test-qian"]); expect(printScript(second)).toBe(printScript(first)); }); it("an included script may use on: for a profile its includer declared, and is refused for one it did not", () => { const root = "/p"; const files: Record<string, string> = { "/p/scripts/main.aite": `test "main"\n needs session a\n needs session b\n step "s"\n run part.aite\n`, "/p/scripts/part.aite": `test "part"\n step "p"\n click text:"Go" on:b\n`, "/p/scripts/bad.aite": `test "main"\n needs session a\n step "s"\n run part.aite\n`, }; const expand = (main: string) => { const r = parseScript(files[main]!, { file: main }); if (!r.ok) throw new Error(JSON.stringify(r.errors)); return expandIncludes(r.script, { file: main, display: main, root, readFile: (p) => files[p] ?? (() => { throw new Error("ENOENT"); })() }); }; const good = expand("/p/scripts/main.aite"); expect(good.ok, JSON.stringify(good)).toBe(true); const bad = expand("/p/scripts/bad.aite"); expect(bad.ok).toBe(false); expect(JSON.stringify(bad)).toContain("on:b names a profile this script does not declare"); });});