blob: b24c54b256a8f8c4a990f6f200a3a82bc34aa259 [file]
import assert from 'node:assert/strict';
import test from 'node:test';
import { formatGitHubOutputs, loadWorkspaceGraph, planTests } from './ci-test-plan.mjs';
const graph = loadWorkspaceGraph();
test('impact planning distinguishes docs, UI, and backend changes', () => {
const docs = planTests(['README.md', 'docs/testing.md'], { graph });
assert.equal(docs.code, false);
assert.deepEqual(docs.workspaces, []);
const ui = planTests(['packages/ui/src/button.tsx'], { graph });
assert.equal(ui.e2e, true);
// Product UI work is not a Storybook catalog change — typecheck/unit/e2e own it.
assert.equal(ui.storybook, false);
assert.equal(ui.scriptMode, 'none');
assert.deepEqual(ui.workspaces, ['packages/ui', 'apps/desktop']);
// Ordinary desktop product files must not drag Storybook Chromium.
assert.equal(planTests(['apps/desktop/src/main/main.ts'], { graph }).storybook, false);
assert.equal(planTests(['apps/desktop/e2e/settings.spec.ts'], { graph }).storybook, false);
// Catalog + harness only.
assert.equal(
planTests(['apps/desktop/stories/app-shell.stories.tsx'], { graph }).storybook,
true,
);
assert.equal(planTests(['apps/desktop/.storybook/preview.tsx'], { graph }).storybook, true);
assert.equal(planTests(['packages/ui/stories/composer.stories.tsx'], { graph }).storybook, true);
// .storybook/preview.tsx reads THEME_PALETTES from this one core module.
// Other core paths must not force Storybook.
const coreSettings = planTests(['packages/core/src/settings.ts'], { graph });
assert.equal(coreSettings.storybook, true);
assert.equal(coreSettings.e2e, false);
assert.equal(planTests(['packages/core/src/index.ts'], { graph }).storybook, false);
// A script the Storybook job RUNS must re-run Storybook, not Electron e2e.
const smoke = planTests(['scripts/storybook-visual-smoke.mjs'], { graph });
assert.equal(smoke.storybook, true);
assert.equal(smoke.e2e, false);
assert.equal(smoke.scriptMode, 'fast');
assert.equal(planTests(['scripts/check-story-annotations.mjs'], { graph }).e2e, false);
assert.equal(planTests(['scripts/check-story-annotations.mjs'], { graph }).storybook, false);
// Alignment auditor drives the e2e job (not Storybook).
const alignment = planTests(['scripts/audit-alignment.mjs'], { graph });
assert.equal(alignment.e2e, true);
assert.equal(alignment.storybook, false);
const backend = planTests(['packages/storage/src/session-store.ts'], { graph });
assert.equal(backend.e2e, false);
assert.equal(backend.storybook, false);
for (const workspace of ['packages/storage', 'packages/runtime', 'apps/desktop']) {
assert.ok(backend.workspaces.includes(workspace));
}
});
test('stress and specialized script checks run only for their owning surfaces', () => {
for (const path of [
'packages/storage/src/agent-run-store.ts',
'packages/storage/src/git-workspace-service.ts',
'packages/storage/src/__tests__/fixtures/git-workspace-service-crash-child.ts',
'packages/storage/src/root-authority.ts',
'packages/storage/src/__tests__/root-authority.test.ts',
'packages/storage/src/__tests__/fixtures/root-lock-holder.ts',
]) {
assert.equal(planTests([path], { graph }).storageStress, true, path);
}
assert.equal(
planTests(['packages/storage/src/session-store.ts'], { graph }).storageStress,
false,
);
assert.equal(planTests([], { graph, forceFull: true }).storageStress, false);
for (const path of [
'scripts/fixture-env.mjs',
'scripts/ci-test-plan.test.mjs',
'scripts/run-workspace-tests-parallel.test.mjs',
]) {
const plan = planTests([path], { graph });
assert.equal(plan.full, false, path);
assert.equal(plan.scriptMode, 'fast', path);
}
const measurement = planTests(['scripts/measure-session-bundle.mjs'], { graph });
assert.equal(measurement.scriptMode, 'extended');
assert.deepEqual(measurement.workspaces, []);
});
test('release tooling and the release config select the checks that cover them', () => {
const graph = loadWorkspaceGraph();
// These run only on release day, so CI has to select their tests from the
// change itself; verify-packaged-app.mjs is shared, and a change there reaches
// the macOS release path without touching anything macOS-specific.
for (const path of [
'scripts/npm-spawn.mjs',
'scripts/package-windows-x64.mjs',
'scripts/verify-windows-x64.mjs',
'scripts/windows-x64-release.test.mjs',
'scripts/verify-packaged-app.mjs',
'scripts/verify-macos-arm64-dmg.mjs',
]) {
assert.equal(planTests([path], { graph }).scriptMode, 'extended', path);
}
// electron-builder rejects an unknown option outright, and only
// scripts/electron-builder-config.test.mjs would notice before release day.
const releaseConfig = planTests(['apps/desktop/electron-builder.config.mjs'], { graph });
assert.equal(releaseConfig.scriptMode, 'fast');
assert.ok(releaseConfig.workspaces.includes('apps/desktop'));
});
test('sandbox is flagged whenever the cli workspace runs in the closure', () => {
// packages/cli/src/__tests__/runtime-bootstrap.test.ts executes real sandboxed
// shell tools, so any change whose dependency closure selects packages/cli must
// provision the sandbox — not only direct cli/runtime edits.
for (const path of [
'packages/cli/src/__tests__/runtime-bootstrap.test.ts',
'packages/runtime/src/shell-tools.ts',
'packages/storage/src/session-store.ts',
'packages/headless/src/cell-output.ts',
]) {
assert.equal(planTests([path], { graph }).runtimeSandbox, true, path);
}
});
test('heavy workspaces are projected onto dedicated CI lanes', () => {
const runtimeHost = planTests(['packages/runtime-host/src/server/index.ts'], { graph });
assert.equal(runtimeHost.runtimeHost, true);
assert.equal(runtimeHost.headless, false);
assert.deepEqual(runtimeHost.standardWorkspaces, ['packages/cli', 'apps/desktop']);
const runtime = planTests(['packages/runtime/src/index.ts'], { graph });
assert.equal(runtime.runtimeHost, true);
assert.equal(runtime.headless, true);
assert.deepEqual(runtime.standardWorkspaces, [
'packages/runtime',
'packages/computer-use',
'packages/cli',
'apps/desktop',
]);
const full = planTests([], { graph, forceFull: true });
assert.equal(full.runtimeHost, true);
assert.equal(full.headless, true);
assert.deepEqual(
full.standardWorkspaces,
graph.dirs.filter((dir) => dir !== 'packages/runtime-host' && dir !== 'packages/headless'),
);
const outputs = formatGitHubOutputs(runtimeHost).split('\n');
assert.ok(outputs.includes('runtime_host=true'));
assert.ok(outputs.includes('headless=false'));
assert.ok(outputs.includes('standard_workspaces=packages/cli,apps/desktop'));
});
test('global and unknown production changes fail safe to the complete suite', () => {
for (const path of ['package-lock.json', 'scripts/ci-test-plan.mjs', 'new-root/file.ts']) {
const plan = planTests([path], { graph });
assert.equal(plan.full, true);
assert.equal(plan.e2e, true);
assert.equal(plan.storybook, true);
assert.equal(plan.storageStress, false);
assert.deepEqual(plan.workspaces, graph.dirs);
}
});