diff --git a/src/lib/exec.ts b/src/lib/exec.ts index 34a6ceff..f0926108 100644 --- a/src/lib/exec.ts +++ b/src/lib/exec.ts @@ -1,4 +1,5 @@ import { type SpawnOptions, type SpawnOptionsWithoutStdio, spawn } from 'node:child_process'; +import { isAbsolute } from 'node:path'; import { run } from './outputs.js'; @@ -11,8 +12,10 @@ const windowsOptions: SpawnOptions = { * Run child process and returns stdout and stderr to user stout */ const spawnPromised = async (cmd: string, args: string[], opts: SpawnOptionsWithoutStdio) => { + const escapedCommand = isAbsolute(cmd) && process.platform === 'win32' ? `"${cmd}"` : cmd; + // NOTE: Pipes stderr, stdout to main process - const childProcess = spawn(cmd, args, { + const childProcess = spawn(escapedCommand, args, { ...opts, stdio: process.env.APIFY_NO_LOGS_IN_TESTS ? 'ignore' : 'inherit', ...(process.platform === 'win32' ? windowsOptions : {}), diff --git a/test/commands/windows/create.test.ts b/test/commands/windows/create.test.ts new file mode 100644 index 00000000..39d15c19 --- /dev/null +++ b/test/commands/windows/create.test.ts @@ -0,0 +1,31 @@ +import { existsSync } from 'node:fs'; + +import { useTempPath } from '../../__setup__/hooks/useTempPath.js'; + +const actName = 'create-my-spaced-actor'; +const { beforeAllCalls, afterAllCalls, joinPath } = useTempPath('spaced actor', { + create: true, + remove: true, + cwd: true, + cwdParent: false, +}); + +const { CreateCommand } = await import('../../../src/commands/create.js'); + +describe.runIf(process.env.FORCE_WINDOWS_TESTS || process.platform === 'win32')('apify create on windows', () => { + beforeEach(async () => { + await beforeAllCalls(); + }); + + afterEach(async () => { + await afterAllCalls(); + }); + + it('works for creating an actor when the folder path contains spaces', async () => { + const ACT_TEMPLATE = 'python-playwright'; + await CreateCommand.run([actName, '--template', ACT_TEMPLATE], import.meta.url); + + // check files structure + expect(existsSync(joinPath(actName))).toBeTruthy(); + }); +});