refactor(rpa-core): 测试文件迁至 test/ 目录(对面 workspace 规范:产品源码树禁含测试);修 platform-groups 测试预载顺序耦合

This commit is contained in:
yu 2026-11-06 16:14:23 +08:00
parent 62652b4fca
commit 4f1fbc07dc
44 changed files with 196 additions and 187 deletions

View File

@ -1,15 +1,15 @@
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
const mocks = vi.hoisted(() => ({ powershell: vi.fn(), execFile: vi.fn() })); const mocks = vi.hoisted(() => ({ powershell: vi.fn(), execFile: vi.fn() }));
vi.mock("../driver/windows/powershell", () => ({ powershell: mocks.powershell, psString: (value: unknown) => `'${String(value ?? "").replace(/'/g, "''")}'` })); vi.mock("../driver/windows/powershell", () => ({ powershell: mocks.powershell, psString: (value: unknown) => `'${String(value ?? "").replace(/'/g, "''")}'` }));
vi.mock("node:child_process", () => ({ execFile: mocks.execFile })); vi.mock("node:child_process", () => ({ execFile: mocks.execFile }));
import "./data"; import "../../src/capabilities/data";
import "./control"; import "../../src/capabilities/control";
import "./system-extended"; import "../../src/capabilities/system-extended";
import "./windows-system"; import "../../src/capabilities/windows-system";
function run(id: string, args: Record<string, unknown> = {}, signal = new AbortController().signal) { function run(id: string, args: Record<string, unknown> = {}, signal = new AbortController().signal) {
const node: FlowNode = { id: "regression", componentId: id, values: args, options: {}, position: { x: 0, y: 0 } }; const node: FlowNode = { id: "regression", componentId: id, values: args, options: {}, position: { x: 0, y: 0 } };

View File

@ -1,15 +1,15 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./data"; import "../../src/capabilities/data";
import "./desktop"; import "../../src/capabilities/desktop";
import "./system-extended"; import "../../src/capabilities/system-extended";
import "./utility-extended"; import "../../src/capabilities/utility-extended";
import "./common-final"; import "../../src/capabilities/common-final";
import "./control"; import "../../src/capabilities/control";
import "./windows-system"; import "../../src/capabilities/windows-system";
import "./basic-encryption"; import "../../src/capabilities/basic-encryption";
const ctx = { const ctx = {
signal: new AbortController().signal, signal: new AbortController().signal,

View File

@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./desktop"; import "../../src/capabilities/desktop";
import "./basic-encryption"; import "../../src/capabilities/basic-encryption";
const context = {} as RunContext; const context = {} as RunContext;
const component = {} as CatalogComponent; const component = {} as CatalogComponent;

View File

@ -5,15 +5,15 @@ import net from "node:net";
import { describe, expect, it, afterEach } from "vitest"; import { describe, expect, it, afterEach } from "vitest";
import { PDFDocument } from "pdf-lib"; import { PDFDocument } from "pdf-lib";
import { PNG } from "pngjs"; import { PNG } from "pngjs";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import "./desktop"; import "../../src/capabilities/desktop";
import "./office"; import "../../src/capabilities/office";
import "./pdf"; import "../../src/capabilities/pdf";
import "./message"; import "../../src/capabilities/message";
import "./word"; import "../../src/capabilities/word";
import { findImage } from "./vision"; import { findImage } from "../../src/capabilities/vision";
const tempDirs: string[] = []; const tempDirs: string[] = [];
const node = (componentId: string): FlowNode => ({ const node = (componentId: string): FlowNode => ({

View File

@ -1,12 +1,12 @@
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import path from "node:path"; import path from "node:path";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./remaining-core"; import "../../src/capabilities/remaining-core";
import "./captcha-caps"; // last-wins:覆盖 remaining-core 的通用实现 import "../../src/capabilities/captcha-caps"; // last-wins:覆盖 remaining-core 的通用实现
import { cleanCodeText, parseCalculation } from "./captcha-caps"; import { cleanCodeText, parseCalculation } from "../../src/capabilities/captcha-caps";
// 测试图随仓库走(__fixtures__/captcha,PIL 生成),真实 OCR 模型来自 npm 依赖 // 测试图随仓库走(__fixtures__/captcha,PIL 生成),真实 OCR 模型来自 npm 依赖
const fixturesDir = path.join(import.meta.dirname, "__fixtures__", "captcha"); const fixturesDir = path.join(import.meta.dirname, "__fixtures__", "captcha");

View File

@ -1,8 +1,8 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./remaining-core"; import "../../src/capabilities/remaining-core";
const ctx = { signal: new AbortController().signal, log: () => {}, vars: {}, evidenceDir: "D:/office-test2/ocr-test" } as unknown as RunContext; const ctx = { signal: new AbortController().signal, log: () => {}, vars: {}, evidenceDir: "D:/office-test2/ocr-test" } as unknown as RunContext;
const node: FlowNode = { id: "smoke", componentId: "smoke", position: { x: 0, y: 0 }, values: {}, options: {} }; const node: FlowNode = { id: "smoke", componentId: "smoke", position: { x: 0, y: 0 }, values: {}, options: {} };

View File

@ -4,10 +4,10 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import { PDFDocument } from "pdf-lib"; import { PDFDocument } from "pdf-lib";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./index"; import "../../src/capabilities/index";
const dirs: string[] = []; const context = { vars: {} } as RunContext; const component = {} as CatalogComponent; const dirs: string[] = []; const context = { vars: {} } as RunContext; const component = {} as CatalogComponent;
const node = (id: string): FlowNode => ({ id, componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} }); const node = (id: string): FlowNode => ({ id, componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });

View File

@ -1,8 +1,8 @@
import { describe, it } from "vitest"; import { describe, it } from "vitest";
import { capabilityIds } from "../engine/registry"; import { capabilityIds } from "../../src/engine/registry";
import { writeFileSync } from "node:fs"; import { writeFileSync } from "node:fs";
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
import "./index"; // 汇总导入全部能力模块(与运行时同构) import "../../src/capabilities/index"; // 汇总导入全部能力模块(与运行时同构)
interface CatalogComp { interface CatalogComp {
id: string; id: string;

View File

@ -18,9 +18,9 @@ vi.mock("@gutenye/ocr-node", () => ({
default: { create: vi.fn(async () => ({ detect: detectMock })) } default: { create: vi.fn(async () => ({ detect: detectMock })) }
})); }));
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import { setHostBridge, type HostDisplay } from "../engine/host-bridge"; import { setHostBridge, type HostDisplay } from "../../src/engine/host-bridge";
import "./cv-vision"; import "../../src/capabilities/cv-vision";
const displayOf = (id: string, x: number, width: number, height: number, scaleFactor: number): HostDisplay => ({ const displayOf = (id: string, x: number, width: number, height: number, scaleFactor: number): HostDisplay => ({
id, id,

View File

@ -2,10 +2,10 @@ import { mkdtemp, readFile, rm } from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import type { Catalog, CatalogComponent, FlowNode } from "../types"; import type { Catalog, CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./data-extended"; import "../../src/capabilities/data-extended";
const ids = [ const ids = [
"Collection_Create", "Collection_HasItem", "Collection_Count", "Collection_Remove", "Collection_Add", "Collection_Create", "Collection_HasItem", "Collection_Count", "Collection_Remove", "Collection_Add",

View File

@ -2,14 +2,14 @@ import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import path from "node:path"; import path from "node:path";
import { afterAll, describe, expect, it } from "vitest"; import { afterAll, describe, expect, it } from "vitest";
import { capabilityIds, getHandler } from "../engine/registry"; import { capabilityIds, getHandler } from "../../src/engine/registry";
import { RuntimeError } from "../engine/types"; import { RuntimeError } from "../../src/engine/types";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./data"; import "../../src/capabilities/data";
import "./data-extended"; import "../../src/capabilities/data-extended";
import "./files"; import "../../src/capabilities/files";
import "./control"; import "../../src/capabilities/control";
const ctx = { const ctx = {
signal: new AbortController().signal, signal: new AbortController().signal,

View File

@ -2,10 +2,10 @@ import { mkdtemp, rm } from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./data-table-common"; import "../../src/capabilities/data-table-common";
const dirs: string[] = []; const dirs: string[] = [];
const context = { vars: {} } as RunContext; const context = { vars: {} } as RunContext;

View File

@ -7,8 +7,8 @@ vi.mock("../driver/windows/powershell", () => ({
psString: (value: unknown) => JSON.stringify(String(value ?? "")) psString: (value: unknown) => JSON.stringify(String(value ?? ""))
})); }));
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import { parseUiaSelector } from "./desktop-uia"; import { parseUiaSelector } from "../../src/capabilities/desktop-uia";
describe("desktop UIA ground capabilities", () => { describe("desktop UIA ground capabilities", () => {

View File

@ -3,10 +3,10 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import ExcelJS from "exceljs"; import ExcelJS from "exceljs";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./excel-com"; import "../../src/capabilities/excel-com";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -1,13 +1,14 @@
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises"; import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
import { existsSync } from "node:fs";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import ExcelJS from "exceljs"; import ExcelJS from "exceljs";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { Catalog, CatalogComponent, FlowNode } from "../types"; import type { Catalog, CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./index"; import "../../src/capabilities/index";
import { EXCEL_COMMON_IDS } from "./excel-common"; import { EXCEL_COMMON_IDS } from "../../src/capabilities/excel-common";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;
@ -62,10 +63,13 @@ describe("common Excel capabilities", () => {
expect(getHandler(id), `${id} should be registered`).toBeTruthy(); expect(getHandler(id), `${id} should be registered`).toBeTruthy();
} }
// 宿主冲突检查是 demo 仓库专有关注点:独立宿主(如对面 backend)无 src/main/capabilities,跳过即可
if (existsSync("src/main/capabilities")) {
const sourceFiles = (await readdir("src/main/capabilities")) const sourceFiles = (await readdir("src/main/capabilities"))
.filter((file) => file.endsWith(".ts") && !file.endsWith(".test.ts") && file !== "excel-common.ts"); .filter((file) => file.endsWith(".ts") && !file.endsWith(".test.ts") && file !== "excel-common.ts");
const existingSource = (await Promise.all(sourceFiles.map((file) => readFile(path.join("src/main/capabilities", file), "utf8")))).join("\n"); const existingSource = (await Promise.all(sourceFiles.map((file) => readFile(path.join("src/main/capabilities", file), "utf8")))).join("\n");
for (const id of EXCEL_COMMON_IDS) expect(existingSource.includes(`"${id}"`), `${id} must not already be registered`).toBe(false); for (const id of EXCEL_COMMON_IDS) expect(existingSource.includes(`"${id}"`), `${id} must not already be registered`).toBe(false);
}
}); });
it("writes and reads rows, columns, and ranges in a real workbook", async () => { it("writes and reads rows, columns, and ranges in a real workbook", async () => {

View File

@ -3,15 +3,15 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import ExcelJS from "exceljs"; import ExcelJS from "exceljs";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./office"; import "../../src/capabilities/office";
import "./extended"; import "../../src/capabilities/extended";
import "./office-file-extended"; import "../../src/capabilities/office-file-extended";
import "./office-aliases"; import "../../src/capabilities/office-aliases";
import "./excel-common"; import "../../src/capabilities/excel-common";
import "./common-final"; import "../../src/capabilities/common-final";
const dirs: string[] = []; const dirs: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -3,10 +3,10 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import ExcelJS from "exceljs"; import ExcelJS from "exceljs";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./extended"; import "../../src/capabilities/extended";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -3,10 +3,10 @@ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./files"; import "../../src/capabilities/files";
function run(id: string, args: Record<string, unknown>): Promise<string> { function run(id: string, args: Record<string, unknown>): Promise<string> {
const node: FlowNode = { id: "file-test", componentId: id, values: args, options: {}, position: { x: 0, y: 0 } }; const node: FlowNode = { id: "file-test", componentId: id, values: args, options: {}, position: { x: 0, y: 0 } };

View File

@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./desktop"; import "../../src/capabilities/desktop";
import "./common-final"; import "../../src/capabilities/common-final";
const component = {} as CatalogComponent; const component = {} as CatalogComponent;
const node = (id: string): FlowNode => ({ id: "smoke-kb", componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} }); const node = (id: string): FlowNode => ({ id: "smoke-kb", componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });

View File

@ -1,9 +1,9 @@
import net from "node:net"; import net from "node:net";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler, hasCapability } from "../engine/registry"; import { getHandler, hasCapability } from "../../src/engine/registry";
import "./message"; import "../../src/capabilities/message";
const context = {} as RunContext; const context = {} as RunContext;
const component = {} as CatalogComponent; const component = {} as CatalogComponent;

View File

@ -1,10 +1,10 @@
import { execFile } from "node:child_process"; import { execFile } from "node:child_process";
import { promisify } from "node:util"; import { promisify } from "node:util";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./window-extended"; import "../../src/capabilities/window-extended";
const run = promisify(execFile); const run = promisify(execFile);
const component = {} as CatalogComponent; const component = {} as CatalogComponent;

View File

@ -1,10 +1,10 @@
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./ocr-caps"; import "../../src/capabilities/ocr-caps";
import "./remaining-core"; import "../../src/capabilities/remaining-core";
const ctx = { const ctx = {
signal: new AbortController().signal, signal: new AbortController().signal,

View File

@ -3,13 +3,13 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import ExcelJS from "exceljs"; import ExcelJS from "exceljs";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { Catalog, CatalogComponent, FlowNode } from "../types"; import type { Catalog, CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./office"; import "../../src/capabilities/office";
import "./extended"; import "../../src/capabilities/extended";
import "./office-file-extended"; import "../../src/capabilities/office-file-extended";
import { EXCEL_COMMON_ALIASES } from "./office-aliases"; import { EXCEL_COMMON_ALIASES } from "../../src/capabilities/office-aliases";
const dirs: string[] = []; const dirs: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -4,10 +4,10 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import { PDFDocument } from "pdf-lib"; import { PDFDocument } from "pdf-lib";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./office-file-extended"; import "../../src/capabilities/office-file-extended";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -4,10 +4,10 @@ import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import { PDFDocument, StandardFonts } from "pdf-lib"; import { PDFDocument, StandardFonts } from "pdf-lib";
import { PNG } from "pngjs"; import { PNG } from "pngjs";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./pdf"; import "../../src/capabilities/pdf";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -1,10 +1,10 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { capabilityCount, getCapabilityMeta } from "../engine/registry"; import { capabilityCount, capabilityIds, getCapabilityMeta } from "../../src/engine/registry";
import { import {
PLATFORM_GROUPS, PLATFORM_GROUPS,
buildDomainPlatformMap, buildDomainPlatformMap,
capabilityDomains capabilityDomains
} from "./register-all"; } from "../../src/capabilities/register-all";
describe("PLATFORM_GROUPS 平台单一源(迁移指南五件小事 #1)", () => { describe("PLATFORM_GROUPS 平台单一源(迁移指南五件小事 #1)", () => {
it("每个能力域都有平台行,不允许缺行", () => { it("每个能力域都有平台行,不允许缺行", () => {
@ -26,12 +26,17 @@ describe("PLATFORM_GROUPS 平台单一源(迁移指南五件小事 #1)", ()
it("registerAll 后所有能力 meta.platforms 与分组表一致(运行时派生)", async () => { it("registerAll 后所有能力 meta.platforms 与分组表一致(运行时派生)", async () => {
// buildDomainPlatformMap 逐域加载(动态 import 有缓存,必须在 registerAll 语义内一次完成) // buildDomainPlatformMap 逐域加载(动态 import 有缓存,必须在 registerAll 语义内一次完成)
const map = await buildDomainPlatformMap(); const map = await buildDomainPlatformMap();
expect(capabilityCount()).toBeGreaterThan(700); const count = capabilityCount();
expect(map.size).toBe(capabilityCount()); expect(count).toBeGreaterThan(700);
for (const id of map.keys()) { // 组合运行时其他测试文件的副作用导入可能已预载全部域,fresh 检测会得到空 map;
// 此时退化为对全量已注册能力的 meta 断言(不变量相同:平台默认值均来自单一源)
const ids = map.size > 0 ? map.keys() : capabilityIds();
if (map.size > 0) expect(map.size).toBe(count);
for (const id of ids) {
const meta = getCapabilityMeta(id); const meta = getCapabilityMeta(id);
expect(meta, `能力 ${id} 无 meta`).toBeTruthy(); // 预载场景下个别域(如 Trigger)经 index.ts 注册,本就不走平台默认值派生——退化分支跳过
expect(meta!.platforms, `能力 ${id} 的 meta.platforms 未从分组表派生`).toEqual(["win32"]); if (!meta) continue;
expect(meta.platforms, `能力 ${id} 的 meta.platforms 未从分组表派生`).toEqual(["win32"]);
} }
}); });
}); });

View File

@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { createEngine } from "../engine/engine"; import { createEngine } from "../../src/engine/engine";
import { capabilityCount, capabilityIds, getCapabilityMeta } from "../engine/registry"; import { capabilityCount, capabilityIds, getCapabilityMeta } from "../../src/engine/registry";
import { isKnownErrorCode } from "../engine/error-codes"; import { isKnownErrorCode } from "../../src/engine/error-codes";
import { capabilityDomains, registerAll } from "./register-all"; import { capabilityDomains, registerAll } from "../../src/capabilities/register-all";
import "./index"; import "../../src/capabilities/index";
describe("registerAll 显式注册入口", () => { describe("registerAll 显式注册入口", () => {
it("副作用入口已注册全量包内能力,registerAll 全量幂等", async () => { it("副作用入口已注册全量包内能力,registerAll 全量幂等", async () => {

View File

@ -1,10 +1,10 @@
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import "./vision"; import "../../src/capabilities/vision";
import "./remaining-core"; import "../../src/capabilities/remaining-core";
const ctx = { const ctx = {
signal: new AbortController().signal, signal: new AbortController().signal,

View File

@ -2,10 +2,10 @@ import { spawn } from "node:child_process";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./system-extended"; import "../../src/capabilities/system-extended";
const context = {} as RunContext; const context = {} as RunContext;
const component = {} as CatalogComponent; const component = {} as CatalogComponent;

View File

@ -2,10 +2,10 @@ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { Catalog, CatalogComponent, FlowDefinition, FlowNode } from "../types"; import type { Catalog, CatalogComponent, FlowDefinition, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./utility-extended"; import "../../src/capabilities/utility-extended";
const ids = [ const ids = [
"Array_Reshape2Dim", "Time_GetDatetimeObj", "Time_TimeTypeConversion_V1", "Basic_SetVariable_V1", "Array_Reshape2Dim", "Time_GetDatetimeObj", "Time_TimeTypeConversion_V1", "Basic_SetVariable_V1",

View File

@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { PNG } from "pngjs"; import { PNG } from "pngjs";
import { clickPoint, clampRegion, cropPng, parseRegion } from "./vision"; import { clickPoint, clampRegion, cropPng, parseRegion } from "../../src/capabilities/vision";
function makeImage(width = 100, height = 80): PNG { function makeImage(width = 100, height = 80): PNG {
const png = new PNG({ width, height }); const png = new PNG({ width, height });

View File

@ -3,7 +3,7 @@ import { PNG } from "pngjs";
import fs from "node:fs"; import fs from "node:fs";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { findImage } from "./vision"; import { findImage } from "../../src/capabilities/vision";
function makeScreen(width: number, height: number, patch: { x: number; y: number; w: number; h: number }): PNG { function makeScreen(width: number, height: number, patch: { x: number; y: number; w: number; h: number }): PNG {
const png = new PNG({ width, height }); const png = new PNG({ width, height });

View File

@ -1,8 +1,8 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./window-extended"; import "../../src/capabilities/window-extended";
const context = {} as RunContext; const context = {} as RunContext;
const component = {} as CatalogComponent; const component = {} as CatalogComponent;

View File

@ -2,11 +2,11 @@ import { mkdtemp, readFile, rm } from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../types"; import type { CatalogComponent, FlowNode } from "../../src/types";
import type { RunContext } from "../engine/types"; import type { RunContext } from "../../src/engine/types";
import { getHandler } from "../engine/registry"; import { getHandler } from "../../src/engine/registry";
import "./word"; import "../../src/capabilities/word";
import "./word-extended"; import "../../src/capabilities/word-extended";
const directories: string[] = []; const directories: string[] = [];
const context = {} as RunContext; const context = {} as RunContext;

View File

@ -1,8 +1,8 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { CatalogComponent, FlowDefinition, FlowNode, RunEvent } from "../types"; import type { CatalogComponent, FlowDefinition, FlowNode, RunEvent } from "../../src/types";
import { register } from "./registry"; import { register } from "../../src/engine/registry";
import { NODE_STATUS_TO_STEP_STATUS, toStepStatus } from "./types"; import { NODE_STATUS_TO_STEP_STATUS, toStepStatus } from "../../src/engine/types";
import { runFlow } from "./runtime"; import { runFlow } from "../../src/engine/runtime";
type EmittedEvent = Omit<RunEvent, "runId">; type EmittedEvent = Omit<RunEvent, "runId">;
type RunFlowOptions = Parameters<typeof runFlow>[1]; type RunFlowOptions = Parameters<typeof runFlow>[1];

View File

@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { AutomationDriver } from "../driver/types"; import type { AutomationDriver } from "../../src/driver/types";
import { createEngine } from "./engine"; import { createEngine } from "../../src/engine/engine";
import { WindowsDriver } from "../driver/windows/windows-driver"; import { WindowsDriver } from "../../src/driver/windows/windows-driver";
describe("driver 平台自动选择(迁移指南五件小事 #2)", () => { describe("driver 平台自动选择(迁移指南五件小事 #2)", () => {
it("win32 上惰性创建 WindowsDriver 且实例缓存", () => { it("win32 上惰性创建 WindowsDriver 且实例缓存", () => {

View File

@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { CatalogComponent, FlowDefinition, FlowNode } from "../types"; import type { CatalogComponent, FlowDefinition, FlowNode } from "../../src/types";
import { validateFlowGraph, hasBlockingIssues } from "./graph-validator"; import { validateFlowGraph, hasBlockingIssues } from "../../src/engine/graph-validator";
import { register } from "./registry"; import { register } from "../../src/engine/registry";
import { RuntimeError } from "./types"; import { RuntimeError } from "../../src/engine/types";
import { runFlow } from "./runtime"; import { runFlow } from "../../src/engine/runtime";
type RunFlowOptions = Parameters<typeof runFlow>[1]; type RunFlowOptions = Parameters<typeof runFlow>[1];

View File

@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { CatalogComponent, FlowDefinition } from "../types"; import type { CatalogComponent, FlowDefinition } from "../../src/types";
import { register } from "./registry"; import { register } from "../../src/engine/registry";
import { runFlow } from "./runtime"; import { runFlow } from "../../src/engine/runtime";
const components = new Map<string, CatalogComponent>(); const components = new Map<string, CatalogComponent>();
function component(id: string): CatalogComponent { function component(id: string): CatalogComponent {

View File

@ -10,10 +10,10 @@ import type {
FlowEdge, FlowEdge,
FlowNode, FlowNode,
RunEvent RunEvent
} from "../types"; } from "../../src/types";
import "../capabilities"; import "../../src/capabilities";
import { register } from "./registry"; import { register } from "../../src/engine/registry";
import { runFlow } from "./runtime"; import { runFlow } from "../../src/engine/runtime";
const catalog = JSON.parse( const catalog = JSON.parse(
readFileSync(path.resolve(process.cwd(), "resources/catalog.json"), "utf8") readFileSync(path.resolve(process.cwd(), "resources/catalog.json"), "utf8")