diff --git a/packages/data-context/src/actions/MigrationActions.ts b/packages/data-context/src/actions/MigrationActions.ts index d0d094b310af..a363e363d0ff 100644 --- a/packages/data-context/src/actions/MigrationActions.ts +++ b/packages/data-context/src/actions/MigrationActions.ts @@ -34,11 +34,11 @@ import { } from '../sources/migration' import { makeCoreData } from '../data' import { LegacyPluginsIpc } from '../data/LegacyPluginsIpc' -import { hasTypeScriptInstalled } from '../util' +import { hasTypeScriptInstalled, toPosix } from '../util' const debug = debugLib('cypress:data-context:MigrationActions') -const tsNode = require.resolve('@packages/server/lib/plugins/child/register_ts_node') +const tsNode = toPosix(require.resolve('@packages/server/lib/plugins/child/register_ts_node')) export function getConfigWithDefaults (legacyConfig: any) { const newConfig = _.cloneDeep(legacyConfig) @@ -103,7 +103,7 @@ export async function processConfigViaLegacyPlugins (projectRoot: string, legacy // this matches the 9.x behavior, which is what we want for // processing legacy pluginsFile (we never supported `"type": "module") in 9.x. if (hasTypeScriptInstalled(projectRoot)) { - const tsNodeLoader = `--require ${tsNode}` + const tsNodeLoader = `--require "${tsNode}"` if (!childOptions.env) { childOptions.env = {} diff --git a/packages/data-context/src/data/ProjectConfigIpc.ts b/packages/data-context/src/data/ProjectConfigIpc.ts index 15023dac9547..a2125ae9844f 100644 --- a/packages/data-context/src/data/ProjectConfigIpc.ts +++ b/packages/data-context/src/data/ProjectConfigIpc.ts @@ -7,7 +7,7 @@ import fs from 'fs-extra' import path from 'path' import inspector from 'inspector' import debugLib from 'debug' -import { autoBindDebug, hasTypeScriptInstalled } from '../util' +import { autoBindDebug, hasTypeScriptInstalled, toPosix } from '../util' import _ from 'lodash' import { pathToFileURL } from 'url' @@ -17,7 +17,7 @@ const debug = debugLib(`cypress:lifecycle:ProjectConfigIpc`) const CHILD_PROCESS_FILE_PATH = require.resolve('@packages/server/lib/plugins/child/require_async_child') const tsNodeEsm = pathToFileURL(require.resolve('ts-node/esm/transpile-only')).href -const tsNode = require.resolve('@packages/server/lib/plugins/child/register_ts_node') +const tsNode = toPosix(require.resolve('@packages/server/lib/plugins/child/register_ts_node')) export type IpcHandler = (ipc: ProjectConfigIpc) => void @@ -128,6 +128,7 @@ export class ProjectConfigIpc extends EventEmitter { let resolved = false this._childProcess.on('error', (err) => { + debug('unhandled error in child process %s', err) this.handleChildProcessError(err, this, resolved, reject) reject(err) }) @@ -139,6 +140,7 @@ export class ProjectConfigIpc extends EventEmitter { * but it's not. */ this.on('childProcess:unhandledError', (err) => { + debug('unhandled error in child process %s', err) this.handleChildProcessError(err, this, resolved, reject) reject(err) }) @@ -150,6 +152,7 @@ export class ProjectConfigIpc extends EventEmitter { }) this.once('loadConfig:error', (err) => { + debug('error loading config %s', err) this.killChildProcess() reject(err) }) @@ -289,7 +292,7 @@ export class ProjectConfigIpc extends EventEmitter { // We do NOT use the `--loader` flag because we have some additional // custom logic for ts-node when used with CommonJS that needs to be evaluated // so we need to load and evaluate the hook first using the `--require` module API. - const tsNodeLoader = `--require ${tsNode}` + const tsNodeLoader = `--require "${tsNode}"` if (childOptions.env.NODE_OPTIONS) { childOptions.env.NODE_OPTIONS += ` ${tsNodeLoader}` @@ -302,9 +305,7 @@ export class ProjectConfigIpc extends EventEmitter { // TODO: Consider using userland `esbuild` with Node's --loader API to handle ESM. } - const proc = fork(CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions) - - return proc + return fork(CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions) } private handleChildProcessError (err: any, ipc: ProjectConfigIpc, resolved: boolean, reject: (reason?: any) => void) { diff --git a/packages/launchpad/cypress/e2e/migration.cy.ts b/packages/launchpad/cypress/e2e/migration.cy.ts index 56d7c6a47e8f..300390f796ce 100644 --- a/packages/launchpad/cypress/e2e/migration.cy.ts +++ b/packages/launchpad/cypress/e2e/migration.cy.ts @@ -1546,8 +1546,8 @@ describe('Migration', { viewportWidth: 1200, retries: { openMode: 0, runMode: 2 }) describe('Migrate custom config files', () => { - it('completes journey for migration-custom-config-file-root-level', () => { - startMigrationFor('migration-custom-config-file-root-level', ['--config-file', 'customConfig.json']) + it('completes journey for migration-custom-config-file-root-level spaces', () => { + startMigrationFor('migration-custom-config-file-root-level spaces', ['--config-file', 'customConfig.json']) // defaults, rename all the things // can rename integration->e2e diff --git a/packages/launchpad/cypress/e2e/open-mode.cy.ts b/packages/launchpad/cypress/e2e/open-mode.cy.ts index 29f78ab15e55..565ba42cbc53 100644 --- a/packages/launchpad/cypress/e2e/open-mode.cy.ts +++ b/packages/launchpad/cypress/e2e/open-mode.cy.ts @@ -242,4 +242,11 @@ describe('Launchpad: Open Mode', () => { cy.get('body').should('not.contain.text', 'Your project does not contain a default supportFile.') cy.get('h1').should('contain', 'Choose a Browser') }) + + it('opens project with spaces in path', () => { + cy.scaffoldProject('simple with spaces') + cy.openProject('simple with spaces', ['--e2e']) + cy.visitLaunchpad() + cy.get('h1').should('contain', 'Choose a Browser') + }) }) diff --git a/scripts/run-webpack.js b/scripts/run-webpack.js index 150aca60edd7..1d179c4525e8 100644 --- a/scripts/run-webpack.js +++ b/scripts/run-webpack.js @@ -20,4 +20,13 @@ if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && s NODE_OPTIONS = `${NODE_OPTIONS} --openssl-legacy-provider` } -cp.execSync(`node ${webpackCli} ${process.argv.slice(2).join(' ')}`, { stdio: 'inherit', env: { ...process.env, NODE_OPTIONS } }) +function buildCommand () { + const file = process.argv.slice(2).join(' ') ?? '' + let program = `node "${webpackCli}"` + + return file ? `${program } "${file}"` : program +} + +const program = buildCommand() + +cp.execSync(program, { stdio: 'inherit', env: { ...process.env, NODE_OPTIONS } }) diff --git a/system-tests/projects/migration-custom-config-file-root-level/README.md b/system-tests/projects/migration-custom-config-file-root-level spaces/README.md similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/README.md rename to system-tests/projects/migration-custom-config-file-root-level spaces/README.md diff --git a/system-tests/projects/migration-custom-config-file-root-level/customConfig.json b/system-tests/projects/migration-custom-config-file-root-level spaces/customConfig.json similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/customConfig.json rename to system-tests/projects/migration-custom-config-file-root-level spaces/customConfig.json diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/integration/foo.spec.js b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/integration/foo.spec.js similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/cypress/integration/foo.spec.js rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/integration/foo.spec.js diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/plugins/index.js b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/plugins/index.js similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/cypress/plugins/index.js rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/plugins/index.js diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/support/index.ts b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/support/index.ts similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/cypress/support/index.ts rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/support/index.ts diff --git a/system-tests/projects/migration-custom-config-file-root-level/expected-cypress.config.js b/system-tests/projects/migration-custom-config-file-root-level spaces/expected-cypress.config.js similarity index 100% rename from system-tests/projects/migration-custom-config-file-root-level/expected-cypress.config.js rename to system-tests/projects/migration-custom-config-file-root-level spaces/expected-cypress.config.js diff --git a/system-tests/projects/simple with spaces/cypress.config.js b/system-tests/projects/simple with spaces/cypress.config.js new file mode 100644 index 000000000000..93b46ace1929 --- /dev/null +++ b/system-tests/projects/simple with spaces/cypress.config.js @@ -0,0 +1,8 @@ +module.exports = { + e2e: { + supportFile: false, + setupNodeEvents (on, config) { + // implement node event listeners here + }, + }, +} diff --git a/system-tests/projects/simple with spaces/package.json b/system-tests/projects/simple with spaces/package.json new file mode 100644 index 000000000000..8a5a20589141 --- /dev/null +++ b/system-tests/projects/simple with spaces/package.json @@ -0,0 +1,3 @@ +{ + "projectFixtureDirectory": "simple_passing" +} \ No newline at end of file