Files
PRA-only-demo/packages/rpa-core/test/capabilities/office-aliases.test.ts
T

118 lines
8.6 KiB
TypeScript

import { readFile, mkdtemp, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import ExcelJS from "exceljs";
import { afterEach, describe, expect, it } from "vitest";
import type { Catalog, CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../../src/engine/registry";
import "../../src/capabilities/office";
import "../../src/capabilities/extended";
import "../../src/capabilities/office-file-extended";
import { EXCEL_COMMON_ALIASES } from "../../src/capabilities/office-aliases";
const dirs: string[] = [];
const context = {} as RunContext;
const component = {} as CatalogComponent;
const node = (id: string): FlowNode => ({ id, componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });
async function run(id: string, args: Record<string, unknown>) { const handler = getHandler(id); expect(handler, id).toBeTruthy(); return handler!(context, node(id), args, component); }
afterEach(async () => Promise.all(dirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true }))));
describe("common Excel aliases", () => {
it("registers only real catalog aliases", async () => {
// vitest 工作目录为仓库根,包内测试统一以 cwd 定位仓库资源
const catalog = JSON.parse(await readFile(path.resolve(process.cwd(), "resources/catalog.json"), "utf8")) as Catalog;
const ids = new Set(catalog.components.map((item) => item.id));
expect(EXCEL_COMMON_ALIASES.length).toBeGreaterThanOrEqual(25);
for (const id of EXCEL_COMMON_ALIASES) { expect(ids.has(id), id).toBe(true); expect(getHandler(id), id).toBeTruthy(); }
});
it("runs a real create, write and read pipeline through alias IDs", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-alias-")); dirs.push(directory);
const handle = await run("Excel_NewExcel", { path: directory, name: "aliases.xlsx", override: "1" });
await run("Excel_WriteCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A", content: "alias", save: "1" });
await expect(run("Excel_ReadCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A" })).resolves.toBe("alias");
});
it("accepts the Excel_NewExcel catalog keys (filePath / isMakedirs)", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-new-")); dirs.push(directory);
const handle = await run("Excel_NewExcel", { filePath: directory, name: "catalog-keys.xlsx", isMakedirs: "True" }) as { path: string };
expect(handle.path).toBe(path.resolve(directory, "catalog-keys.xlsx"));
});
it("rejects a missing directory when isMakedirs is False", async () => {
const directory = path.join(await mkdtemp(path.join(os.tmpdir(), "rpa-excel-new-")), "missing");
dirs.push(directory);
await expect(run("Excel_NewExcel", { filePath: directory, name: "none.xlsx", isMakedirs: "False" })).rejects.toThrow("目录不存在");
});
it("opens a workbook through the Excel_OpenExcel filePath key", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-open-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "open-me.xlsx" }) as { path: string };
await expect(run("Excel_OpenExcel", { filePath: created.path })).resolves.toMatchObject({ path: created.path });
});
it("renames a sheet through the Excel_RenameSheet newSheet key", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-rename-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "rename-me.xlsx" }) as { path: string };
await expect(run("Excel_RenameSheet", { objExcel: created, sheet: "Sheet1", newSheet: "库存表", isSave: "True" })).resolves.toBeTruthy();
const reopened = await run("Excel_OpenExcel", { filePath: created.path }) as { id: string };
await expect(run("Excel_GetSheetsName", { objExcel: reopened })).resolves.toEqual(["库存表"]);
});
it("writes a range through the Excel_WriteRange catalog keys (objExcel/cellPos/data/isSave)", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-range-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "range.xlsx" }) as { path: string };
await run("Excel_WriteRange", { objExcel: created, sheet: "Sheet1", cellPos: "B2", data: [[1, "壹"], [2, "贰"]], isSave: "True" });
const reopened = await run("Excel_OpenExcel", { filePath: created.path }) as { id: string };
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "B2:C3" })).resolves.toEqual([[1, "壹"], [2, "贰"]]);
});
it("saves as through the Excel_SaveAs catalog keys (filename/isAbsolutePath)", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-saveas-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "origin.xlsx" }) as { path: string };
await run("Excel_WriteCell", { workbook: created, sheet: "Sheet1", row: 1, column: "A", content: "saveas" });
const savedAs = await run("Excel_SaveAs", { objExcel: created, filename: path.join(directory, "legacy-saveas.xlsx"), isAbsolutePath: "True" }) as { path: string };
expect(savedAs.path).toBe(path.resolve(directory, "legacy-saveas.xlsx"));
const reopened = await run("Excel_OpenExcel", { filePath: savedAs.path }) as { id: string };
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "A1" })).resolves.toEqual([["saveas"]]);
});
it("resolves a relative Excel_SaveAs filename against the original workbook directory", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-saveas-rel-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "rel-origin.xlsx" }) as { path: string };
const savedAs = await run("Excel_SaveAs", { objExcel: created, filename: "rel-target.xlsx", isAbsolutePath: "False" }) as { path: string };
expect(savedAs.path).toBe(path.resolve(directory, "rel-target.xlsx"));
});
it("combines the Excel_Cs_SaveAs directory path with the name field", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-saveas-cs-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "cs-origin.xlsx" }) as { path: string };
const targetDir = path.join(directory, "nested");
const savedAs = await run("Excel_Cs_SaveAs", { workbook: created, path: targetDir, name: "cs-target.xlsx" }) as { path: string };
expect(savedAs.path).toBe(path.resolve(targetDir, "cs-target.xlsx"));
const reopened = new ExcelJS.Workbook();
await reopened.xlsx.readFile(savedAs.path);
expect(reopened.worksheets.length).toBeGreaterThan(0);
});
it("clears a range through the Excel_ClearRange cellPos key", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-clear-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "clear.xlsx" }) as { path: string };
await run("Excel_WriteRange", { objExcel: created, sheet: "Sheet1", cellPos: "A1", data: [["甲", "乙"], ["丙", "丁"]] });
await run("Excel_ClearRange", { objExcel: created, sheet: "Sheet1", cellPos: "A1:B2", isFormat: "False", isSave: "True" });
const reopened = await run("Excel_OpenExcel", { filePath: created.path }) as { id: string };
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "A1:B2" })).resolves.toEqual([["", ""], ["", ""]]);
});
it("clears through the Excel_Cs_ClearRange startRow/startColumn keys", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-clear-cs-")); dirs.push(directory);
const created = await run("Excel_NewExcel", { filePath: directory, name: "clear-cs.xlsx" }) as { path: string };
await run("Excel_WriteRange", { objExcel: created, sheet: "Sheet1", cellPos: "A1", data: [["1", "2"], ["3", "4"]] });
await run("Excel_Cs_ClearRange", { objExcel: created, sheet: "Sheet1", startRow: "2", startColumn: "A", lastRow: "2", lastColumn: "B", mode: "内容", save: "True" });
const reopened = await run("Excel_OpenExcel", { filePath: created.path }) as { id: string };
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "A2:B2" })).resolves.toEqual([["", ""]]);
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "A1:B1" })).resolves.toEqual([["1", "2"]]);
});
});