From 2b346002db42e58598265feae6f4aa35ce5e99cf Mon Sep 17 00:00:00 2001 From: Charlie Kolb Date: Tue, 15 Sep 2026 10:08:06 +0000 Subject: [PATCH] test(editor): Stub the lazy credentials button in NodeView test and report signal-killed vitest runs (no-changelog) (#38695) Co-authored-by: Claude Fable 5.1 --- .../editor-ui/src/app/views/NodeView.test.ts | 3 +++ .../src/core/test-scoped-runner.test.ts | 27 +++++++++++++++++-- .../janitor/src/core/test-scoped-runner.ts | 22 ++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/packages/frontend/editor-ui/src/app/views/NodeView.test.ts b/packages/frontend/editor-ui/src/app/views/NodeView.test.ts index eea27519a1c..56045487df4 100644 --- a/packages/frontend/editor-ui/src/app/views/NodeView.test.ts +++ b/packages/frontend/editor-ui/src/app/views/NodeView.test.ts @@ -100,6 +100,9 @@ describe('NodeView', () => { // test here needs it, and on a writable canvas the import can still be in // flight when the environment tears down, which fails the whole run. LazyNodeCreation: true, + // Same for the setup-credentials button: its import chain pulls in the + // ready-to-run stores and their bundled workflow fixtures. + LazySetupWorkflowCredentialsButton: true, WorkflowCanvas: defineComponent({ emits: ['copy:nodes'], setup(_, { expose }) { diff --git a/packages/testing/janitor/src/core/test-scoped-runner.test.ts b/packages/testing/janitor/src/core/test-scoped-runner.test.ts index a7845ea08eb..bcca1a31e4d 100644 --- a/packages/testing/janitor/src/core/test-scoped-runner.test.ts +++ b/packages/testing/janitor/src/core/test-scoped-runner.test.ts @@ -1,7 +1,7 @@ import { isAbsolute } from 'node:path'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; -import { buildRunnerArgs } from './test-scoped-runner.js'; +import { buildRunnerArgs, resolveExitCode } from './test-scoped-runner.js'; const rootDir = '/repo/root'; @@ -38,3 +38,26 @@ describe('buildRunnerArgs', () => { ); }); }); + +describe('resolveExitCode', () => { + it('passes a normal exit status through unchanged', () => { + const error = vi.spyOn(console, 'error').mockImplementation(() => {}); + expect(resolveExitCode({ status: 0, signal: null })).toBe(0); + expect(resolveExitCode({ status: 1, signal: null })).toBe(1); + expect(error).not.toHaveBeenCalled(); + }); + + it('reports the spawn error when vitest does not start', () => { + const error = vi.spyOn(console, 'error').mockImplementation(() => {}); + const enoent = new Error('spawnSync vitest ENOENT'); + expect(resolveExitCode({ status: null, signal: null, error: enoent })).toBe(1); + expect(error).toHaveBeenCalledWith(expect.stringContaining('ENOENT')); + expect(error).not.toHaveBeenCalledWith(expect.stringContaining('signal')); + }); + + it('names the signal and fails when vitest exits without a status', () => { + const error = vi.spyOn(console, 'error').mockImplementation(() => {}); + expect(resolveExitCode({ status: null, signal: 'SIGKILL' })).toBe(1); + expect(error).toHaveBeenCalledWith(expect.stringContaining('SIGKILL')); + }); +}); diff --git a/packages/testing/janitor/src/core/test-scoped-runner.ts b/packages/testing/janitor/src/core/test-scoped-runner.ts index d4fc8993b90..170647820f5 100644 --- a/packages/testing/janitor/src/core/test-scoped-runner.ts +++ b/packages/testing/janitor/src/core/test-scoped-runner.ts @@ -58,5 +58,25 @@ export function runTestScoped(options: TestScopedOptions): number { // Pass cwd explicitly so an override via --package-dir is honoured // (otherwise spawnSync inherits the caller's cwd and vitest would // resolve config + tests from the wrong project). - return spawnSync('vitest', args, { stdio: 'inherit', cwd: options.packageDir }).status ?? 1; + const result = spawnSync('vitest', args, { stdio: 'inherit', cwd: options.packageDir }); + return resolveExitCode(result); +} + +// A signal-killed vitest has no status and prints no summary, so name the signal. +// A spawn failure has no status either; with inherited stdio, only `error` reports it. +export function resolveExitCode(result: { + status: number | null; + signal: NodeJS.Signals | null; + error?: Error; +}): number { + if (result.status !== null) return result.status; + if (result.error) { + console.error(`[janitor:test-scoped] vitest failed to start: ${result.error.message}`); + return 1; + } + console.error( + `[janitor:test-scoped] vitest exited without a status (signal: ${result.signal ?? 'unknown'}). ` + + 'The process was killed before it could report results; check the runner for memory pressure.', + ); + return 1; }