improve: speed up plugin npm package tests (#121989)

* test(packaging): collapse duplicate plugin installs

* test(packaging): combine bundled dependency proof

* test(packaging): name packed artifact proof

---------

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-11 03:35:33 -07:00
committed by GitHub
parent 79016b415a
commit 33ce7313d7
+186 -201
View File
@@ -388,8 +388,25 @@ describe("plugin npm package manifest staging", () => {
it("overlays package-local runtime metadata while packing and restores source package json", () => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-runtime-");
const packageDir = writePublishablePluginPackage(repoDir);
const sourcePackageJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
sourcePackageJson.openclaw.channel = {
id: "diffs",
configuredState: {
specifier: "./configured-state",
exportName: "hasConfiguredChannelState",
},
};
writeJsonFile(join(packageDir, "package.json"), sourcePackageJson);
writeFileText(
join(packageDir, "configured-state.ts"),
"export function hasConfiguredChannelState() {}\n",
);
writeFileText(join(packageDir, "dist", "index.js"), "export {};\n");
writeFileText(join(packageDir, "dist", "setup-entry.js"), "export {};\n");
writeFileText(
join(packageDir, "dist", "configured-state.js"),
"export function hasConfiguredChannelState() { return true; }\n",
);
const resolved = resolveAugmentedPluginNpmPackageJson({
repoRoot: repoDir,
@@ -414,6 +431,13 @@ describe("plugin npm package manifest staging", () => {
openclaw: {
extensions: ["./index.ts"],
setupEntry: "./dist/setup-entry.js",
channel: {
id: "diffs",
configuredState: {
specifier: "./dist/configured-state.js",
exportName: "hasConfiguredChannelState",
},
},
compat: {
pluginApi: ">=2026.4.30",
},
@@ -436,6 +460,9 @@ describe("plugin npm package manifest staging", () => {
expect(stagedPackageJson.openclaw.runtimeExtensions).toEqual(["./dist/index.js"]);
expect(stagedPackageJson.openclaw.setupEntry).toBe("./dist/setup-entry.js");
expect(stagedPackageJson.openclaw.runtimeSetupEntry).toBe("./dist/setup-entry.js");
expect(stagedPackageJson.openclaw.channel.configuredState.specifier).toBe(
"./dist/configured-state.js",
);
expect(stagedPackageJson.bundledDependencies).toEqual([]);
expect(stagedPackageJson.bundleDependencies).toBeUndefined();
expect(stagedPackageJson.files).toContain("dist/**");
@@ -448,159 +475,135 @@ describe("plugin npm package manifest staging", () => {
expect(readFileSync(join(packageDir, "package.json"), "utf8")).toBe(originalText);
});
it.each(
[
{
label: "ESM configured-state",
metadataKey: "configuredState",
runtimeFormat: "esm",
sourceName: "configured-state",
it("packs and loads both mapped channel-state probes from one package artifact", () => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-state-runtime-");
const packageDir = writePublishablePluginPackage(repoDir);
const sourcePackageJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
sourcePackageJson.openclaw.build = { runtimeFormat: "cjs" };
sourcePackageJson.openclaw.channel = {
id: "diffs",
configuredState: {
specifier: "./configured-state",
exportName: "hasConfiguredChannelState",
},
{
label: "CommonJS configured-state",
metadataKey: "configuredState",
runtimeFormat: "cjs",
sourceName: "configured-state",
persistedAuthState: {
specifier: "./dist/auth-presence.cjs",
exportName: "hasPersistedChannelAuth",
},
};
writeJsonFile(join(packageDir, "package.json"), sourcePackageJson);
writeFileText(
join(packageDir, "configured-state.ts"),
"export function hasConfiguredChannelState() {}\n",
);
writeFileText(
join(packageDir, "auth-presence.ts"),
"export function hasPersistedChannelAuth() {}\n",
);
writeFileText(join(packageDir, "dist", "index.cjs"), "module.exports = {};\n");
writeFileText(join(packageDir, "dist", "setup-entry.cjs"), "module.exports = {};\n");
writeFileText(
join(packageDir, "dist", "configured-state.cjs"),
"exports.hasConfiguredChannelState = () => true;\n",
);
writeFileText(
join(packageDir, "dist", "auth-presence.cjs"),
"exports.hasPersistedChannelAuth = () => true;\n",
);
const originalText = readFileSync(join(packageDir, "package.json"), "utf8");
withAugmentedPluginNpmManifestForPackage({ repoRoot: repoDir, packageDir }, () => {
const stagedPackageJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
expect(stagedPackageJson.openclaw.channel.configuredState).toEqual({
specifier: "./dist/configured-state.cjs",
exportName: "hasConfiguredChannelState",
},
{
label: "ESM persisted-auth state",
metadataKey: "persistedAuthState",
runtimeFormat: "esm",
sourceName: "auth-presence",
exportName: "hasPersistedChannelAuth",
},
{
label: "CommonJS persisted-auth state",
metadataKey: "persistedAuthState",
runtimeFormat: "cjs",
sourceName: "auth-presence",
exportName: "hasPersistedChannelAuth",
},
].flatMap((testCase) => [
{ ...testCase, label: `${testCase.label} from source`, specifierKind: "source" },
{ ...testCase, label: `${testCase.label} from built runtime`, specifierKind: "runtime" },
]),
)(
"packs and loads $label from the actual installed plugin runtime",
({ metadataKey, runtimeFormat, sourceName, exportName, specifierKind }) => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-state-runtime-");
const packageDir = writePublishablePluginPackage(repoDir);
const extension = runtimeFormat === "cjs" ? ".cjs" : ".js";
const sourceSpecifier = `./${sourceName}`;
const runtimeSpecifier = `./dist/${sourceName}${extension}`;
const sourcePackageJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
sourcePackageJson.openclaw.channel = {
id: "diffs",
[metadataKey]: {
specifier: specifierKind === "runtime" ? runtimeSpecifier : sourceSpecifier,
exportName,
},
};
if (runtimeFormat === "cjs") {
sourcePackageJson.openclaw.build = { runtimeFormat: "cjs" };
}
writeJsonFile(join(packageDir, "package.json"), sourcePackageJson);
writeFileText(join(packageDir, `${sourceName}.ts`), `export function ${exportName}() {}\n`);
writeFileText(join(packageDir, "dist", `index${extension}`), "export {};\n");
writeFileText(join(packageDir, "dist", `setup-entry${extension}`), "export {};\n");
writeFileText(
join(packageDir, "dist", `${sourceName}${extension}`),
runtimeFormat === "cjs"
? `exports.${exportName} = () => true;\n`
: `export function ${exportName}() { return true; }\n`,
);
const originalText = readFileSync(join(packageDir, "package.json"), "utf8");
withAugmentedPluginNpmManifestForPackage({ repoRoot: repoDir, packageDir }, () => {
const stagedPackageJson = JSON.parse(
readFileSync(join(packageDir, "package.json"), "utf8"),
);
expect(stagedPackageJson.openclaw.channel[metadataKey]).toEqual({
specifier: runtimeSpecifier,
exportName,
});
const packedFiles = listNpmPackDryRunFiles(packageDir);
expect(packedFiles).toContain(runtimeSpecifier.slice(2));
expect(packedFiles).not.toContain(`${sourceName}.ts`);
const consumerDir = join(repoDir, "external-consumer");
mkdirSync(consumerDir, { recursive: true });
writeJsonFile(join(consumerDir, "package.json"), { private: true, type: "module" });
const packInvocation = resolvePluginNpmCommand([
"pack",
"--json",
"--ignore-scripts",
"--pack-destination",
consumerDir,
]);
const pack = spawnSync(packInvocation.command, packInvocation.args, {
cwd: packageDir,
encoding: "utf8",
...(packInvocation.env ? { env: packInvocation.env } : {}),
...(packInvocation.shell !== undefined ? { shell: packInvocation.shell } : {}),
stdio: ["ignore", "pipe", "pipe"],
...(packInvocation.windowsVerbatimArguments !== undefined
? { windowsVerbatimArguments: packInvocation.windowsVerbatimArguments }
: {}),
});
expect(pack.status, pack.stderr).toBe(0);
const [packedPackage] = JSON.parse(pack.stdout) as [{ filename: string }];
const installInvocation = resolvePluginNpmCommand([
"install",
"--ignore-scripts",
"--omit=peer",
"--no-audit",
"--no-fund",
"--package-lock=false",
join(consumerDir, packedPackage.filename),
]);
const install = spawnSync(installInvocation.command, installInvocation.args, {
cwd: consumerDir,
encoding: "utf8",
...(installInvocation.env ? { env: installInvocation.env } : {}),
...(installInvocation.shell !== undefined ? { shell: installInvocation.shell } : {}),
stdio: ["ignore", "pipe", "pipe"],
...(installInvocation.windowsVerbatimArguments !== undefined
? { windowsVerbatimArguments: installInvocation.windowsVerbatimArguments }
: {}),
});
expect(install.status, install.stderr).toBe(0);
const installedRoot = join(consumerDir, "node_modules", "@openclaw", "diffs");
const load = spawnSync(
process.execPath,
[
"--input-type=module",
"--eval",
`import fs from "node:fs";\n` +
`import { pathToFileURL } from "node:url";\n` +
`const root = ${JSON.stringify(installedRoot)};\n` +
`const pkg = JSON.parse(fs.readFileSync(root + "/package.json", "utf8"));\n` +
`const state = pkg.openclaw.channel[${JSON.stringify(metadataKey)}];\n` +
`const loaded = await import(new URL(state.specifier, pathToFileURL(root + "/")));\n` +
`if (loaded[state.exportName]?.() !== true) throw new Error("installed state checker failed");\n` +
`process.stdout.write("INSTALLED_PLUGIN_CHANNEL_STATE_OK\\n");\n`,
],
{ cwd: consumerDir, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] },
);
expect(load.status, load.stderr).toBe(0);
expect(load.stdout).toBe("INSTALLED_PLUGIN_CHANNEL_STATE_OK\n");
});
expect(readFileSync(join(packageDir, "package.json"), "utf8")).toBe(originalText);
},
);
expect(stagedPackageJson.openclaw.channel.persistedAuthState).toEqual({
specifier: "./dist/auth-presence.cjs",
exportName: "hasPersistedChannelAuth",
});
it("installs and cleans package-local bundled dependencies while packing", () => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-bundled-deps-");
const consumerDir = join(repoDir, "external-consumer");
mkdirSync(consumerDir, { recursive: true });
writeJsonFile(join(consumerDir, "package.json"), { private: true, type: "module" });
const packInvocation = resolvePluginNpmCommand([
"pack",
"--json",
"--ignore-scripts",
"--pack-destination",
consumerDir,
]);
const pack = spawnSync(packInvocation.command, packInvocation.args, {
cwd: packageDir,
encoding: "utf8",
...(packInvocation.env ? { env: packInvocation.env } : {}),
...(packInvocation.shell !== undefined ? { shell: packInvocation.shell } : {}),
stdio: ["ignore", "pipe", "pipe"],
...(packInvocation.windowsVerbatimArguments !== undefined
? { windowsVerbatimArguments: packInvocation.windowsVerbatimArguments }
: {}),
});
expect(pack.status, pack.stderr).toBe(0);
const [packedPackage] = JSON.parse(pack.stdout) as [
{ filename: string; files: Array<{ path: string }> },
];
const packedFiles = packedPackage.files.map((file) => file.path);
expect(packedFiles).toContain("dist/configured-state.cjs");
expect(packedFiles).toContain("dist/auth-presence.cjs");
expect(packedFiles).not.toContain("configured-state.ts");
expect(packedFiles).not.toContain("auth-presence.ts");
const extract = spawnSync(
"tar",
["-xzf", join(consumerDir, packedPackage.filename), "-C", consumerDir],
{
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
},
);
expect(extract.status, extract.stderr).toBe(0);
const packageRoot = join(consumerDir, "package");
const load = spawnSync(
process.execPath,
[
"--input-type=module",
"--eval",
`
import fs from "node:fs";
import { pathToFileURL } from "node:url";
const root = ${JSON.stringify(packageRoot)};
const pkg = JSON.parse(fs.readFileSync(root + "/package.json", "utf8"));
for (const key of ["configuredState", "persistedAuthState"]) {
const state = pkg.openclaw.channel[key];
const loaded = await import(new URL(state.specifier, pathToFileURL(root + "/")));
if (loaded[state.exportName]?.() !== true) throw new Error("packed state checker failed: " + key);
}
process.stdout.write("PACKED_PLUGIN_CHANNEL_STATE_OK\\n");
`,
],
{
cwd: packageRoot,
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
},
);
expect(load.status, load.stderr).toBe(0);
expect(load.stdout).toBe("PACKED_PLUGIN_CHANNEL_STATE_OK\n");
});
expect(readFileSync(join(packageDir, "package.json"), "utf8")).toBe(originalText);
});
it("stages portable bundled dependencies without polluting pack output", () => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-portable-optional-");
const packageDir = writePublishablePluginPackage(repoDir);
writeFileText(join(packageDir, "dist", "index.js"), "export {};\n");
writeFileText(join(packageDir, "dist", "setup-entry.js"), "export {};\n");
writeLocalDependencyPackage(packageDir);
writeOptionalPlatformDependencyPackage(packageDir);
writeLocalDependencyPackage(packageDir, {
optionalDependencySpec: "file:../../deps/optional-platform-dep",
});
writeJsonFile(join(packageDir, "package.json"), {
name: "@openclaw/diffs",
version: "2026.5.3",
@@ -624,69 +627,19 @@ describe("plugin npm package manifest staging", () => {
});
const originalText = readFileSync(join(packageDir, "package.json"), "utf8");
const nodeModulesPath = join(packageDir, "node_modules");
expect(existsSync(nodeModulesPath)).toBe(false);
withAugmentedPluginNpmManifestForPackage(
{ repoRoot: repoDir, packageDir, bundleDependencies: true },
() => {
const stagedPackageJson = JSON.parse(
readFileSync(join(packageDir, "package.json"), "utf8"),
);
expect(stagedPackageJson.bundledDependencies).toEqual(["local-runtime-dep"]);
expect(stagedPackageJson.bundleDependencies).toBeUndefined();
expect(stagedPackageJson.devDependencies).toBeUndefined();
expect(existsSync(join(nodeModulesPath, "local-runtime-dep", "package.json"))).toBe(true);
expect(existsSync(join(packageDir, "package-lock.json"))).toBe(false);
const packedFiles = listNpmPackDryRunFiles(packageDir);
expect(packedFiles).toContain("node_modules/local-runtime-dep/package.json");
expect(packedFiles).not.toContain("package-lock.json");
expect(packedFiles).not.toContain("npm-shrinkwrap.json");
},
);
expect(existsSync(nodeModulesPath)).toBe(false);
expect(existsSync(join(packageDir, "package-lock.json"))).toBe(false);
expect(readFileSync(join(packageDir, "package.json"), "utf8")).toBe(originalText);
});
it("force-installs missing optional bundled dependencies for portable packs", () => {
const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-npm-package-portable-optional-");
const packageDir = writePublishablePluginPackage(repoDir);
writeFileText(join(packageDir, "dist", "index.js"), "export {};\n");
writeFileText(join(packageDir, "dist", "setup-entry.js"), "export {};\n");
writeOptionalPlatformDependencyPackage(packageDir);
writeLocalDependencyPackage(packageDir, {
optionalDependencySpec: "file:../../deps/optional-platform-dep",
});
writeJsonFile(join(packageDir, "package.json"), {
name: "@openclaw/diffs",
version: "2026.5.3",
type: "module",
dependencies: {
"local-runtime-dep": "file:./deps/local-runtime-dep",
},
openclaw: {
extensions: ["./index.ts"],
setupEntry: "./setup-entry.ts",
compat: {
pluginApi: ">=2026.4.30",
},
release: {
publishToNpm: true,
},
},
});
const nodeModulesPath = join(packageDir, "node_modules");
const manifestModuleUrl = new URL(
"../scripts/lib/plugin-npm-package-manifest.mts",
import.meta.url,
).href;
const childSource = `
import { existsSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { withAugmentedPluginNpmManifestForPackage } from ${JSON.stringify(manifestModuleUrl)};
import {
resolvePluginNpmCommand,
withAugmentedPluginNpmManifestForPackage,
} from ${JSON.stringify(manifestModuleUrl)};
const packageDir = ${JSON.stringify(packageDir)};
const nodeModulesPath = ${JSON.stringify(nodeModulesPath)};
@@ -697,12 +650,42 @@ withAugmentedPluginNpmManifestForPackage(
bundleDependencies: true,
},
() => {
const stagedPackageJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
if (JSON.stringify(stagedPackageJson.bundledDependencies) !== '["local-runtime-dep"]') {
throw new Error("bundled dependencies were not staged");
}
if (stagedPackageJson.bundleDependencies || stagedPackageJson.devDependencies) {
throw new Error("unpublishable dependency metadata remained staged");
}
if (!existsSync(join(nodeModulesPath, "local-runtime-dep", "package.json"))) {
throw new Error("missing bundled runtime dependency");
}
if (!existsSync(join(nodeModulesPath, "optional-platform-dep", "package.json"))) {
throw new Error("missing portable optional bundled dependency");
}
if (existsSync(join(packageDir, "package-lock.json"))) {
throw new Error("package lock remained staged");
}
const invocation = resolvePluginNpmCommand(["pack", "--dry-run", "--json", "--ignore-scripts"]);
const pack = spawnSync(invocation.command, invocation.args, {
cwd: packageDir,
encoding: "utf8",
...(invocation.env ? { env: invocation.env } : {}),
...(invocation.shell !== undefined ? { shell: invocation.shell } : {}),
stdio: ["ignore", "pipe", "pipe"],
...(invocation.windowsVerbatimArguments !== undefined
? { windowsVerbatimArguments: invocation.windowsVerbatimArguments }
: {}),
});
if (pack.status !== 0) throw new Error(pack.stderr || "npm pack failed");
const [packedPackage] = JSON.parse(pack.stdout);
const packedFiles = packedPackage.files.map((file) => file.path);
if (!packedFiles.includes("node_modules/local-runtime-dep/package.json")) {
throw new Error("bundled runtime dependency was not packed");
}
if (packedFiles.includes("package-lock.json") || packedFiles.includes("npm-shrinkwrap.json")) {
throw new Error("package lock was packed");
}
process.stdout.write("pack-json\\n");
},
);
@@ -721,6 +704,8 @@ withAugmentedPluginNpmManifestForPackage(
expect(result.stdout).toBe("pack-json\n");
expect(existsSync(nodeModulesPath)).toBe(false);
expect(existsSync(join(packageDir, "package-lock.json"))).toBe(false);
expect(readFileSync(join(packageDir, "package.json"), "utf8")).toBe(originalText);
});
it("honors plugin package opt-out for bundled runtime dependencies", () => {