findElectron() probed exactly one path, and got three things wrong at once for anyone not on a hoisted POSIX install: * It looked only under the REPO ROOT. This is an npm workspaces repo and npm hoists a dependency only when nothing conflicts, so `electron` installing into apps/desktop/node_modules is an ordinary outcome, not a broken tree. * It joined a bare `electron`. On Windows the dist file is `electron.exe`, so the probe could never match there. * Its PATH fallback spawned `which`, which is not a command on Windows, so the fallback failed for a reason unrelated to whether electron is on PATH. The three combine into a misleading error: the suite refuses to start with 'Run "npm install" from the repo root' on a tree that has electron installed. Reproduced on Windows 11 against this repo, where apps/desktop/node_modules/electron/dist/electron.exe exists and the old body throws that message; the reporter on #88036 hit the same thing on Linux and had to hand-symlink the package before the suite would run. Resolution now asks the installed `electron` package for its own path first (its main export IS the absolute executable, resolved from path.txt and honouring ELECTRON_OVERRIDE_DIST_PATH), then falls back to explicit dist probes for each root, then to PATH with the platform's lookup command. The error message lists what was searched. The rules live in e2e/electron-binary.ts so they can be unit-tested without importing the Playwright runner, with the platform passed in rather than read from process.platform: reading it would leave every Windows rule untested on the Linux CI runner. Wiring: the vitest `electron` project picks up e2e/**/*.unit.test.ts and Playwright ignores the same pattern, so helper unit tests run in exactly one runner and the specs are untouched. Verified: 5 unit tests pass; mutation-checked one rule at a time (hardcoding the binary name fails 2, reversing the probe order fails 1, hardcoding `which` fails 1). tsc -p . and tsc -p tsconfig.e2e.json clean. This is the environment blocker called out in #88036, not its rendering bug, so it is deliberately a subset. Refs #88036
55 lines
2.2 KiB
TypeScript
55 lines
2.2 KiB
TypeScript
import * as path from 'node:path'
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import { electronBinaryName, electronDistCandidates, pathLookupCommand } from './electron-binary'
|
|
|
|
// Platform is a parameter everywhere below rather than read from
|
|
// process.platform, so the Windows rules are pinned on the Linux CI runner too.
|
|
// Reading the real platform would leave every Windows-only rule untested.
|
|
|
|
describe('electronBinaryName', () => {
|
|
it('asks for electron.exe on Windows', () => {
|
|
expect(electronBinaryName('win32')).toBe('electron.exe')
|
|
})
|
|
|
|
it('asks for a bare electron everywhere else', () => {
|
|
expect(electronBinaryName('linux')).toBe('electron')
|
|
expect(electronBinaryName('darwin')).toBe('electron')
|
|
})
|
|
})
|
|
|
|
describe('electronDistCandidates', () => {
|
|
const desktop = path.join('repo', 'apps', 'desktop')
|
|
const repo = 'repo'
|
|
|
|
it('probes the workspace-local install before the hoisted one', () => {
|
|
// npm only hoists `electron` to the repo root when nothing conflicts, so
|
|
// apps/desktop/node_modules is an ordinary outcome of `npm install`, not a
|
|
// broken tree. Probing only the repo root is what makes the suite refuse to
|
|
// start with "run npm install" on a tree that has electron installed.
|
|
expect(electronDistCandidates([desktop, repo], 'linux')).toEqual([
|
|
path.join(desktop, 'node_modules', 'electron', 'dist', 'electron'),
|
|
path.join(repo, 'node_modules', 'electron', 'dist', 'electron'),
|
|
])
|
|
})
|
|
|
|
it('carries the platform binary name into every candidate', () => {
|
|
// A bare `electron` file never exists in a Windows dist, so a probe built
|
|
// from a hardcoded name cannot match there no matter which root it walks.
|
|
for (const candidate of electronDistCandidates([desktop, repo], 'win32')) {
|
|
expect(path.basename(candidate)).toBe('electron.exe')
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('pathLookupCommand', () => {
|
|
it('uses where on Windows and which elsewhere', () => {
|
|
// `which` is not a command on Windows; spawning it unconditionally made the
|
|
// PATH fallback fail for a reason unrelated to whether electron is on PATH.
|
|
expect(pathLookupCommand('win32')).toBe('where')
|
|
expect(pathLookupCommand('linux')).toBe('which')
|
|
expect(pathLookupCommand('darwin')).toBe('which')
|
|
})
|
|
})
|